<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
佇列和前文所學的棧還是有一定區別的,佇列明確指出先進先出。假如說一個佇列的入隊順序為A B C D,那麼出隊順序一定為A B C D,因為無論你是在A進去再出來,然後B進去再出來接著CD進去再出來或者類似的,都不會影響它最終的出隊順序A B C D。這點和棧還是有區別的,畢竟棧是後進先出。
佇列:
棧:
思路:
這裡要定義兩個結構體,除了要定義1個鏈式結構來記錄各個節點外,還要定義一個結構來記錄隊頭和隊尾。以此方便後續的隊尾入資料,隊頭出資料。
Queue.h 檔案:
//建立佇列結構 typedef int QDataType; //方便後續更改儲存資料型別,本文以int為例 //建立佇列節點 typedef struct QueueNode { QDataType data; //儲存資料 struct QueueNode* next; //記錄下一個節點 }QNode; //儲存隊頭和隊尾 typedef struct Queue { QNode* head; //頭指標 QNode* tail; //尾指標 }Queue;
思路:
佇列可以為空,但是管理頭指標和尾指標的結構體不能為空,所以一開始就要斷言。其次,在插入資料前,佇列肯定是空的,所以直接把頭指標和尾指標置空即可。
Queue.h 檔案:
//初始化佇列 void QueueInit(Queue* pq);
Queue.c 檔案:
//初始化佇列 void QueueInit(Queue* pq) { assert(pq); pq->head = pq->tail = NULL; }
思路:
銷燬佇列就是把佇列的每個資料都銷燬掉,那麼需要遍歷連結串列進行挨個銷燬free。首先定義一個cur指標為pq->head,用來儲存第一個資料,遍歷cur,如果不為空,就free。最後把tail和head置空即可。
Queue.h 檔案:
//銷燬佇列 void QueueDestory(Queue* pq);
Queue.c 檔案:
//銷燬佇列 void QueueDestory(Queue* pq) { assert(pq); QNode* cur = pq->head; while (cur) { QNode* next = cur->next; free(cur); cur = next; } pq->head = pq->tail = NULL; }
思路:
入佇列其實很簡單,只需要尾插即可,首先要新建立一個節點來儲存新插入的資料。但是在尾插之前要考慮如果一開始佇列沒有資料,為空,那麼只需要把head和tail節點指向新節點newnode節點即可。相反的,如果一開始就有資料,那麼只需正常尾插把tail的next指向新節點newnode,再把newnode賦給tail即可。
Queue.h 檔案:
//入佇列 void QueuePush(Queue* pq, QDataType x);
Queue.c 檔案:
//入佇列 void QueuePush(Queue* pq, QDataType x) { assert(pq); //建立一個新節點儲存資料 QNode* newnode = (QNode*)malloc(sizeof(QNode)); //暴力檢測newnode,因為malloc的都要檢測 assert(newnode); newnode->next = NULL; newnode->data = x; //如果一開始沒有資料,為空的情況 if (pq->tail == NULL) { assert(pq->head == NULL); pq->head = pq->tail = newnode; } else { pq->tail->next = newnode; pq->tail = newnode; } }
思路:
特殊情況:
這裡在刪除資料時,首先要考慮特殊情況,當刪到只剩一個資料時,再刪一次,此時資料是沒了,不過head為空了,而tail變成野指標了,為了避免此現象的產生,單獨討論並置空head和tail即可。
一般情況:
此時只需要定義一個next指標儲存head的下一個節點,將head移動到next即可,並把舊的head置空。
Queue.h 檔案:
//出佇列 void QueuePop(Queue* pq);
Queue.c 檔案:
//出佇列 void QueuePop(Queue* pq) { assert(pq); assert(pq->head && pq->tail); //tail和head均不能為空 //特殊:當刪到head=tail的位置時 if (pq->head->next == NULL) { free(pq->head); pq->head = pq->tail = NULL; } //一般情況 else { //儲存head的下一個節點 QNode* next = pq->head->next; free(pq->head); pq->head = next; } }
思路:
如果head為空或者tail為空都是判空的條件,直接返回即可。
Queue.h 檔案:
//判空 bool QueueEmpty(Queue* pq);
Queue.c 檔案:
//判空 bool QueueEmpty(Queue* pq) { assert(pq); return pq->head == NULL; }
思路:
求元素個數其實不難,只需要定義一個cur指標為第一個資料pq->head,定義變數size來記錄個數。依次遍歷cur,不為空,size就++。這種遍歷的思想不復雜,但時間複雜度達到O(N),不是太好,想要O(1)的話可以直接在當初定義結構體時多定義一個size變數,專門用來記錄有效元素個數,每次入佇列size++,出佇列size--。這樣實現是比較好的,不過為了封裝成一個獨立模組,還是採用遍歷的方式。如下:
Queue.h 檔案:
//獲取有效元素個數 size_t QueueSize(Queue* pq);
Queue.c 檔案:
//獲取有效元素個數 size_t QueueSize(Queue* pq) { assert(pq); QNode* cur = pq->head; size_t size = 0; while (cur) { size++; cur = cur->next; } return size; }
思路:
首先要斷言頭部不能為空,如果頭部都為空了,那還怎麼能獲得頭部元素,其次直接返回頭部head的資料即可。
Queue.h 檔案:
//獲取隊頭元素 QDataType QueueFront(Queue* pq);
Queue.c 檔案:
//獲取隊頭元素 QDataType QueueFront(Queue* pq) { assert(pq); assert(pq->head); //頭部不能為空 return pq->head->data; }
思路:
有了獲取隊頭元素的經驗,隊尾就更簡單了,把head換位tail即可,結構與上文一樣。
Queue.h 檔案:
//獲取隊尾元素 QDataType QueueBack(Queue* pq);
Queue.c 檔案:
//獲取隊尾元素 QDataType QueueBack(Queue* pq) { assert(pq); assert(pq->tail); //尾部不能為空 return pq->tail->data; }
#pragma once #include<stdio.h> #include<stdlib.h> #include<assert.h> #include<stdbool.h> //建立佇列結構 typedef int QDataType; //方便後續更改儲存資料型別,本文以int為例 //建立佇列節點 typedef struct QueueNode { QDataType data; //儲存資料 struct QueueNode* next; //記錄下一個節點 }QNode; //儲存隊頭和隊尾 typedef struct Queue { QNode* head; //頭指標 QNode* tail; //尾指標 }Queue; //初始化佇列 void QueueInit(Queue* pq); //銷燬佇列 void QueueDestory(Queue* pq); //入佇列 void QueuePush(Queue* pq, QDataType x); //出佇列 void QueuePop(Queue* pq); //判空 bool QueueEmpty(Queue* pq); //獲取有效元素個數 size_t QueueSize(Queue* pq); //獲取隊頭元素 QDataType QueueFront(Queue* pq); //獲取隊尾元素 QDataType QueueBack(Queue* pq);
#define _CRT_SECURE_NO_WARNINGS 1 #include"Queue.h" //初始化佇列 void QueueInit(Queue* pq) { assert(pq); pq->head = pq->tail = NULL; } //銷燬佇列 void QueueDestory(Queue* pq) { assert(pq); QNode* cur = pq->head; while (cur) { QNode* next = cur->next; free(cur); cur = next; } pq->head = pq->tail = NULL; } //入佇列 void QueuePush(Queue* pq, QDataType x) { assert(pq); //建立一個新節點儲存資料 QNode* newnode = (QNode*)malloc(sizeof(QNode)); //暴力檢測newnode,因為malloc的都要檢測 assert(newnode); newnode->next = NULL; newnode->data = x; //如果一開始沒有資料,為空的情況 if (pq->tail == NULL) { assert(pq->head == NULL); pq->head = pq->tail = newnode; } else { pq->tail->next = newnode; pq->tail = newnode; } } //出佇列 void QueuePop(Queue* pq) { assert(pq); assert(pq->head && pq->tail); //tail和head均不能為空 //特殊:當刪到head=tail的位置時 if (pq->head->next == NULL) { free(pq->head); pq->head = pq->tail = NULL; } //一般情況 else { //儲存head的下一個節點 QNode* next = pq->head->next; free(pq->head); pq->head = next; } } //判空 bool QueueEmpty(Queue* pq) { assert(pq); return pq->head == NULL; } //獲取有效元素個數 size_t QueueSize(Queue* pq) { assert(pq); QNode* cur = pq->head; size_t size = 0; while (cur) { size++; cur = cur->next; } return size; } //獲取隊頭元素 QDataType QueueFront(Queue* pq) { assert(pq); assert(pq->head); //頭部不能為空 return pq->head->data; } //獲取隊尾元素 QDataType QueueBack(Queue* pq) { assert(pq); assert(pq->tail); //尾部不能為空 return pq->tail->data; }
#define _CRT_SECURE_NO_WARNINGS 1 #include"Queue.h" void TestQueue() { Queue q; QueueInit(&q); //插入資料 QueuePush(&q, 1); QueuePush(&q, 2); QueuePush(&q, 3); QueuePush(&q, 4); //列印 while (!QueueEmpty(&q)) { printf("%d ", QueueFront(&q)); QueuePop(&q); } printf("n"); } int main() { TestQueue(); return 0; }
到此這篇關於C語言超詳細講解佇列的實現及程式碼的文章就介紹到這了,更多相關C語言 佇列的實現內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45