Startpunkten
This commit is contained in:
76
AVL_tree/header.hpp
Normal file
76
AVL_tree/header.hpp
Normal 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
273
AVL_tree/huvud.cpp
Normal 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
BIN
AVL_tree/run_me
Normal file
Binary file not shown.
344
AVL_tree/tree.cpp
Normal file
344
AVL_tree/tree.cpp
Normal 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
BIN
Dijkstra/NeverNeverLand.doc
Normal file
Binary file not shown.
BIN
Dijkstra/dijkstra.exe
Normal file
BIN
Dijkstra/dijkstra.exe
Normal file
Binary file not shown.
285
Dijkstra/graf.cpp
Normal file
285
Dijkstra/graf.cpp
Normal 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
75
Dijkstra/graf.h
Normal 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
36
Dijkstra/header.h
Normal 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
240
Dijkstra/list.h
Normal 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
191
Dijkstra/main.cpp
Normal 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
BIN
Dijkstra/map.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
1068
Dijkstra/network.txt
Normal file
1068
Dijkstra/network.txt
Normal file
File diff suppressed because it is too large
Load Diff
17
Dijkstra/read_me
Normal file
17
Dijkstra/read_me
Normal 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
292
Hashing/hash.cpp
Normal 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
83
Hashing/header.hpp
Normal 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
294
Hashing/huvud.cpp
Normal 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
144
Simulering/lab1.cpp
Normal 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
57
Simulering/lab1.hpp
Normal 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
123
Simulering/main.cpp
Normal 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--;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user