《資料結構》嚴蔚敏 鏈式儲存實現佇列 演算法3_4_2
阿新 • • 發佈:2019-01-12
這個用連結串列代替陣列來實現佇列
這個程式碼書寫的時候注意ClearQueue(Link_Queue *q)
和DestroyQueue(Link_Queue *q)
這兩個函式
前者在寫的時候:要注意第一步是先將rear指標挪到指向佇列首元素的位置,然後一舉將剩下的元素一併釋放,接著再釋放首元素,然後使兩個指標都指向頭節點
後者在寫的時候:要注意第一步也是先將rear指標挪到指向佇列首元素的位置,但是此時是將包括首元素在內一併都釋放掉。然後讓兩個指標都指向空。
剩下的和連結串列操作就差不多了,無需多費口舌
//用鏈式儲存佇列 //注意ClearQueue(Link_Queue *q) 寫得很全面 #include<stdio.h> #include<stdlib.h> #define OK 0 #define ERROR -1 typedef int Status; typedef int QElemType; //連結串列上鍊的每一個結構 typedef struct QNode { QElemType data; struct QNode *next; }QNode,*QueuePtr; //連結串列本身 typedef struct { QueuePtr front; QueuePtr rear; }Link_Queue; Status InitQueue(Link_Queue * q) { //建立一個頭節點和一個頭指標 q->front = (QueuePtr)malloc(sizeof(QNode)); if(q->front == NULL) //return ERROR; exit(ERROR); q->rear = q->front; q->front->next = NULL; return OK; } Status DestroyQueue(Link_Queue *q) { //free(q); //這考慮的也太navie了 while(q->front) { q->rear = q->front->next; free(q->front); q->front = q->rear; } return OK; } //巧妙 Status ClearQueue(Link_Queue *q) { // if(q->front != q->rear) // q->front --; // q->front->next = NULL; q->rear = q->front->next;//先儲存一下 while(q->rear) { q->front->next = q->rear->next; free(q->rear); q->rear = q->front->next; } q->rear = q->front; return OK; } Status QueueEmpty(Link_Queue q) { if(q.front == q.rear) return OK; else return ERROR; } int QueueLength(Link_Queue q) { int count = 0; QueuePtr p = q.front; while(p != q.rear) { count++; p=p->next; } return count; //return q.rear - q.front; //this have a little question //算不算上頭節點呢,是用頭減尾還是尾減頭呢? } Status GetHead(Link_Queue q,QElemType *e) { *e = q.front->next->data; return OK; } Status EnQueue(Link_Queue *q,QElemType e) { QueuePtr temp; temp = (QueuePtr)malloc(sizeof(QNode)); if(temp == NULL) //return ERROR; exit(ERROR); temp->data = e; //temp = q->front; // while( temp != q->rear) //這裡有尾指標啊大哥 // { // temp = temp->next; // } //q->rear->next = temp; temp->next = NULL; q->rear->next = temp; q->rear = temp; //最後要把為指標改變一下 return OK; } Status DeQueue(Link_Queue *q,QElemType *e) { if( q->front == q->rear ) return ERROR; //刪除的時候要把原來的儲存一下,好釋放空間 QueuePtr temp; temp = q->front->next; *e = temp->data; q->front->next = temp->next; //當刪除最後一個元素時需要注意⚠️此時隊尾指標丟了 if(q->rear == temp) q->rear = q->front; free(temp); //q->front->next = q->front->next->next; return OK; } Status QueueTraverse(Link_Queue q,void(*visit)(QElemType )) { if( q.front == q.rear ) return ERROR; while(q.front != q.rear) { q.front = q.front->next; visit(q.front->data); } printf("\n"); return OK; } void visit(QElemType c) { printf("%d ", c); } int main(int argc, char const *argv[]) { Link_Queue q; QElemType delete,length; InitQueue(&q); EnQueue(&q,1); EnQueue(&q,2); EnQueue(&q,3); EnQueue(&q,4); GetHead(q,&delete); printf("top is %d ", delete); printf("\nAfter insert: "); QueueTraverse(q,visit); length = QueueLength(q); printf("queue length is %d \n", length); DeQueue(&q,&delete); printf("\ndelete %d is ok!\n", delete); printf("\nAfter delete: "); QueueTraverse(q,visit); length = QueueLength(q); printf("queue length is %d \n", length); printf("\n"); return 0; }