Startpunkten

This commit is contained in:
2026-03-05 13:39:39 +01:00
commit c4d164d8c3
20 changed files with 3598 additions and 0 deletions

76
AVL_tree/header.hpp Normal file
View File

@@ -0,0 +1,76 @@
//##################################################################
// PROGRAMMERINGSUPPGIFT 2
// DATASTRUKTURER OCH ALGORITMER
// AVL TRÄD
//==================================================================
// HEADER.HPP
// Filen innehåller definition som används i programmet
// Christian Ohlsson
// Karlstad 980927
//==================================================================
#ifndef _header_
#define _header_
#include <iostream.h>
#include <fstream.h>
#include <iomanip.h>
#include <stdlib.h>
#include <string.h>
//#include <conio.h>
#include <ctype.h>
const int FALSE = 0; //boolsk variabel
const int TRUE = !FALSE; //boolsk variabel
const int BUFFERSIZE = 100; //för säker inmatning
const int FILENAMESIZE = 8; //för MS-DOS 6.0
const int NAMESIZE = 20; //antal tecken som kan matas in som namn
const int NUMBERSIZE = 20; //antal tecken som kan matas in som nummer
const int ENTER = 13; //ASCII kod för enter
const int BACKSPACE = 8; //ASCII kod för backspace
//typedef int bool; //definierar boolsk variabel
typedef char nameType[NAMESIZE]; //sätter nametypen till char
typedef char numberType[NUMBERSIZE]; //sätter numberTypen till char
struct treeNode; //förvarnar datorn om en struct
typedef treeNode* ptrType; //ger en pekartype till en struct
struct treeNode{ //en nod i trädet
nameType name;
numberType number;
ptrType left;
ptrType right;
int height;
treeNode(nameType oneName,numberType number,
ptrType left, ptrType right,
int height);
};
class treeClass
{
public:
treeClass();
~treeClass(){};
ptrType node;
ptrType seek(ptrType node, nameType value);
bool isEmpty();
void destroyTree(ptrType &node);
void setHeight(ptrType &node);
void rotation(ptrType &node);
void inOrder(ptrType treeNode);
void del(ptrType &node, nameType oneName);
void insert(ptrType &node,nameType oneName,numberType number, int height);
void save(ptrType node, fstream &fil);
private:
int balance(ptrType &node);
int maxHeight(ptrType &node);
int size;
void singleLeft(ptrType &node);
void singleRight(ptrType &node);
void doubleRL(ptrType &node);
void doubleLR(ptrType &node);
void delLeft(ptrType &node, nameType oneName, numberType oneNumber);
void delRoot(ptrType &node);
};
#endif

273
AVL_tree/huvud.cpp Normal file
View File

@@ -0,0 +1,273 @@
//##################################################################
// PROGRAMMERINGSUPPGIFT 2
// DATASTRUKTURER OCH ALGORITMER
// AVL TRÄD
//==================================================================
// HUVUD.CPP
// Filen innehåller huvudprogrammet
// Christian Ohlsson
// Karlstad 980927
//==================================================================
#include "header.hpp"
//###############################################################
// SÄKER INMATNING AV MENYVAL
// ser till att bara en character matas in
// som menyval som dessutom måste vara en siffra
//===============================================================
/*
char mataInChar()
{
bool test = FALSE;
char temp, svar;
do {
temp = getch();
if(isalnum(temp) && test == FALSE) {
cout << temp;
svar = temp;
test = TRUE;
}
else if(temp == BACKSPACE && test == TRUE) {
gotoxy(wherex()-1, wherey());
cout << " ";
gotoxy(wherex()-1, wherey());
test = FALSE;
}
}while(temp != ENTER || test == FALSE);
return svar;
}
*/
//##################################################################
// SÄTTER IN EN NOD I TRÄD
// calls: treeClass::insert, treeclass::seek, treeClass::setHeight
// treeClass::rotation
//==================================================================
void _insert(treeClass &myTree)
{
nameType oneName;
numberType number;
int height=0;
cout <<"\n Ange namn: ";
cin >> oneName;
if(strlen(oneName) > NAMESIZE)
cout << "\n Man kan högst ange namnet med " << NAMESIZE << " tecken";
else {
if(myTree.seek(myTree.node, oneName) != NULL)
cout << "\n Du har redan satt in "
<< oneName << " i katalogen";
else {
cout <<"\n Ange telefonnummer: ";
cin >> number;
if (strlen(number) > NUMBERSIZE)
cout << "\n Man kan högst ange nummret med " << NUMBERSIZE << " tecken";
else {
myTree.insert(myTree.node,oneName,number,height);
myTree.setHeight(myTree.node);
myTree.rotation(myTree.node);
myTree.setHeight(myTree.node);
return;
}
}
}
// getch();
}
//##################################################################
// TAR BORT EN NOD UR TRÄD
// calls: treeClass::del, treeClass::isEmpty, treeclass::seek
// treeClass::setHeight, treeClass::rotation
//==================================================================
void _del(treeClass &myTree)
{
if(!myTree.isEmpty()) {
nameType oneName;
cout << "\n Vem vill du ta bort: ";
cin >> oneName;
if(strlen(oneName) > NAMESIZE)
cout << "\n Man kan högst ange namnet med " << NAMESIZE << " tecken";
else {
if(myTree.seek(myTree.node, oneName) == NULL)
cerr << "\n " << oneName << " finns inte i katalogen. ";
else {
myTree.del(myTree.node, oneName);
myTree.setHeight(myTree.node);
myTree.rotation(myTree.node);
myTree.setHeight(myTree.node);
return;
}
}
}
else
cerr << "\n Telefonkatalogen är tom... ";
// getch();
}
//##################################################################
// SKRIVER UT I INORDER
// calls: treeClass::inOrder, treeClass::isEmpty
//==================================================================
void _inOrder(treeClass myTree)
{
if(!myTree.isEmpty()) {
// clrscr();
cout << setw(NAMESIZE)
<< "Namn"
<< setw(NAMESIZE)
<< "Telefon"
<< setw(NAMESIZE)
<< "Höjd \n"
<< setw(NAMESIZE)
<< " ------------------------------------------------------------------ \n";
myTree.inOrder(myTree.node);
}
else
cerr << "\n Telefonkatalogen är tom... ";
// getch();
}
//##################################################################
// SÖKER I TRÄDET
// calls: treeClass::seek, treeClass::isEmpty
//==================================================================
void _seek(treeClass myTree)
{
if(!myTree.isEmpty()) {
nameType oneName;
cout << "\n Mata in namn: ";
cin >> oneName;
ptrType tempNode = myTree.seek(myTree.node, oneName);
if(tempNode != NULL)
cout << "\n " << tempNode->name
<< " har telefonnummer: "
<< tempNode->number;
else
cout << "\n " << oneName << " fanns inte med i katalogen...";
}
else
cerr << "\n Telefonkatalogen är tom... ";
// getch();
}
//##################################################################
// SPARAR TRÄDET PÅ FIL
// calls: treeClass::save, treeClass::isEmpty
//==================================================================
void _save(treeClass myTree)
{
if(!myTree.isEmpty()) {
fstream fil;
char filnamn[FILENAMESIZE];
cout << "\n Ange filnamn att spara: ";
cin >> filnamn;
fil.open(filnamn,ios::out|ios::binary);
myTree.save(myTree.node, fil);
fil.close();
}
else {
cerr << "\n Telefonkatalogen är tom...";
// getch();
}
}
//##################################################################
// HÄMTAR ETT TRÄD FRÅN EN FIL
// läser in värdet i varje nod i preorder
// och sätter in det i trädet i preoder
// calls treeClass::insert, treeClass::isEmpty, treeClass::setHeight
// treeClass::rotation
//==================================================================
void _load(treeClass &myTree)
{
if(myTree.isEmpty()) {
fstream fil;
numberType number;
nameType oneName;
char filnamn[FILENAMESIZE];
cout << "\n Ange filnamn att hämta: ";
cin >> filnamn;
fil.open(filnamn,ios::in|ios::binary);
if(fil)
while(fil.peek() != EOF) {
fil.read((char*)&oneName,sizeof(oneName));
fil.read((char*)&number,sizeof(number));
myTree.insert(myTree.node, oneName,number,0);
myTree.setHeight(myTree.node);
myTree.rotation(myTree.node);
myTree.setHeight(myTree.node);
}
else {
cerr << "\n Filen finns inte...";
// getch();
}
fil.close();
}
else {
cerr << "\n Det finns redan personer i katalogen. \n"
<< " Du måste ta bort samtliga personer \n"
<< " genom att välja detta i menyn. \n";
// getch();
}
}
//##################################################################
// DESTROYTREE
// tar bort hela trädet
// calls: treeClass::isEmpty, treeClass::destroyTree
//==================================================================
void _destroyTree(treeClass &myTree)
{
if(!myTree.isEmpty())
myTree.destroyTree(myTree.node);
else {
cerr << "\n Telefonkatalogen är tom...";
// getch();
}
}
//##################################################################
// MENY ITEMS
// skriver ut menyn på skärmen
//==================================================================
void meny()
{
// clrscr();
cout << " \n TELEFON KATALOGEN "
<< " \n ----------------- "
<< " \n 1. Lägg till person "
<< " \n 2. Ta bort person "
<< " \n 3. Sök efter person "
<< " \n 4. Skriv ut i bokstavsordning "
<< " \n 5. Spara på fil "
<< " \n 6. Hämta från fil "
<< " \n 7. Radera hela trädet "
<< " \n 0. Avsluta "
<< " \n ";
// gotoxy(2,12); //ställer markören under menyn
}
//##################################################################
// MAIN FUNCTION
// skapar trädet myTree av typen treeClass
// calls: alla drivrutiner
//==================================================================
void main()
{
treeClass myTree;
char val;
do {
meny();
cin >> val;
// val = mataInChar();;
switch (val)
{
case '1' : _insert(myTree);break;
case '2' : _del(myTree);break;
case '3' : _seek(myTree);break;
case '4' : _inOrder(myTree);break;
case '5' : _save(myTree);break;
case '6' : _load(myTree);break;
case '7' : _destroyTree(myTree);break;
case '0' : cout << "\n Programmet avslutat";break;
default : cerr << "\n Felaktigt val";
// getch();
}
}while(val != '0');
}

BIN
AVL_tree/run_me Normal file

Binary file not shown.

344
AVL_tree/tree.cpp Normal file
View File

@@ -0,0 +1,344 @@
//##################################################################
// PROGRAMMERINGSUPPGIFT 2
// DATASTRUKTURER OCH ALGORITMER
// AVL TRÄD
//==================================================================
// TREE.CPP
// Filen innehåller funktioner för trädet
// Christian Ohlsson
// Karlstad 980927
//==================================================================
#include "header.hpp"
//##################################################################
// SKAPAR ETT TRÄD & SÄTTER NODE TILL NULL
//==================================================================
treeClass::treeClass():node(NULL)
{
}
//##################################################################
// DESTROYTREE
// traverserar genom trädet rekursivt
// och raderar hela trädet
// pre: att det finns ett träd
// post: samtliga noder i trädet är borttagna
// calls: destroyTree (rekursivt)
//==================================================================
void treeClass::destroyTree(ptrType &node)
{
if(node->left != NULL)
destroyTree(node->left);
if(node->right != NULL)
destroyTree(node->right);
delete node;
node = NULL;
}
//##################################################################
// SKAPAR EN NOD
// pre: TRUE
// post: en ny nod har skapats
//==================================================================
treeNode::treeNode(nameType oneName,numberType oneNumber,
ptrType L, ptrType R, int H) : left(L),right(R),height(H)
{
strcpy(name, oneName);
strcpy(number,oneNumber);
}
//##################################################################
// SÖKER EFTER ETT ELEMENT I TRÄDET
// pre: att trädet inte är tomt
// post: NULL om noden inte fanns
// post: sökta noden om den fanns med
// calls: seek (rekursivt)
//==================================================================
ptrType treeClass::seek(ptrType node, nameType oneName)
{
ptrType treeNodeFound;
if(node == NULL)
treeNodeFound = NULL;
else if (strcmp(node->name, oneName) == 0)
treeNodeFound = node;
else if (strcmp(node->name, oneName) > 0)
treeNodeFound = seek(node->left, oneName);
else
treeNodeFound = seek(node->right, oneName);
return treeNodeFound;
}
//##################################################################
// KOLLAR OM DET FINNS NODER I TRÄDET
// pre: TRUE
// post: TRUE om trädet är tomt
// post: FALSE om det finns noder i trädet
//==================================================================
bool treeClass::isEmpty()
{
if (node==NULL)
return TRUE;
return FALSE;
}
//##################################################################
// SKRIVER UT TRÄDET I INORDER
// pre: att trädet inte är tomt
// post: trädet har skrivits ut i bokstavsordning
// calls: inOrder (rekursivt)
//==================================================================
void treeClass::inOrder(ptrType treeNode)
{
if(treeNode) {
inOrder(treeNode->left);
cout << setw(NAMESIZE)
<< treeNode->name
<< setw(NAMESIZE)
<< treeNode->number
<< setw(NAMESIZE)
<< treeNode->height << endl;
inOrder(treeNode->right);
}
}
//##################################################################
// SÄTTER IN EN NOD I TRÄDET
// pre: att personen inte redan finns
// post: trädet har fått en ny nod insatt
// på rätt plats.
// calls: insert (rekursivt)
//==================================================================
void treeClass::insert(ptrType &node,nameType oneName,numberType number, int height)
{
if(node==NULL)
node=new treeNode(oneName,number,NULL,NULL,height);
else if(strcmp(oneName, node->name) < 0)
insert(node->left,oneName,number,height);
else
insert(node->right,oneName,number,height);
}
//##################################################################
// SÖKER SIG FRAM TILL NODEN SOM SKALL TAS BORT
// pre: att det finns ett träd
// pre: att noden finns
// post: noden har hittats
// calls: delRoot, del (rekursivt)
//==================================================================
void treeClass::del(ptrType &node, nameType oneName)
{
if(strcmp(oneName,node->name) == 0)
delRoot(node);
else if(strcmp(oneName,node->name) < 0)
del(node->left, oneName);
else
del(node->right,oneName);
}
//##################################################################
// TAR BORT EN NODEN OM DEN INT HAR TVÅ BARN
// pre: att det finns ett träd
// pre: att noden finns
// post: noden har tagits ur trädet och
// de andra noderna sitter nu rätt placerade
// calls: delLeft
//==================================================================
void treeClass::delRoot(ptrType &node)
{
ptrType delPtr;
nameType nyItem;
numberType nyNumber;
if(node != NULL) {
if((node->left == NULL) && (node->right == NULL)) {
delete node;
node = NULL;
}
else if(node->left == NULL) {
delPtr = node;
node = node->right;
delPtr->right = NULL;
delete delPtr;
}
else if(node->right == NULL) {
delPtr = node;
node = node->left;
delPtr->left = NULL;
delete delPtr;
}
else {
delLeft(node->right, nyItem, nyNumber);
strcpy(node->name, nyItem);
strcpy(node->number, nyNumber);
}
}
}
//##################################################################
// TAR BORT EN NOD TILL VÄNSTER
// pre: att det finns ett träd
// pre: att noden finns
// post: noden har tagits ur trädet och
// de andra noderna sitter nu rätt placerade
// calls: delLeft (rekursivt)
//==================================================================
void treeClass::delLeft(ptrType &node, nameType oneName, numberType oneNumber)
{
if((node != NULL) && (node->left == NULL)) {
strcpy(oneName, node->name);
strcpy(oneNumber, node->number);
ptrType delPtr = node;
node = node->right;
delPtr->right = NULL;
delete delPtr;
}
else
delLeft(node->left, oneName, oneNumber);
}
//##################################################################
// ROTATI0N
// roterar trädet så att det blir ett AVL träd
// pre: att det finns ett träd
// post: trädets alla noder sitter balanserade
// calls: rotation (rekursivt), balance,
// singleLeft, singleRight, doubleRL, doubleLR
//==================================================================
void treeClass::rotation(ptrType &node)
{
if(node) {
rotation(node->left);
rotation(node->right);
if(balance(node) == 2) {
if(balance(node->right) >= 1)
singleLeft(node);
else if(balance(node->right) <= -1)
doubleRL(node);
}
else if(balance(node) == -2) {
if(balance(node->left) >= 1)
doubleLR(node);
else if(balance(node->left) <= -1)
singleRight(node);
}
}
}
//##################################################################
// BALANSERAR TRÄDET
// returnerar högerbarnets höjd minus vänsterbarnets
// pre: att trädet inte är tomt
// post: höjddifferansen är returnerad
// calls: none
//==================================================================
int treeClass::balance(ptrType &node) //eg root
{
int leftValue, rightValue;
if(node->left == NULL)
leftValue = -1;
else
leftValue = node->left->height;
if(node->right == NULL)
rightValue = -1;
else
rightValue = node->right->height;
return (rightValue - leftValue);
}
//##################################################################
// SINGLE LEFT ROTATION
// roterar åt vänster
// pre: att det finns ett träd
// post: trädet är vänsterroterat
// calls: none
//==================================================================
void treeClass::singleLeft(ptrType &node)
{
ptrType oldNode = node;
node = node->right;
oldNode->right = node->left;
node->left = oldNode;
}
//##################################################################
// SINGLE RIGHT ROTATION
// roterar åt höger
// pre: att det finns ett träd
// post: trädet är högerroterat
// calls: none
//==================================================================
void treeClass::singleRight(ptrType &node)
{
ptrType oldNode = node;
node = node->left;
oldNode->left = node->right;
node->right = oldNode;
}
//##################################################################
// DOUBLE RIGHT-LEFT ROTATION
// Utför en dubbel höger-vänster rotation
// pre: att det finns ett träd
// post: trädet är höger-vänster roterat
// calls: singleRight, singleLeft
//==================================================================
void treeClass::doubleRL(ptrType &node)
{
singleRight(node->right);
singleLeft(node);
}
//##################################################################
// DOUBLE LEFT-RIGHT ROTATION
// Utför en dubbel vänster-höger rotation
// pre: att det finns ett träd
// post: trädet är vänster-höger roterat
// calls: singleLeft, singleRight
//==================================================================
void treeClass::doubleLR(ptrType &node)
{
singleLeft(node->left);
singleRight(node);
}
//##################################################################
// SÄTTER ALLA HÖJDER I TRÄDET I POSTORDER
// pre: att trädet inte är tomt
// post: noderna i trädet har alla rätt höjd
// calls: setHeight (rekursivt), maxHeight
//==================================================================
void treeClass::setHeight(ptrType &node)
{
if(node) {
setHeight(node->left);
setHeight(node->right);
node->height = maxHeight(node) +1;
}
}
//##################################################################
// FINNER MAXIMAL HÖJD EN NOD BEFINNER SIG PÅ
// pre: att trädet inte är tomt
// post: maxhöjden har returnerats
// calls: inget
//==================================================================
int treeClass::maxHeight(ptrType &node)
{
int max;
if(node->left && node->right) {
max = node->left->height;
if(node->right->height > max)
return (node->right->height);
else
return max;
}
else if(node->left)
return (node->left->height);
else if(node->right)
return (node->right->height);
else
return (-1);
}
//##################################################################
// SPARAR TRÄDET PÅ FIL
// läser av nodens namn och nummer i alla noder i
// preorder och skriver de på filen.
// pre: att det finns ett träd
// post: trädet har sparats på fil
// calls: save (rekursivt)
//==================================================================
void treeClass::save(ptrType node, fstream &fil)
{
if(node) {
fil.write((char*)&node->name,sizeof(node->name));
fil.write((char*)&node->number,sizeof(node->number));
save(node->left,fil);
save(node->right,fil);
}
}

BIN
Dijkstra/NeverNeverLand.doc Normal file

Binary file not shown.

BIN
Dijkstra/dijkstra.exe Normal file

Binary file not shown.

285
Dijkstra/graf.cpp Normal file
View File

@@ -0,0 +1,285 @@
/************************************************
* Laboration 4 i
* Datastrukturer och Algoritmer
* Dijkstras Shortest Path
*************************************************
* Christian Ohlsson
* Karlstads universitet, 1999
*
* graf.cpp
* Innehåller de funktioner programmet
* använder sig av för att beräkna
* den kortaste vägen
*************************************************/
#include "header.h"
/*===============================================
* graphNode
* Construktor.
* Skapar en graphNode
-------------------------------------------------*/
graphNode::graphNode() {
startCity = -1;
endCity = -1;
Start = 0;
End = 0;
}
/*===============================================
* Operator ==
* Operatoröverlagring
-------------------------------------------------*/
int graphNode::operator==(graphNode node) {
if(Start != node.Start || End != node.End ||
startCity != node.startCity || endCity != node.endCity)
return false;
return true;
}
/*===============================================
* Operator =
* Operatoröverlagring
-------------------------------------------------*/
void graphNode::operator=(graphNode node) {
startCity = node.startCity;
endCity = node.endCity;
Start = node.Start;
End = node.End;
}
/*===============================================
* Operator >
* Operatoröverlagring
-------------------------------------------------*/
int graphNode::operator>(graphNode node) {
if(Start <= node.Start)
return false;
return true;
}
/*===============================================
* dijkstraNode
* Construktor.
* Skapar en Dijkstra node
-------------------------------------------------*/
dijkstraNode::dijkstraNode() {
deleted = false;
lastCity = 0;
Totaltime = MAXINT; //Tiden sätts till max
}
/*===============================================
* ~dijkstraNode
* Destruktor.
* Tar bort en nod
-------------------------------------------------*/
dijkstraNode::~dijkstraNode() {}
/*===============================================
* graph
* Construktor
* Skapar en graph
-------------------------------------------------*/
graph::graph() {
visitedCities = 0;
table = NULL;
lastPath = NULL;
prevSize = 0;
lastTime = 0;
}
/*===============================================
* ~graph
* Destruktor
* Anropar deleteGraph
-------------------------------------------------*/
graph::~graph() { deleteGraph(); }
/*===============================================
* deleteGraph
* Tömmer grafen på info
-------------------------------------------------*/
void graph::deleteGraph() {
if(table != NULL)
delete[] table;
if(lastPath != NULL)
delete[] lastPath;
table = NULL;
lastPath = NULL;
visitedCities = 0;
prevSize = 0;
lastTime = 0;
}
/*===============================================
* makeGraph
* Skapar en graf med size stycken städer.
* Tar först bort eventuell gammal graf.
* Returnerar true om allt gick bra
-------------------------------------------------*/
int graph::makeGraph(int size) {
deleteGraph();
table = new list<graphNode>*[size];
if(table == NULL)
return false;
for(int index = 0; index < size; index++)
table[index] = new list<graphNode>[size];
if(table == NULL)
return false;
visitedCities = size;
return true;
}
/*===============================================
* connect
* Skapar förbindelse mellan noderna i grafen
-------------------------------------------------*/
void graph::connect(int startvertex, int endvertex, graphNode node) {
if(startvertex < 0 || startvertex > visitedCities-1 ||
endvertex < 0 || endvertex > visitedCities-1)
return;
node.startCity = startvertex;
node.endCity = endvertex;
table[startvertex][endvertex].insert(node);
}
/*===============================================
* shortestPath
* Letar reda på den kortaste
* vägen mellan två noder
-------------------------------------------------*/
graphNode graph::shortestPath(int startvertex, int endvertex, int time) {
int index, time1, time2;
graphNode node1, node2;
if(startvertex < 0 || startvertex > visitedCities-1 ||
endvertex < 0 || endvertex > visitedCities-1)
return node1;
int connections = table[startvertex][endvertex].listLength();
if(connections == 0) return node1;
node1 = table[startvertex][endvertex].printElement(1);
time1 = getTime(node1, time);
for(index = 2; index <= connections; index++) {
node2 = table[startvertex][endvertex].printElement(index);
time2 = getTime(node2, time);
if(time1 > time2) {
node1 = node2;
time1 = time2;
}
}
return node1;
}
/*===============================================
* getTime
* Returnerar antalet timmar mellan tiden
* time och tiden som finns i noden
-------------------------------------------------*/
int graph::getTime(graphNode node, int time) {
int total;
if(node.Start >= time && node.End > time && node.Start < node.End)
total = node.End - time;
else if(node.Start > node.End)
total = ( (24 - time + node.Start) + (24 - node.Start + node.End) );
else
total = (24 - time + node.End);
return total;
}
/*===============================================
* dijkstra
* Beräknar den kortaste sträckan dvs. tiden
* mellan två städer i NeverNeverLand
-------------------------------------------------*/
void graph::dijkstra(int startvertex, int endvertex, int time) {
delPath();
if(startvertex == endvertex || startvertex < 0 ||
startvertex > visitedCities-1 || endvertex < 0 ||
endvertex > visitedCities-1)
return;
dijkstraNode *temparray = new dijkstraNode[visitedCities];
if(temparray == NULL) return;
int min, index, parent = 0, temptime;
graphNode tempnode;
temparray[startvertex].Totaltime = 0;
temparray[startvertex].deleted = true;
min = startvertex;
while(min != endvertex) {
for(index = 0; index < visitedCities; index++) {
if(!temparray[index].deleted) {
tempnode = shortestPath(min, index, time);
if(tempnode.startCity != -1) {
temptime = getTime(tempnode, time);
if((temptime + temparray[min].Totaltime)
< temparray[index].Totaltime) {
temparray[index].Totaltime =
temptime + temparray[min].Totaltime;
if(parent == 0)
temparray[index].lastCity = 0;
else
temparray[index].lastCity = min;
temparray[index].Node = tempnode;
}
}
}
}
min = getMinTime(temparray);
temparray[min].deleted = true;
time = temparray[min].Node.End;
parent++;
}
calcPath(temparray, min);
}
/*===============================================
* calcPath
* Skapar en array med information
* om den kortaste vägen.
-------------------------------------------------*/
void graph::calcPath(dijkstraNode *array, int start) {
graphNode *path = new graphNode[visitedCities];
if(path == NULL)
return;
int temp = 1, index = start;
while(array[index].lastCity > 0) {
temp++;
index = array[index].lastCity;
}
prevSize = temp;
lastTime = array[start].Totaltime;
for(index = temp-1; index >= 0; index--) {
path[index] = array[start].Node;
start = array[start].lastCity;
}
lastPath = path;
}
/*===============================================
* getMinIndex
* Hittar den minsta noden i en array och
* returnerar dess index i arrayen
-------------------------------------------------*/
int graph::getMinTime(dijkstraNode *temptable) {
int temp = 0, index;
while(temptable[temp].deleted)
temp++;
for(index = temp+1; index < visitedCities; index++) {
if(!temptable[index].deleted) {
if(temptable[temp].Totaltime > temptable[index].Totaltime)
temp = index;
}
}
return temp;
}
/*===============================================
* delPath
* Tar bort det som lastpath pekar på
-------------------------------------------------*/
void graph::delPath() {
if(lastPath != NULL)
delete[] lastPath;
lastPath = NULL;
prevSize = 0;
}

75
Dijkstra/graf.h Normal file
View File

@@ -0,0 +1,75 @@
/************************************************
* Laboration 4 i
* Datastrukturer och Algoritmer
* Dijkstras Shortest Path
*************************************************
* Christian Ohlsson
* Karlstads universitet, 1999
*
* Graph.h
* Innehåller de definitioner och klasser
* som används för att beräkna kortaste
* vägen mellan två städer
*************************************************/
#ifndef _GRAPH_H_
#define _GRAPH_H_
#include "list.h"
/*===============================================
* graphNode
* Nod mellan två städer
-------------------------------------------------*/
class graphNode {
public:
graphNode(); //Construktor
~graphNode() {}; //Destruktor
int startCity; //Stad man åker ifrån
int endCity; //Stad man kommer till
int Start; //Starttid
int End; //Ankomsttid
void operator=(graphNode node); //Operator-överlagring
int operator>(graphNode node); //för noder
int operator==(graphNode node); //...
};
/*===============================================
* dijkstraNode
* Speciell nod för Dijkstra
-------------------------------------------------*/
class dijkstraNode {
public:
int deleted; //Märkning för noden
int lastCity; //Föregående besökt stad
int Totaltime; //TotaL restid
dijkstraNode(); //Construktor
~dijkstraNode(); //Destruktor
graphNode Node; //En nod
};
/*===============================================
* graph
* Skapar en graf och sköter uträkningen
-------------------------------------------------*/
class graph {
private:
int visitedCities; //Antalet traverserade städer
list<graphNode> **table; //Resväg
graphNode shortestPath(int startvertex, int endvertex, int time);
void delPath();
int getTime(graphNode node, int time);
int getMinTime(dijkstraNode *temptable);
void calcPath(dijkstraNode *array, int start);
public:
int lastTime; //Tid som ökas när vi reser
int prevSize; //Antalet städer i arrayen
graphNode *lastPath; //Traverserad väg
graph(); //Construktor
~graph(); //Destruktor
void deleteGraph();
void connect(int startvertex, int endvertex, graphNode node);
int makeGraph(int size);
void dijkstra(int startvertex, int endvertex, int time);
};
#endif

36
Dijkstra/header.h Normal file
View File

@@ -0,0 +1,36 @@
/************************************************
* Laboration 4 i
* Datastrukturer och Algoritmer
* Dijkstras Shortest Path
*************************************************
* Christian Ohlsson
* Karlstads universitet, 1999
*
* Header.h
* Innehåller definitioner och includes
* som används i programmet.
*************************************************/
#ifndef ___HEADER___
#define ___HEADER___
#include <iostream.h>
#include <stdlib.h>
#include <values.h>
#include <fstream.h>
#include <string.h>
#include <conio.h>
#include "graf.h"
#include "list.h"
const int false=0; //boolsk variabel
const int true=!false; //boolsk variabel
const int citySize=25; //Max antal tecken i en stad
const int numOfCities=13; //Antalet städer
const int FORWARD=2; //För inläsning
const int MAXTIME = 6; //Max antal tkn
const int BASE=10; //Talbas
const int BUFFERSIZE=20; //Buffer för säker inmatning
#endif

240
Dijkstra/list.h Normal file
View File

@@ -0,0 +1,240 @@
/************************************************
* Laboration 4 i
* Datastrukturer och Algoritmer
* Dijkstras Shortest Path
*************************************************
* Christian Ohlsson
* Karlstads universitet, 1999
*
* list.h
* Innehåller definitioner och funktioner
* för en templatelista.
*************************************************/
#ifndef _LISTA_H_
#define _LISTA_H_
#include "header.h"
/*===============================================
* list
* Denna klass skapar en templatelista.
* Varje nod innehåller ett godtyckligt data-
* fält och en pekare till nästa nod.
-------------------------------------------------*/
template <class T>
class list {
private:
struct nod { // En template nod
T data;
nod *next;
};
int size; // Storleken på listan.
nod *head; // Pekar på första elementet i listan.
public:
list();
~list();
int listLength(); //Storleken på listan
void insert(T data); //Sätter in en nod
void del(int place); //Tar bort en nod
void sort(void); //Sorterar listan
int seek(T data); //Söker i listan
int isFree(void); //Kollar om det finns element i listan
void delAll(void); //Tar bort allt i listan
int occupiedExist(T data); //Kollar om inmatat värde existerar
int occupied(int place); //Testar om det finns plats
void setNode(nod *dat, T data); //Mata in data i den nya noden
T printElement(int place); //Visar Innehållet på bestämd plats.
T *getPtr(int place); //Returnera platsen på place position
};
/*===============================================
* list
* Construktor, skapar en lista
-------------------------------------------------*/
template <class T>
list<T>::list() {
head = NULL;
size = 0;
}
/*===============================================
* ~list
* Destruktor. Anropar delAll
-------------------------------------------------*/
template <class T>
list<T>::~list() { delAll(); }
/*===============================================
* insert
* Sätter in en ny nod i listan
-------------------------------------------------*/
template <class T>
void list<T>::insert(T data) {
nod *newNode = new nod;
newNode->next = head;
head = newNode;
size++;
newNode->data = data;
}
/*===============================================
* del
* Tar bort ett element på en viss
* position i listan
-------------------------------------------------*/
template <class T>
void list<T>::del(int place) {
int i = 1;
nod *temp1;
temp1 = head;
nod *temp2;
temp2 = head->next;
if(temp2 == NULL || place == 1) { //Bara ett element i listan
head = temp1->next;
delete temp1;
size--;
}
else { //Flera element i listan
temp2 = head;
while(i < place) {
temp1 = temp2;
temp2 = temp1->next;
i++;
}
temp1->next = temp2->next;
delete temp2;
size--;
}
}
/*===============================================
* isFree
* Kollar om listan är tom. Returnerar
* true om listan är tom
-------------------------------------------------*/
template <class T>
int list<T>::isFree() {
if(size == 0) return true;
else return false;
}
/*===============================================
* occupied
* Kollar om plats finns på en angiven
* position.
-------------------------------------------------*/
template <class T>
int list<T>::occupied(int place) {
if( (place < 1) || (place > size) ) return false;
else return true;
}
/*===============================================
* listLength
* Returnerar antalet element i listan
-------------------------------------------------*/
template <class T>
int list<T>::listLength() { return size; }
/*===============================================
* sort
* Sorterar elementen i listan
-------------------------------------------------*/
template <class T>
void list<T>::sort() {
nod *temp;
T sop;
int changed;
do {
changed = 0;
for(temp = head; temp != NULL; temp = temp->next)
if(temp->data > temp->next->data) {
sop = temp->data;
temp->data = temp->next->data;
temp->next->data = sop;
changed = 1;
}
}while(changed);
}
/*===============================================
* delAll
* Tar bort alla element i listan.
* Sätter sedan storleken till 0
-------------------------------------------------*/
template <class T>
void list<T>::delAll() {
nod *temp1 = head;
nod *temp2;
head = NULL;
while(temp1 != NULL) {
temp2 = temp1;
temp1 = temp1->next;
delete temp2;
}
size = 0;
}
/*===============================================
*
*
-------------------------------------------------*/
template <class T>
int list<T>::occupiedExist(T data) { //Kollar om inmatat värde existerar
nod *temp;
for(temp = head; temp != NULL; temp = temp->next)
if(temp->data == data)
return true;
return false;
}
/*===============================================
*
*
-------------------------------------------------*/
template <class T>
int list<T>::seek(T data) { //Söker efter ett element i listan
nod *temp;
int position = 0;
for(temp = head; temp != NULL; temp = temp->next) {
position++;
if(temp->data == data)
return position; //Funnet! Returnera positionen
}
position = 0;
return position; //Inget hittades, returnera 0
}
/*===============================================
* printElement
* Hämtar element på en angiven plats
-------------------------------------------------*/
template <class T>
T list<T>::printElement(int place) {
nod *temp1 = head;
int i = 1;
while(i < place && i < size) {
temp1 = temp1->next;
i++;
}
return temp1->data;
}
/*===============================================
* getPtr
* Returnera adressen till ett element
* på en angiven plats
-------------------------------------------------*/
template <class T>
T *list<T>::getPtr(int place) {
nod *temp1 = head;
int i = 1;
while(i < place && i < size) {
temp1 = temp1->next;
i++;
}
return &(temp1->data);
}
#endif

191
Dijkstra/main.cpp Normal file
View File

@@ -0,0 +1,191 @@
/************************************************
* Laboration 4 i
* Datastrukturer och Algoritmer
* Dijkstras Shortest Path
*************************************************
* Christian Ohlsson
* Karlstads universitet, 1999
*
* main.cpp
* Innehåller drivrutiner för
* Dijkstra labben.
* Skapat med Borland C++ 4.0
* Låt main.cpp och graph.cpp
* finnas i projektet.
* Kompilera för Easywin, Windows 3.x
* 16-bitar, target: Small
* Se till att filen network.txt finns
* i samma katalog som dijkstra.exe
*************************************************/
#include "header.h"
/*===============================================
* cities
* Alla städer i NeverNeverLand
-------------------------------------------------*/
const char cities[numOfCities][citySize] = {
{"Wonderland"},
{"Sanctuary"},
{"Battlefield"},
{"Octopus's Garden"},
{"Paradise City"},
{"Strawberry Fields"},
{"Chaos"},
{"El Dorado"},
{"Kozmic Place"},
{"Oz"},
{"Nowhereland"},
{"Shangrila"},
{"Southbound"}
};
graph myGraph; //Global klass för grafen
/*===============================================
* mataIn
* Ser till att bara tal matas in
-------------------------------------------------*/
int mataIn() {
char buffer[BUFFERSIZE];
int f;
do {
cin >> buffer;
if (strcmp(buffer,"0") == 0) return 0;
else {
f = atoi(buffer);
if (f!=0) return f;
else cout <<"NAN, try again: ";
}
}while (!f);
return 0;
}
/*===============================================
* getName
* Hämtar namn på stad, dvs det nummer staden
* motsvarar
-------------------------------------------------*/
int getName(char *text) {
int i = 0;
while(strcmp(text, cities[i]) !=0 && i < numOfCities)
i++;
if(i >= numOfCities) return -1;
else return i;
}
/*===============================================
* readGraph
* Läser in alla städer och tider från fil.
-------------------------------------------------*/
void readGraph()
{
graphNode node;
ifstream myFile;
char temp[citySize];
if(!myGraph.makeGraph(numOfCities)) { //Skapar en graf
cout<<"Could not make graph";getch();
return;
}
myFile.open("network.txt"); //Öppnar filen
do {
myFile.get(temp, citySize);
node.startCity = getName(temp); //Hämtar startstad
myFile.seekg(FORWARD, ios::cur);
myFile.get(temp, citySize);
node.endCity = getName(temp); //Hämtar slutstad
myFile.seekg(FORWARD, ios::cur);
myFile.get(temp, citySize);
node.Start = atoi(temp); //Hämtar starttid
myFile.seekg(FORWARD, ios::cur);
myFile.get(temp, citySize);
node.End = atoi(temp); //Hämtar sluttid
myFile.seekg(FORWARD, ios::cur);
myGraph.connect(node.startCity, node.endCity, node); //Sätter in noden
} while(myFile.peek() != EOF);
}
/*===============================================
* printPath
* Skriver ut kortaste vägen
-------------------------------------------------*/
void printPath() {
int index;
char text[citySize * 4], time[MAXTIME];
cout << "The shortest path is:"
<< "\n________________________________________________________";
for(index = 0; index < myGraph.prevSize; index++) {
text[0] = 0;
time[0] = 0;
cout << "\nFrom " << cities[myGraph.lastPath[index].startCity];
itoa(myGraph.lastPath[index].Start, time, BASE);
cout << " "<< time << ":00\t";
time[0] = 0;
cout << "to ";
cout << cities[myGraph.lastPath[index].endCity];
itoa(myGraph.lastPath[index].End, time, BASE);
cout << " " << time << ":00\t";
}
text[0] = 0; time[0] = 0;
itoa(myGraph.lastTime, time, BASE);
cout << "\n________________________________________________________";
cout << "\nThe total travelling time is "<<time<<" hours";
}
/*===============================================
* printTowns
* Skriver ut alla städer på skärmen
-------------------------------------------------*/
void printTowns()
{
clrscr();
cout << "\t\t\t\t\t\t\t\t<b-brox>"
<< "\n Welcome to the RailWay Company"
<< "\n in the NeverNeverLand..."
<< "\n ____________________________________________________"
<< "\n | 0. Wonderland 7. El Dorado |"
<< "\n | 1. Sanctuary 8. Kozmic Place |"
<< "\n | 2. Battlefield 9. Oz |"
<< "\n | 3. Octopus's Garden 10. Nowhereland |"
<< "\n | 4. Paradise City 11. Shangrila |"
<< "\n | 5. Strawberry Fields 12. Southbound |"
<< "\n | 6. Chaos |"
<< "\n |__________________________________________________|"
<< "\n";
}
/*===============================================
* main
* Huvudfunktionen för programmet.
* Läser in grafen och ber användaren
* mata in mellan vilka städer han skall resa
-------------------------------------------------*/
void main() {
int start, end, time;
char playAgain;
readGraph(); //Läs in filen
do{
printTowns(); //Skriv ut städerna
do {
cout <<"\nFrom wich town (0-"<<(numOfCities-1)<<"): ";
start=mataIn();
}while(start<0 || start>numOfCities-1);
do {
cout <<"To wich town (0-"<<(numOfCities-1)<<"): ";
end=mataIn();
}while(end<0 || end>numOfCities-1);
do {
cout <<"Time of departure (0-24): ";
time=mataIn();
}while(time<0 || time>24);
myGraph.dijkstra(start, end, time); //Beräkna kortaste väg
if(myGraph.prevSize > 0)
printPath(); //Skriv ut vägen
else
cout <<"\nStarttown and arrivaltown are the same! Are you stupid?";
cout <<"\n\nPlay Again (Y/N)? ";
cin >> playAgain;
}while(playAgain == 'y' || playAgain == 'Y');
}

BIN
Dijkstra/map.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

1068
Dijkstra/network.txt Normal file

File diff suppressed because it is too large Load Diff

17
Dijkstra/read_me Normal file
View File

@@ -0,0 +1,17 @@
Laboration 4 i
Datastrukturer och Algoritmer
Dijkstra's shortest path
------------------------------------------------
Stort OBS!
Denna lab är utvecklad under windows
med Borland C++ 5.0
Kompilering under Linux kommer ej
att fungera utan lite trix.
Tex finns inte funktioner som clrscr()
i Linux.
Exe-filen borde gå att köra på en windows-
dator. Se till att network.txt finns i samma
katalog som exe-filen.
Labben är provkörd och klar.
------------------------------------------------
Christian Ohlsson, di7chro@cse.kau.se, 1999

292
Hashing/hash.cpp Normal file
View File

@@ -0,0 +1,292 @@
//##################################################################
// PROGRAMMERINGSUPPGIFT 3
// DATASTRUKTURER OCH ALGORITMER
// HASH TABELL
//==================================================================
// HASH.HPP
// Filen innehåller hashfunktionerna
// Christian Ohlsson
// Ingela Johansson
// Anna-Maria Haglund
// Karlstad 981007
//==================================================================
#include "header.hpp"
//##################################################################
//Function: hashClass()
//Task: constuctorn
//Calls: nothing
//==================================================================
hashClass::hashClass()
{
prime();
PRIMENUMBER=0;
ARRAYSIZE = DEFAULTSIZE;
hashPtr = new hashNode[ARRAYSIZE];
for(int i=0; i<ARRAYSIZE ; i++) {
strcpy(hashPtr[i].name, "");
strcpy(hashPtr[i].number, "");
hashPtr[i].exist = FALSE;
}
}
//##################################################################
//Function: ~hashclass
//Task: destructorn
//Calls: nothing
//==================================================================
hashClass::~hashClass(){ delete hashPtr; }
//##################################################################
//Function: getSize()
//Task: returnerar storleken på hashtabellen
//Calls: nothing
//==================================================================
int hashClass::getSize(){ return ARRAYSIZE; }
//##################################################################
//Function: nextPrime()
//Task: returnerar nästa primtal
//Calls: nothing
//==================================================================
int hashClass::nextPrime()
{
PRIMENUMBER++;
return primeArray[DEFAULTPRIMENUMBER+PRIMENUMBER];
}
//##################################################################
//Function: prime()
//Task: lägger in primtalen i en array
//Calls: isPrime()
//==================================================================
void hashClass::prime()
{
int i = 1, num=FIRSTPRIME;
primeArray[0] = STARTPRIME;
while(i<PRIMEARRAYSIZE) {
if(isPrime(num, i, primeArray)) {
primeArray[i] = num;
i++;
}
num = (num+PRIMESTEP);
}
}
//##################################################################
//Function: isPrime()
//Task: kollar om ett tal är ett primtal
//Calls: nothing
//=================================================================
bool hashClass::isPrime(int nummer, int antal, int primeArray[PRIMEARRAYSIZE])
{
for(int i = 0; i < antal; i++)
if(nummer%primeArray[i] == 0)
return FALSE;
return TRUE;
}
//##################################################################
//Function: search()
//Task: söker efter ett namn i tabellen
//Calls: hash1() och hash2()
//==================================================================
bool hashClass::search(nameType name)
{
int location = hash1(name);
if(strcmp(hashPtr[location].name, name) == 0)
return TRUE;
else
while(hashPtr[location].exist == TRUE) {
location = location + hash2(hash1(name));
if(location > ARRAYSIZE)
location = location - ARRAYSIZE;
if(strcmp(hashPtr[location].name, name) == 0)
return TRUE;
}
return FALSE;
}
//##################################################################
//Function: getNode()
//Task: hämtar en nod ur tabellen, d.v.s. namn telefonnummer och
// "deleted-flaggan"
//Calls: hash1() och hash2()
//==================================================================
hashNode hashClass::getNode(nameType &oneName)
{
int location = hash1(oneName);
if(strcmp(hashPtr[location].name, oneName) == 0)
return (hashPtr[location]);
else
do {
location = location + hash2(hash1(oneName));
if(location>ARRAYSIZE) {
location = (location-ARRAYSIZE);
if(strcmp(hashPtr[location].name, oneName) == 0)
return hashPtr[location];
}
}while(hashPtr[location].exist == FALSE);
}
//##################################################################
//Function: biggerHash()
//Task: kollar om en större tabell behövs (om 80% av positionerna
// är upptagna)
//Calls: checkOccupied()
//==================================================================
bool hashClass::biggerHash()
{
float siz = INSERTFACTOR*getSize();
int occ = checkOccupied();
if(occ>=siz)
return TRUE;
return FALSE;
}
//##################################################################
//Function: newHashArray()
//Task:
//Calls: reHash()
//==================================================================
void hashClass::newHashArray()
{
int oldSize = ARRAYSIZE;
ARRAYSIZE = nextPrime();
reHash(oldSize);
}
//##################################################################
//Function:
//Task:
//Calls:
//==================================================================
bool hashClass::anotherHash()
{
int del=0;
float siz = DELETEFACTOR*getSize();
for(int i=0; i<ARRAYSIZE ; i++)
if(hashPtr[i].exist == TRUE && !hashPtr[i].name[0])
del++;
if(del>=siz)
return TRUE;
return FALSE;
}
//##################################################################
//Function:
//Task:
//Calls:
//==================================================================
void hashClass::reHash(int oldSize)
{
int location;
hashNode *tempPtr = new hashNode[ARRAYSIZE];
for(int j=0; j<oldSize ; j++) {
strcpy(tempPtr[j].name, hashPtr[j].name);
strcpy(tempPtr[j].number, hashPtr[j].number);
tempPtr[j].exist = hashPtr[j].exist;
}
destroyHash(oldSize);
hashPtr = new hashNode[ARRAYSIZE];
for(int k=0; k<ARRAYSIZE ; k++) {
strcpy(hashPtr[k].name, "");
strcpy(hashPtr[k].number, "");
hashPtr[k].exist = FALSE;
}
for(int i=0; i<oldSize ; i++)
if(tempPtr[i].exist == TRUE && tempPtr[i].name[0]) {
location = hash1(tempPtr[i].name);
if(hashPtr[location].exist == FALSE)
insert(location, tempPtr[i]);
else
while(hashPtr[location].exist == TRUE) {
location = location + hash2(hash1(tempPtr[i].name));
if(location > ARRAYSIZE)
location = location - ARRAYSIZE;
if(hashPtr[location].exist == FALSE)
insert(location, tempPtr[i]);
}
}
delete tempPtr;
}
//##################################################################
//Function:
//Task:
//Calls:
//==================================================================
int hashClass::hash1(nameType name)
{
int sum = 0;
for(int i=0 ; i<strlen(name) ; i++)
sum = name[i] + sum;
return (sum % ARRAYSIZE);
}
//##################################################################
//Function:
//Task:
//Calls:
//==================================================================
int hashClass::hash2(int key){ return(STEPSIZE - (key % STEPSIZE)) }
//##################################################################
//Function:
//Task:
//Calls:
//==================================================================
int hashClass::checkOccupied()
{
int occupied = 0;
for(int i=0 ; i<ARRAYSIZE ; i++)
if(hashPtr[i].exist == TRUE)
occupied++;
return occupied;
}
//##################################################################
//Function:
//Task:
//Calls:
//==================================================================
void hashClass::destroyHash(int oldSize)
{
for(int i = 0; i < oldSize; i++)
delHash(i);
}
//##################################################################
//Function:
//Task:
//Calls:
//==================================================================
void hashClass::del(int location)
{
strcpy(hashPtr[location].name, "");
strcpy(hashPtr[location].number, "");
hashPtr[location].exist = TRUE;
}
//##################################################################
//Function:
//Task:
//Calls:
//==================================================================
void hashClass::delHash(int location)
{
strcpy(hashPtr[location].name, "");
strcpy(hashPtr[location].number, "");
hashPtr[location].exist = FALSE;
}
//##################################################################
//Function:
//Task:
//Calls:
//==================================================================
void hashClass::insert(int location, hashNode &newNode)
{
strcpy(hashPtr[location].name, newNode.name);
strcpy(hashPtr[location].number, newNode.number);
hashPtr[location].exist = TRUE;
}
//##################################################################
//Function:
//Task:
//Calls:
//==================================================================
void hashClass::save(fstream &fil)
{
int i = 0;
while(i < ARRAYSIZE) {
if((hashPtr[i].name[0]) && (hashPtr[i].exist == TRUE))
fil.write((char*)& hashPtr[i],sizeof(hashPtr[i]));
i++;
}
}

83
Hashing/header.hpp Normal file
View File

@@ -0,0 +1,83 @@
//##################################################################
// PROGRAMMERINGSUPPGIFT 3
// DATASTRUKTURER OCH ALGORITMER
// HASH TABELL
//==================================================================
// HEADER.HPP
// Filen innehåller definition som används i programmet
// Christian Ohlsson
// Ingela Johansson
// Anna-Maria Haglund
// Karlstad 981007
//==================================================================
#ifndef _header_
#define _header_
#include <iostream.h> //för in och utmatning
#include <fstream.h> //för filhantering
#include <iomanip.h> //för textmanipulation
#include <string.h> //för strängmanipulation
#include <conio.h> //för getch()
#include <ctype.h> //för isalnum
#include <stdlib.h> //för en massa saker
const int FALSE = 0; //boolsk variabel
const int TRUE = !FALSE //boolsk variabel
const int FILENAMESIZE = 8; //för MS-DOS 6.0
const int NAMESIZE = 20; //antal tecken som kan matas in som namn
const int NUMBERSIZE = 20; //antal tecken som kan matas in som nummer
const int ENTER = 13; //ASCII kod för enter
const int BACKSPACE = 8; //ASCII kod för backspace
const int PRIMEARRAYSIZE = 30; //storlek på primtalsarrayen
const int DEFAULTSIZE = 11; //hasharrayens defaultstorlek
const int TABSIZE = 20; //antal steg som motsvarar TAB
const int STEPSIZE = 7; //antal steg hash2 max stegar fram
const int DEFAULTPRIMENUMBER = 4; //minsta primtalet i arrayen
const int FIRSTPRIME = 3; //första talet som man jämför med
const int STARTPRIME = 2; //första primtalet i arrayen
const int PRIMESTEP = 2; //antal steg som man hoppar fram
const float INSERTFACTOR = 0.8; //ger en omhashning när 80% är upptaget
const float DELETEFACTOR = 0.3; //ger en omhashning när 30% är märkta deleted
typedef int bool; //definierar boolesk variabel
typedef char nameType[NAMESIZE]; //sätter nametypen till char
typedef char numberType[NUMBERSIZE]; //sätter numberTypen till char
struct hashNode{ //en nod
nameType name;
numberType number;
bool exist;
};
class hashClass
{
public:
hashClass();
~hashClass();
bool search(nameType name);
hashNode getNode(nameType &oneName);
int hash1(nameType name);
int hash2(int key);
int getSize();
void newHashArray();
void reHash(int oldSize);
void print();
void prime();
int checkOccupied();
void destroyHash(int oldSize);
bool biggerHash();
bool anotherHash();
void del(int location);
void insert(int location, hashNode &newNode);
void save(fstream &fil);
hashNode *hashPtr;
int nextPrime();
private:
void delHash(int location);
bool isPrime(int nummer, int antal, int primeArray[PRIMEARRAYSIZE]);
int ARRAYSIZE;
int primeArray[];
int PRIMENUMBER;
};
#endif

294
Hashing/huvud.cpp Normal file
View File

@@ -0,0 +1,294 @@
//##################################################################
// PROGRAMMERINGSUPPGIFT 3
// DATASTRUKTURER OCH ALGORITMER
// HASH TABELL
//==================================================================
// HUVUD.CPP
// Filen innehåller huvudprogrammet
// Christian Ohlsson
// Ingela Johansson
// Anna-Maria Haglund
// Karlstad 981007
//==================================================================
#include "header.hpp"
//###############################################################
// SÄKER INMATNING AV MENYVAL
// ser till att bara en character matas in
// som menyval som dessutom måste vara en siffra
//===============================================================
char mataInChar()
{
bool test = FALSE;
char temp, svar;
do {
temp = getch();
if(isalnum(temp) && test == FALSE) {
cout << temp;
svar = temp;
test = TRUE;
}
else if(temp == BACKSPACE && test == TRUE) {
gotoxy(wherex()-1, wherey());
cout << " ";
gotoxy(wherex()-1, wherey());
test = FALSE;
}
}while(temp != ENTER || test == FALSE);
return svar;
}
//##################################################################
//Function:
//Task:
//Calls:
//==================================================================
void _insert(hashClass &hashTable)
{
nameType name;
numberType number;
hashNode newNode;
int location;
if(hashTable.biggerHash() == FALSE) {
cout << "\n Skriv in namn: ";
cin >> name;
if(hashTable.search(name) == FALSE) {
cout << "\n Skriv in nummer: ";
cin >> number;
strcpy(newNode.name, name);
strcpy(newNode.number, number);
location = hashTable.hash1(name);
if(hashTable.hashPtr[location].exist == FALSE)
hashTable.insert(location, newNode);
else
while(hashTable.hashPtr[location].exist == TRUE) {
location = location + hashTable.hash2(hashTable.hash1(newNode.name));
if(location > hashTable.getSize())
location = location - hashTable.getSize();
if(hashTable.hashPtr[location].exist == FALSE) {
hashTable.insert(location, newNode);
return;
}
}
}
else {
cout << "\n Du har redan satt in " << name << " i katalogen";
getch();
}
}
else
hashTable.newHashArray();
}
//##################################################################
//Function:
//Task:
//Calls:
// TAR BORT EN NOD UR TRÄD
// calls: hashClass::del, getSize, search, hash1, hash2
//==================================================================
void _del(hashClass &hashTable)
{
nameType name;
int location;
cout << "\n Vem vill du ta bort: ";
cin >> name;
if(hashTable.search(name)) {
if(hashTable.anotherHash() == FALSE) {
location = hashTable.hash1(name);
if(strcmp(hashTable.hashPtr[location].name, name) == 0)
hashTable.del(location);
else {
while(hashTable.hashPtr[location].exist == TRUE) {
location = location + hashTable.hash2(hashTable.hash1(name));
if(location > hashTable.getSize())
location = location - hashTable.getSize();
if(strcmp(hashTable.hashPtr[location].name, name) == 0)
hashTable.del(location);
}
}
}
else
hashTable.reHash(hashTable.getSize());
}
else {
cout << " " << name << " finns inte i telefonkatalogen";
getch();
}
}
//##################################################################
//Function:
//Task:
//Calls:
// SKRIVER UT I INORDER
// calls: hashClass::print
//==================================================================
void _print(hashClass &hashTable)
{
int size = hashTable.getSize();
clrscr();
cout << "Plats"
<< setw(TABSIZE-3)
<< "Namn"
<< setw(TABSIZE)
<< "Nummer"
<< "\n-------------------------------------------";
for(int i=0 ; i < size ; i++)
if(hashTable.hashPtr[i].exist == TRUE && hashTable.hashPtr[i].name[0])
cout << endl
<< i
<< setw(TABSIZE)
<< hashTable.hashPtr[i].name
<< setw(TABSIZE)
<< hashTable.hashPtr[i].number;
cout << "\n\n\n\n Arrayen är nu " << size << " stor"
<< "\n och " << hashTable.checkOccupied() << " platser är upptagna.";
getch();
}
//##################################################################
//Function:
//Task:
//Calls:
// SÖKER I TRÄDET
// calls: hashClass::search
// calls: hashClass::isEmpty
//==================================================================
void _search(hashClass &hashTable)
{
hashNode newNode;
nameType name;
cout << "\n Mata in namn: ";
cin >> name;
if(hashTable.search(name)) {
newNode = hashTable.getNode(name);
cout << "\n "
<< newNode.name
<< " har telefonnummer "
<< newNode.number
<< ".";
}
else
cout << " " << name << " finns inte i telefonkatalogen";
getch();
}
//##################################################################
//Function:
//Task:
//Calls:
// SPARAR TRÄDET PÅ FIL
// calls: hashClass::save
// calls: hashClass::isEmpty
//==================================================================
void _save(hashClass &hashTable)
{
fstream fil;
char filnamn[FILENAMESIZE];
cout << "\n Ange filnamn att spara: ";
cin >> filnamn;
fil.open(filnamn,ios::out|ios::binary);
hashTable.save(fil);
fil.close();
}
//##################################################################
//Function:
//Task:
//Calls:
// HÄMTAR ETT TRÄD FRÅN EN FIL
// läser in värdet i varje nod i preorder
// och sätter in det i trädet i preoder
// calls hashClass::insert
// calls: hashClass::isEmpty
//==================================================================
void _load(hashClass &hashTable)
{
fstream fil;
int i = 0;
char filnamn[FILENAMESIZE];
cout << "\n Ange filnamn att hämta: ";
cin >> filnamn;
hashTable.destroyHash(hashTable.getSize());
fil.open(filnamn,ios::in|ios::binary);
if(fil) {
while(fil.peek() != EOF) {
fil.read((char*)& hashTable.hashPtr[i],sizeof(hashTable.hashPtr[i]));
hashTable.insert(i, hashTable.hashPtr[i]);
i++;
}
}
else {
cerr << "\n Filen finns inte...";
getch();
}
hashTable.reHash(hashTable.getSize());
fil.close();
}
//##################################################################
//Function:
//Task:
//Calls:
// DESTROYTREE
// tar bort hela trädet
// calls: hashClass::isEmpty
// calls: hashClass::destroyHash
//==================================================================
void _destroyHash(hashClass &hashTable)
{
hashTable.destroyHash(hashTable.getSize());
cerr << "\n Telefonkatalogen är tom...";
getch();
}
//##################################################################
//Function:
//Task:
//Calls:
// MENY ITEMS
// skriver ut menyn på skärmen
//==================================================================
void meny()
{
clrscr();
cout << " \n TELEFON KATALOGEN "
<< " \n ----------------- "
<< " \n 1. Lägg till person "
<< " \n 2. Ta bort person "
<< " \n 3. Sök efter person "
<< " \n 4. Skriv ut "
<< " \n 5. Spara på fil "
<< " \n 6. Hämta från fil "
<< " \n 7. Radera hela katalogen "
<< " \n 0. Avsluta ";
gotoxy(2,12); //ställer markören under menyn
}
//##################################################################
//Function:
//Task:
//Calls:
// MAIN FUNCTION
// skapar trädet hashTable av typen hashClass
// calls: alla drivrutiner
//==================================================================
void main()
{
hashClass hashTable;
char val;
do {
meny();
val = mataInChar();
switch (val)
{
case '1' : _insert(hashTable);break;
case '2' : _del(hashTable);break;
case '3' : _search(hashTable);break;
case '4' : _print(hashTable);break;
case '5' : _save(hashTable);break;
case '6' : _load(hashTable);break;
case '7' : _destroyHash(hashTable);break;
case '0' : cout << "\n Programmet avslutat";break;
default : cerr << "\n Felaktigt val";getch();
}
}while(val != '0');
exit(0);
}

144
Simulering/lab1.cpp Normal file
View File

@@ -0,0 +1,144 @@
/* *********************************************************************** */
/* lab1.cpp 980910 */
/* Innehåller köhantering */
/* *********************************************************************** */
/* Daniel Westerberg */
/* Christian Ohlsson */
/* Anna-Maria Haglund */
/* Ingela Johansson */
/* Charlotta Lagerkvist */
/* *********************************************************************** */
#include "lab1.hpp"
/* *********************************************************************** */
/* constructorn */
/* Nollställer variabler */
/* INPUT: inget */
/* OUTPUT: inget */
/* *********************************************************************** */
queue::queue()
{
first = NULL;
last = NULL;
cur = NULL;
r = 0;
}
/* *********************************************************************** */
/* destructorn */
/* Tömmer listan */
/* INPUT: inget */
/* OUTPUT: inget */
/* *********************************************************************** */
queue::~queue()
{
cur = first;
while (cur)
{
first = cur;
cur = cur->next;
delete first;
}
first = NULL;
last = NULL;
cur = NULL;
r = 0;
}
/* *********************************************************************** */
/* enqueue() */
/* ställer en person med ett antal varor i kön */
/* INPUT: antal varor */
/* OUTPUT: bool */
/* *********************************************************************** */
bool queue::enqueue(int v)
{
if (cur = new kund)
{
cur->next=NULL;
cur->varor = v;
if (first == NULL)
first = cur;
else
last->next = cur;
last = cur;
return TRUE;
}
return FALSE;
}
/* *********************************************************************** */
/* dequeue() */
/* tar bort en person ur kön */
/* INPUT: inget */
/* OUTPUT: bool */
/* *********************************************************************** */
bool queue::dequeue()
{
if (cur = first)
{
if ((first = first->next) == NULL)
last=NULL;
delete cur;
return TRUE;
}
return FALSE;
}
/* *********************************************************************** */
/* warez() */
/* kollar hur lång varje kö är, tidsmässigt! */
/* INPUT: inget */
/* OUTPUT: tiden för varje kund baserad på antal varor */
/* *********************************************************************** */
int queue::warez()
{
int x=0;
cur = first;
while (cur)
{
x += cur->varor*R + B; // räknar ut tiden för varje kund + 'x'
cur = cur->next;
}
return x;
}
/* *********************************************************************** */
/* pay() */
/* betalningsfunktion, returnerar antalet varor kvar att betala */
/* INPUT: antal varor att läggas till */
/* OUTPUT: antal varor för första kunden i kön */
/* *********************************************************************** */
int queue::pay(int v)
{
if (first)
return (first->varor += v); // lägger till 'v' och returnerar
else
return 0;
}
/* *********************************************************************** */
/* queueSize() */
/* returnerar antalet kunder i kön */
/* INPUT: inget */
/* OUTPUT: Antal kunder i kön */
/* *********************************************************************** */
int queue::queueSize()
{
int x=0;
cur = first;
while (cur)
{
cur = cur->next;
x++;
}
return x;
}
/* *********************************************************************** */
/* isEmpty() */
/* kollar om en kö är tom */
/* INPUT: inget */
/* OUTPUT: TRUE om listan är tom */
/* *********************************************************************** */
bool queue::isEmpty() { return (first == NULL) ; }

57
Simulering/lab1.hpp Normal file
View File

@@ -0,0 +1,57 @@
/* *********************************************************************** */
/* lab1.hpp 980910 */
/* Headerfil för lab1 */
/* *********************************************************************** */
/* Daniel Westerberg */
/* Christian Ohlsson */
/* Anna-Maria Haglund */
/* Ingela Johansson */
/* Charlotta Lagerkvist */
/* *********************************************************************** */
#include <dos.h>
#include <conio.h>
#include <stdlib.h>
#include <iostream.h>
typedef int bool;
const bool TRUE=-1, FALSE=0;
const int K=6; //Konstant för antal kassor
const int R=8; //Konstant för antal sekunder per vara
const int B=20; //Konstant för betalning
const int T=100; //Konstant för hur mycket snabbare än real-time det går
const int MS=1000; //Konstant för antal ms på en sekund
const int SPM=60; //Antal sekunder per minut
const int STARTTID=9*SPM*SPM+SPM; //Gör att programmet startar 9.01
const int MOVEX=5; //Antal steg att flytta i X-led
const int CENT=100; //Ger 100% att starta med
const int FALL1=10; //Ger 10% chans
const int FALL2=40; //Ger 30% chans
const int FALL3=90; //Ger 50% chans
const int MAV=40; //Ger slumptal mellan 1 - 40
class queue
{
private:
typedef struct kund
{
struct kund *next;
int varor;
} kund;
kund *first;
kund *last;
kund *cur;
public:
char r;
queue();
~queue();
bool enqueue(int);
bool dequeue();
int warez();
int pay(int);
int queueSize();
bool isEmpty();
};

123
Simulering/main.cpp Normal file
View File

@@ -0,0 +1,123 @@
/* *********************************************************************** */
/* main.cpp 980910 */
/* Innehåller huvudprogram för köhantering */
/* *********************************************************************** */
/* Daniel Westerberg */
/* Christian Ohlsson */
/* Anna-Maria Haglund */
/* Ingela Johansson */
/* Charlotta Lagerkvist */
/* *********************************************************************** */
#include "lab1.hpp"
/* *********************************************************************** */
/* Klassarray */
/* *********************************************************************** */
class queue q[K];
/* *********************************************************************** */
/* funktionsprototyper som denna fil innehåller */
/* *********************************************************************** */
void betala(int);
void print(long);
void addkund(void);
/* *********************************************************************** */
/* main med huvud-loop och delay */
/* *********************************************************************** */
void main()
{
long clock=STARTTID;
int kund=0;
while(!kbhit())
{
print(clock++);
if (++kund == SPM)
{
addkund();
kund=0;
}
for(int x=0; x<K; x++)
betala(x);
delay(MS/T);
}
}
/* *********************************************************************** */
/* print() */
/* skriver ut allting på skärmen */
/* INPUT: klockan */
/* OUTPUT: Tiden på skärmen */
/* *********************************************************************** */
void print(long cl)
{
for(int x=0; x<K; x++)
{
gotoxy(2,x+MOVEX);
cout << "Kassa nr " << (x+1) << "; Varor: " << q[x].pay(0) << ' ';
gotoxy(23,x+MOVEX);
cout << ", Kunder: " << q[x].queueSize() << ' ';
}
gotoxy(1,1);
cout<<"Tid: "<<(cl/(SPM*SPM))<<':'<<((cl/SPM)%SPM)<<':'<<(cl%SPM)<<" ";
}
/* *********************************************************************** */
/* betala() */
/* beräknar tiden för varorna och tar bort varor och kunder */
/* INPUT: position i klassarray */
/* OUTPUT: inget */
/* *********************************************************************** */
void betala(int pos)
{
if(q[pos].isEmpty()==0)
if(q[pos].pay(0))
{
q[pos].r++;
if(q[pos].r==R)
if(q[pos].pay(-1)==0)
q[pos].r=B;
else
q[pos].r=0;
}
else
if(q[pos].r>0)
q[pos].r--;
else
q[pos].dequeue();
}
/* *********************************************************************** */
/* addkund() */
/* lägger till en kund med ett slumpmässigt antal varor i den minsta kön */
/* INPUT: inget */
/* OUTPUT: inget */
/* *********************************************************************** */
void addkund()
{
int in, x, min, pos=0;
unsigned int slumptal;
srand((unsigned) time(NULL));
slumptal = rand()%CENT;
if (slumptal < FALL1)
in=0;
else if (slumptal < FALL2)
in=1;
else if (slumptal < FALL3)
in=2;
else
in=3;
while(in)
{
min=q[0].warez();
for(x=1; x<K; x++)
if (min>q[x].warez())
{
min=q[x].warez();
pos=x;
}
q[pos].enqueue(rand()%MAV+1);
in--;
}
}