1. 程式人生 > >資料結構C語言實現之鏈式佇列的6種演算法程式碼

資料結構C語言實現之鏈式佇列的6種演算法程式碼

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. typedef int elemType;
  4. /************************************************************************/
  5. /* 以下是關於佇列連結儲存操作的6種演算法 */
  6. /************************************************************************/
  7. struct sNode{
  8.     elemType data; /* 值域 */
  9.     struct sNode *next;
    /* 連結指標 */
  10. };
  11. struct queueLK{
  12.     struct sNode *front; /* 隊首指標 */
  13.     struct sNode *rear; /* 隊尾指標 */
  14. };
  15. /* 1.初始化鏈隊 */
  16. void initQueue(struct queueLK *hq)
  17. {
  18.     hq->front = hq->rear = NULL; /* 把隊首和隊尾指標置空 */
  19.     return;
  20. }
  21. /* 2.向鏈隊中插入一個元素x */
  22. void enQueue(struct queueLK *hq, elemType x)
  23. {
  24.     /* 得到一個由newP指標所指向的新結點 */
  25.     struct
    sNode *newP;
  26.     newP = malloc(sizeof(struct sNode));
  27.     if(newP == NULL){
  28.         printf("記憶體空間分配失敗! ");
  29.         exit(1);
  30.     }
  31.     /* 把x的值賦給新結點的值域,把新結點的指標域置空 */
  32.     newP->data = x;
  33.     newP->next = NULL;
  34.     /* 若鏈隊為空,則新結點即是隊首結點又是隊尾結點 */
  35.     if(hq->rear == NULL){
  36.         hq->front = hq->rear =
    newP;
  37.     }else{ /* 若鏈隊非空,則依次修改隊尾結點的指標域和隊尾指標,使之指向新的隊尾結點 */
  38.         hq->rear = hq->rear->next = newP; /* 注意賦值順序哦 */
  39.     }
  40.     return;
  41. }
  42. /* 3.從佇列中刪除一個元素 */
  43. elemType outQueue(struct queueLK *hq)
  44. {
  45.     struct sNode *p;
  46.     elemType temp;
  47.     /* 若鏈隊為空則停止執行 */
  48.     if(hq->front == NULL){
  49.         printf("佇列為空,無法刪除! ");
  50.         exit(1);
  51.     }
  52.     temp = hq->front->data; /* 暫存隊尾元素以便返回 */
  53.     p = hq->front; /* 暫存隊尾指標以便回收隊尾結點 */
  54.     hq->front = p->next; /* 使隊首指標指向下一個結點 */
  55.     /* 若刪除後鏈隊為空,則需同時使隊尾指標為空 */
  56.     if(hq->front == NULL){
  57.         hq->rear = NULL;
  58.     }
  59.     free(p); /* 回收原隊首結點 */
  60.     return temp; /* 返回被刪除的隊首元素值 */
  61. }
  62. /* 4.讀取隊首元素 */
  63. elemType peekQueue(struct queueLK *hq)
  64. {
  65.     /* 若鏈隊為空則停止執行 */
  66.     if(hq->front == NULL){
  67.         printf("佇列為空,無法刪除! ");
  68.         exit(1);
  69.     }
  70.     return hq->front->data; /* 返回隊首元素 */
  71. }
  72. /* 5.檢查鏈隊是否為空,若為空則返回1, 否則返回0 */
  73. int emptyQueue(struct queueLK *hq)
  74. {
  75.     /* 判斷隊首或隊尾任一個指標是否為空即可 */
  76.     if(hq->front == NULL){
  77.         return 1;
  78.     }else{
  79.         return 0;
  80.     }
  81. }
  82. /* 6.清除鏈隊中的所有元素 */
  83. void clearQueue(struct queueLK *hq)
  84. {
  85.     struct sNode *p = hq->front; /* 隊首指標賦給p */
  86.     /* 依次刪除佇列中的每一個結點,最後使隊首指標為空 */
  87.     while(p != NULL){
  88.         hq->front = hq->front->next;
  89.         free(p);
  90.         p = hq->front;
  91.     } /* 迴圈結束後隊首指標已經為空 */
  92.     hq->rear = NULL; /* 置隊尾指標為空 */
  93.     return;
  94. }
  95. /************************************************************************/
  96. int main(int argc, char* argv[])
  97. {
  98.     struct queueLK q;
  99.     int a[8] = {3, 8, 5, 17, 9, 30, 15, 22};
  100.     int i;
  101.     initQueue(&q);
  102.     for(i = 0; i < 8; i++){
  103.         enQueue(&q, a[i]);
  104.     }
  105.     printf("%d ", outQueue(&q)); printf("%d ", outQueue(&q));
  106.     enQueue(&q, 68);
  107.     printf("%d ", peekQueue(&q)); printf("%d ", outQueue(&q));
  108.     while(!emptyQueue(&q)){
  109.         printf("%d ", outQueue(&q));
  110.     }
  111.     printf(" ");
  112.     clearQueue(&q);
  113.     system("pause");
  114. }
  115. ##################################################################
  116. PART II
  117. #include <stdio.h>
  118. #include <stdlib.h>
  119. typedef int elemType;
  120. /************************************************************************/
  121. /* 以下是關於佇列順序儲存操作的6種演算法 */
  122. /************************************************************************/
  123. struct queue{
  124.     elemType *queue; /* 指向儲存佇列的陣列空間 */
  125.     int front, rear, len; /* 隊首指標(下標),隊尾指標(下標),佇列長度變數 */
  126.     int maxSize; /* queue陣列長度 */
  127. };
  128. void againMalloc(struct queue *q)
  129. {
  130.     /* 空間擴充套件為原來的2倍,原內容被自動拷貝到p所指向的儲存空間中 */
  131.     elemType *p;
  132.     p = realloc(q->queue, 2 * q->maxSize * sizeof(elemType));
  133.     /* 動態儲存空間分配,若失敗則退出執行 */
  134.     if(!p){
  135.         printf("空間分配失敗! ");
  136.         exit(1);
  137.     }
  138.     q->queue = p; /* 使queue指向新的佇列空間 */
  139.     /* 把原佇列的尾部內容後移maxSize個位置 */
  140.     if(q->rear != q->maxSize -1){
  141.         int i;
  142.         for(i = 0; i <= q->rear; i++){
  143.             q->queue[i+q->maxSize] = q->queue[i];
  144.         }
  145.         q->rear += q->maxSize; /* 隊尾指標後移maxSize個位置 */
  146.     }
  147.     q->maxSize = 2 * q->maxSize; /* 把佇列空間大小修改為新的長度 */
  148.     return;
  149. }
  150. /* 1.初始化佇列 */
  151. void initQueue(struct queue *q, int ms)
  152. {
  153.     /* 檢查ms是否有效,若無效則退出執行 */
  154.     if(ms <= 0){
  155.         printf("ms值非法! ");
  156.         exit(1);
  157.     }
  158.     q->maxSize = ms; /* 置佇列空間大小為ms */
  159.     /* 動態儲存空間分配,若失敗則退出執行 */
  160.     q->queue = malloc(ms * sizeof(elemType));
  161.     if(!q->queue){
  162.         printf("記憶體空間分配失敗! ");
  163.         exit(1);
  164.     }
  165.     q->front = q->rear = 0; /* 初始置佇列為空 */
  166.     return;
  167. }
  168. /* 2.向佇列中插入元素x */
  169. void enQueue(struct queue *q, elemType x)
  170. {
  171.     /* 當佇列滿時進行動態生分配 */
  172.     if((q->rear + 1) % q->maxSize == q->front){
  173.         againMalloc(q);
  174.     }
  175.     q->rear = (q->rear + 1) % q->maxSize; /* 求出隊尾的下一個位置 */
  176.     q->queue[q->rear] = x; /* 把x的值賦給新的隊尾 */
  177.     return;
  178. }
  179. /* 3.從佇列中刪除元素並返回 */
  180. elemType outQueue(struct queue *q)
  181. {
  182.     /* 若佇列為空則終止執行 */
  183.     if(q->front == q->rear){
  184.         printf("佇列為空,無法刪除! ");
  185.         exit(1);
  186.     }
  187.     q->front = (q->front +1) % q->maxSize; /* 使隊首指標指向下一個位置 */
  188.     return q->queue[q->front]; /* 返回隊首元素 */
  189. }
  190. /* 4.讀取隊首元素,不改變佇列狀態 */
  191. elemType peekQueue(struct queue *q)
  192. {
  193.     /* 若佇列為空則終止執行 */
  194.     if(q->front == q->rear){
  195.         printf("佇列為空,無法刪除! ");
  196.         exit(1);
  197.     }
  198.     return q->queue[(q->front +1) % q->maxSize];/* 隊首元素是隊首指標的下一個位置中的元素 */
  199. }
  200. /* 5.檢查一個佇列是否為空,若是則返回1,否則返回0 */
  201. int emptyQueue(struct queue *q)
  202. {
  203.     if(q->front == q->rear){
  204.         return 1;
  205.     }else{
  206.         return 0;
  207.     }
  208. }
  209. /* 6.清除一個佇列,並釋放動態儲存空間 */
  210. void clearQueue(struct queue *q)
  211. {
  212.     if(q->queue != NULL){
  213.         free(q->queue);
  214.         q->queue = NULL; /* 設定佇列空間指標為空 */
  215.         q->front = q->rear = 0; /* 設定佇列為空 */
  216.         q->maxSize = 0; /* 設定佇列大小為0 */
  217.     }
  218.     return;
  219. }
  220. /************************************************************************/
  221. int main(int argc, char* argv[])
  222. {
  223.     struct queue q;
  224.     int a[8] = {3, 8, 5, 17, 9, 30, 15, 22};
  225.     int i;
  226.     initQueue(&q, 5);
  227.     for(i = 0; i < 8; i++){
  228.         enQueue(&q, a[i]);
  229.     }
  230.     printf("%d ", outQueue(&q)); printf("%d ", outQueue(&q));
  231.     enQueue(&q, 68);
  232.     printf("%d ", peekQueue(&q)); printf("%d ", outQueue(&q));
  233.     while(!emptyQueue(&q)){
  234.         printf("%d ", outQueue(&q));
  235.     }
  236.     printf(" ");
  237.     clearQueue(&q);
  238.     system("pause");
  239.     return 0;
  240. }