C語言詳解鏈?zhǔn)疥?duì)列與循環(huán)隊(duì)列的實(shí)現(xiàn)
隊(duì)列的實(shí)現(xiàn)
隊(duì)列是一種先進(jìn)先出(First in First Out)的線性表,簡稱FIFO。與棧不同,棧是一種后進(jìn)先出(先進(jìn)后出)的線性表。在隊(duì)列中,允許插入的一端稱為隊(duì)尾,允許刪除的一端稱為隊(duì)頭。假設(shè)隊(duì)列是q=(a1,a2,…,an),那么a1就是隊(duì)頭元素,而an是隊(duì)尾元素。這樣我們就可以刪除時,總是從a1開始,而插入時,列在最后。這也比較符合我們通常生活中的習(xí)慣,排在第一個的優(yōu)先出列,最后來的當(dāng)然在隊(duì)伍的最后。隊(duì)列分為順序隊(duì)列和循環(huán)隊(duì)列。順序隊(duì)列我們可以利用數(shù)組或者鏈表實(shí)現(xiàn)。這里,我們選擇用鏈表實(shí)現(xiàn)順序隊(duì)列。
今天主要介紹鏈表實(shí)現(xiàn)的隊(duì)列和循環(huán)隊(duì)列
鏈?zhǔn)疥?duì)列
隊(duì)列主要有哪些基本操作
// 初始化隊(duì)列 void QueueInit(Queue* q); ? // 隊(duì)尾入隊(duì)列 void QueuePush(Queue* q, QDataType data); // 隊(duì)頭出隊(duì)列 void QueuePop(Queue* q); // 獲取隊(duì)列頭部元素 QDataType QueueFront(Queue* q); // 獲取隊(duì)列隊(duì)尾元素 QDataType QueueBack(Queue* q); // 獲取隊(duì)列中有效元素個數(shù) int QueueSize(Queue* q); // 檢測隊(duì)列是否為空,如果為空返回非零結(jié)果,如果非空返回0 bool QueueEmpty(Queue* q); // 銷毀隊(duì)列 void QueueDestroy(Queue* q);
鏈?zhǔn)疥?duì)列的定義
typedef int QDataType; // 鏈?zhǔn)浇Y(jié)構(gòu):表示隊(duì)列 typedef struct QListNode { struct QListNode* _next; QDataType _data; }QNode; ? // 隊(duì)列的結(jié)構(gòu) typedef struct Queue { QNode* _front; QNode* _rear; }Queue;
鏈?zhǔn)疥?duì)列的實(shí)現(xiàn)
1、初始化隊(duì)列
void QueueInit(Queue* q) { assert(q); q->_front = NULL; q->_rear = NULL; }
2、銷毀隊(duì)列
void QueueDestroy(Queue* q) { assert(q); QNode* cur = q->_front; while (cur != NULL) { QNode* next = cur->_next; free(cur); cur = next; } q->_front = q->_rear = NULL; }
3、隊(duì)列判空
bool QueueEmpty(Queue* q) { assert(q); //if (q->_front == NULL) //{ // return 1; //} //else //{ // return 0; //} return q->_front == NULL; }
4、入隊(duì)操作
void QueuePush(Queue* q, QDataType data) { assert(q); QNode* newnode = (QNode*)malloc(sizeof(QNode)); if (newnode == NULL) { exit(-1); } newnode->_data = data; newnode->_next = NULL; if (q->_front == NULL) { q->_front = q->_rear = newnode; } else { q->_rear->_next = newnode; q->_rear = newnode; } }
5、出隊(duì)操作
void QueuePop(Queue* q) { assert(q); assert(!QueueEmpty(q)); QNode* next = q->_front->_next; free(q->_front); q->_front = next; if (q->_front == NULL) { q->_rear = NULL; } }
6、取隊(duì)頭元素
QDataType QueueFront(Queue* q) { assert(q); assert(!QueueEmpty(q)); return q->_front->_data; }
7、取隊(duì)尾操作
QDataType QueueBack(Queue* q) { assert(q); assert(!QueueEmpty(q)); return q->_rear->_data; }
8、隊(duì)中有效元素個數(shù)
int QueueSize(Queue* q) { assert(q); int size = 0; QNode* cur = q->_front; while (cur) { size++; cur = cur->_next; } return size; }
循環(huán)隊(duì)列
循環(huán)隊(duì)列的定義
循環(huán)隊(duì)列就是將隊(duì)列存儲空間的最后一個位置繞到第一個位置,形成邏輯上的環(huán)狀空間,供隊(duì)列循環(huán)使用。在循環(huán)隊(duì)列結(jié)構(gòu)中,當(dāng)存儲空間的最后一個位置已被使用而再要進(jìn)入隊(duì)運(yùn)算時,只需要存儲空間的第一個位置空閑,便可將元素加入到第一個位置,即將存儲空間的第一個位置作為隊(duì)尾。循環(huán)隊(duì)列可以更簡單防止偽溢出的發(fā)生,但隊(duì)列大小是固定的。在循環(huán)隊(duì)列中,當(dāng)隊(duì)列為空時,有front=rear,而當(dāng)所有隊(duì)列空間全占滿時,也有front=rear。為了區(qū)別這兩種情況,規(guī)定循環(huán)隊(duì)列最多只能有MaxSize-1個隊(duì)列元素,當(dāng)循環(huán)隊(duì)列中只剩下一個空存儲單元時,隊(duì)列就已經(jīng)滿了。因此,隊(duì)列判空的條件是front=rear,而隊(duì)列判滿的條件是front=(rear+1)%MaxSize。
循環(huán)隊(duì)列的空間可以重復(fù)利用,解決了普通隊(duì)列的空間浪費(fèi)問題
循環(huán)隊(duì)列的實(shí)現(xiàn)
typedef struct { int *a; int front; int tail; int k; } MyCircularQueue; ? //提前聲明判空判滿 bool myCircularQueueIsEmpty(MyCircularQueue* obj); bool myCircularQueueIsFull(MyCircularQueue* obj); //創(chuàng)建循環(huán)隊(duì)列 MyCircularQueue* myCircularQueueCreate(int k) { MyCircularQueue* cq=(MyCircularQueue*)malloc(sizeof(MyCircularQueue)); cq->a=(int*)malloc(sizeof(int)*(k+1)); cq->front=cq->tail=0; cq->k=k; return cq; } //循環(huán)隊(duì)列入隊(duì) bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) { if(myCircularQueueIsFull(obj)){ return false; } obj->a[obj->tail]=value; obj->tail++; obj->tail%=(obj->k+1); ? return true; } //循環(huán)隊(duì)列出隊(duì) bool myCircularQueueDeQueue(MyCircularQueue* obj) { if(myCircularQueueIsEmpty(obj)){ return false; } obj->front++; obj->front%=(obj->k+1); return true; ? } //循環(huán)隊(duì)列取隊(duì)頭 int myCircularQueueFront(MyCircularQueue* obj) { if(myCircularQueueIsEmpty(obj)){ return -1; } return obj->a[obj->front]; } //循環(huán)隊(duì)列取隊(duì)尾 int myCircularQueueRear(MyCircularQueue* obj) { if(myCircularQueueIsEmpty(obj)){ return -1; } int i=(obj->tail+obj->k)%(obj->k+1); return obj->a[i]; } //循環(huán)隊(duì)列判空 bool myCircularQueueIsEmpty(MyCircularQueue* obj) { return obj->front==obj->tail; } //循環(huán)隊(duì)列判滿 bool myCircularQueueIsFull(MyCircularQueue* obj) { return (obj->tail+1)%(obj->k+1)==obj->front; } //銷毀循環(huán)隊(duì)列 void myCircularQueueFree(MyCircularQueue* obj) { free(obj->a); free(obj); }
到此這篇關(guān)于C語言詳解鏈?zhǔn)疥?duì)列與循環(huán)隊(duì)列的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)C語言 隊(duì)列內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
c++利用stl set_difference對車輛進(jìn)出區(qū)域進(jìn)行判定
這篇文章主要介紹了set_difference,用于求兩個集合的差集,結(jié)果集合中包含所有屬于第一個集合但不屬于第二個集合的元素,需要的朋友可以參考下2017-03-03C語言 數(shù)據(jù)結(jié)構(gòu)平衡二叉樹實(shí)例詳解
這篇文章主要介紹了C語言 數(shù)據(jù)結(jié)構(gòu)平衡二叉樹實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-06-06Qt利用QDrag實(shí)現(xiàn)拖拽拼圖功能詳解
QDrag類為MIME-based拖拽數(shù)據(jù)轉(zhuǎn)換提供支持。本文為大家主要介紹如何利用QDrag類實(shí)現(xiàn)拖拽拼圖功能。左邊是打散的圖,拖動到右邊進(jìn)行復(fù)現(xiàn),此外程序還支持手動拖入原圖片,感興趣的可以了解一下2022-07-07在C++中高效使用和處理Json格式數(shù)據(jù)的示例代碼
最近的項(xiàng)目在用c處理后臺的數(shù)據(jù)時,因?yàn)楹枚嗤獠拷涌诙荚谑褂肑son格式作為返回的數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù)描述,如何在c中高效使用和處理Json格式的數(shù)據(jù)就成為了必須要解決的問題,需要的朋友可以參考下2023-11-11