Σημειώσεις ένατης εβδομάδας Η δομή της ουράς (queue), είναι και αυτή γραμμική δομή, όπως η λίστα και η στοίβα. Το βασικό χαρακτηριστικό της είναι ότι, όπως και στις φυσικές ουρές, εξυπηρετείται πρώτος, αυτός που ήρθε πρώτος. Η εισαγωγή κόμβων γίνεται στην ουρά του Queue, ενώ η εξαγωγή κόμβων γίνεται πάντα από την κεφαλή της ουράς. Οι βασικές λειτουργίες είναι enqueue και dequeue. Ο λόγος ότι προσθέτουμε στο τέλος ενώ τραβάμε τιμές από την κορυφή μας αναγκάζει να χρησιμοποιήσουμε δύο δείκτες. /* ** παράδειγμα Queue από το βιβλίο Deitel & Deitel */ #include <stdio.h> #include <stdlib.h> struct queuenode { char data; struct queuenode *nextptr; ; typedef struct queuenode QueueNode; typedef QueueNode *QueueNodePtr; void printqueue(queuenodeptr currentptr); int isempty(queuenodeptr headptr); char dequeue(queuenodeptr *headptr, QueueNodePtr *tailptr); void enqueue(queuenodeptr *headptr, QueueNodePtr *tailptr, char value); void instructions(void); int main(void){ QueueNodePtr headptr=null; QueueNodePtr tailptr=null; int choice; char item; instructions(); printf("? "); scanf("%d",&choice); while(choice!=3) { switch(choice){ case 1: printf("enter a char: "); scanf("\n%c",&item); enqueue(&headptr,&tailptr,item); Σημειώσεις Εργαστηρίου Δομών και Αλγορίθμων Week9 1 costis@teicrete.gr
printqueue(headptr); break; case 2: if(!isempty(headptr)){ item=dequeue(&headptr,&tailptr); printf("%c has been dequeued.\n",item); printqueue(headptr); break; default: printf("invalid choice.\n"); instructions(); break; printf("? "); scanf("%d",&choice); printf("end of run.\n"); return 0; void instructions(void) { printf("enter your choice:\n" " 1 to add an item to the queue.\n" " 2 to remove an item from the queue.\n" " 3 to end.\n"); void enqueue(queuenodeptr *headptr, QueueNodePtr *tailptr, char value){ QueueNodePtr newptr; newptr=malloc(sizeof(queuenode)); if(newptr!=null){ newptr->data=value; newptr->nextptr=null; if(isempty(*headptr)) *headptr=newptr; (*tailptr)->nextptr=newptr; *tailptr=newptr; printf("%c not inserted. No memory.\n",value); Σημειώσεις Εργαστηρίου Δομών και Αλγορίθμων Week9 2 costis@teicrete.gr
char dequeue(queuenodeptr *headptr, QueueNodePtr *tailptr){ char value; QueueNodePtr tempptr; value=(*headptr)->data; tempptr=*headptr; *headptr=(*headptr)->nextptr; if(*headptr==null){ *tailptr=null; free(tempptr); return value; int isempty(queuenodeptr headptr){ return headptr==null; void printqueue(queuenodeptr currentptr) { if (currentptr == NULL) printf("queue is empty.\n\n"); { printf("the queue is:\n"); while (currentptr!= NULL) { printf("%c --> ", currentptr->data); currentptr = currentptr->nextptr; printf("null\n\n"); Η δομή του δένδρου (tree), είναι μη γραμμική δομή. Κάθε κόμβος περιέχει δύο δείκτες. Σε μία απλή υλοποίηση η κορυφή του δέντρου παραμένει σταθερή. Εισαγωγή κόμβων γίνεται πάντα μετά από αναζήτηση και τοποθετούνται στην κατάλληλη θέση έτσι ώστε ο κανόνας: ο αριστερός κόμβος να είναι μικρότερος από τον τρέχοντα και ο δεξιός μεγαλύτερος να ισχύει πάντα. /* ** παράδειγμα Binary Tree από το βιβλίο Deitel & Deitel */ #include <stdio.h> #include <stdlib.h> struct treenode { struct treenode *leftptr; int data; Σημειώσεις Εργαστηρίου Δομών και Αλγορίθμων Week9 3 costis@teicrete.gr
; struct treenode *rightptr; typedef struct treenode TreeNode; typedef TreeNode* TreeNodePtr; void insertnode(treenodeptr *treeptr,int value); void inorder(treenodeptr treeptr); int main(void){ TreeNodePtr rootptr = NULL; insertnode(&rootptr, 13); insertnode(&rootptr, 6); insertnode(&rootptr, 17); insertnode(&rootptr, 27); insertnode(&rootptr, 33); insertnode(&rootptr, 42); insertnode(&rootptr, 48); printf("\n -----inorder---------------------------------------\n"); inorder(rootptr); return 0; void insertnode(treenodeptr *treeptr,int value){ if(*treeptr==null) { *treeptr=malloc(sizeof(treenode)); if(*treeptr!=null){ (*treeptr)->data=value; (*treeptr)->leftptr=null; (*treeptr)->rightptr=null; { printf("no memory\n"); { if(value < (*treeptr)->data) insertnode(&((*treeptr)->leftptr), value); if(value>(*treeptr)->data) insertnode(&((*treeptr)->rightptr), value); printf("dup"); void inorder(treenodeptr treeptr) { if (treeptr!= NULL) { inorder(treeptr->leftptr); printf("%3d ", treeptr->data); inorder(treeptr->rightptr); Σημειώσεις Εργαστηρίου Δομών και Αλγορίθμων Week9 4 costis@teicrete.gr
Η πρόσβαση στους κόμβους το δένδρου μπορεί να γίνει με τους παρακάτω τρόπους 1 : 1 Wikipedia http://en.wikipedia.org/wiki/tree_traversal Σημειώσεις Εργαστηρίου Δομών και Αλγορίθμων Week9 5 costis@teicrete.gr
Σημειώσεις Εργαστηρίου Δομών και Αλγορίθμων Week9 6 costis@teicrete.gr
Ψευδοκώδικας: preorder(node) if node == null then return preorder(node.left) preorder(node.right) iterativepreorder(node) parentstack = empty stack while (not parentstack.isempty() or node null) if (node null) parentstack.push(node) node = node.left node = parentstack.pop() node = node.right In-order inorder(node) if node == null then return inorder(node.left) inorder(node.right) iterativeinorder(node) parentstack = empty stack while (not parentstack.isempty() or node null) if (node null) parentstack.push(node) node = node.left node = parentstack.pop() node = node.right Post-order postorder(node) if node == null then return postorder(node.left) postorder(node.right) iterativepostorder(node) parentstack = empty stack lastnodevisited = null while (not parentstack.isempty() or node null) if (node null) parentstack.push(node) node = node.left peeknode = parentstack.peek() if (peeknode.right null and lastnodevisited peeknode.right) /* if right child exists AND traversing node from left child, move right */ node = peeknode.right parentstack.pop() visit(peeknode) lastnodevisited = peeknode Σημειώσεις Εργαστηρίου Δομών και Αλγορίθμων Week9 7 costis@teicrete.gr
Πρόσβαση levelorder: 1. Ψευδοκώδικας: levelorder(root) q = empty queue q.enqueue(root) while not q.empty do node := q.dequeue() if node.left null then q.enqueue(node.left) if node.right null then q.enqueue(node.right) 2. Υλοποίηση σε C: void levelorder(treenodeptr treeptr) { QueueNodePtr qh= NULL; QueueNodePtr qt= NULL; enqueue(&qh, &qt, treeptr); do { treeptr=dequeue(&qh, &qt); printf("%3d ", treeptr->data); if(treeptr->leftptr!=null) enqueue(&qh, &qt, treeptr->leftptr); if(treeptr->rightptr!=null) enqueue(&qh,&qt, treeptr->rightptr); while(!isempty(qh)); Σημειώσεις Εργαστηρίου Δομών και Αλγορίθμων Week9 8 costis@teicrete.gr