????????????????????????Take your time ! ????????????????????????
??個人主頁:??????大魔王??????
??所屬專欄:??魔王的修煉之路–數(shù)據(jù)結(jié)構(gòu)??
如果你覺得這篇文章對你有幫助,請在文章結(jié)尾處留下你的點贊??和關(guān)注??,支持一下博主。同時記得收藏?這篇文章,方便以后重新閱讀。
前言
隊列介紹:只允許在一端進行插入數(shù)據(jù)操作,在另一端進行刪除數(shù)據(jù)操作的特殊線性表,隊列具有先進后出FIFQ(First In First Out)入隊列:進行插入操作的一端稱為隊尾。出隊列:進行刪除操作的一端稱為隊頭。
代碼實現(xiàn)
1、創(chuàng)建結(jié)構(gòu)體
對于隊列,需要創(chuàng)建兩個結(jié)構(gòu)體,第一個為結(jié)點的結(jié)構(gòu)體,第二個是記錄隊列頭、尾及元素個數(shù)的結(jié)構(gòu)體,因為隊列在入隊時相當于尾插,如果不記錄尾結(jié)點,需要一直遍歷,這樣效率低,所以在操作后直接記錄尾結(jié)點,記錄個數(shù)是因為方便其他函數(shù)操作,比如需要個數(shù)時,直接訪問這個成員就行了,不需要再遍歷一遍看看有幾個,對于隊列是否為空,也不需要判斷指針是否為空,直接判斷個數(shù)就行了。
代碼實現(xiàn):
#pragma once
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
typedef int QDataType;
typedef struct QueueNode
{
struct QueueNode* next;
QDataType data;
}QNode;
typedef struct Queue
{
QNode* head;
QNode* tail;
int size;//目的:要個數(shù)時,不需要遍歷一遍,直接就能知道有幾個。
}Queue;
2、初始化結(jié)構(gòu)體
剛開始時怎樣創(chuàng)建?是創(chuàng)建一個結(jié)構(gòu)體指針然后接收在函數(shù)里開辟一塊空間返回的結(jié)構(gòu)體指針還是直接創(chuàng)建一個結(jié)構(gòu)體,我們這里選擇直接創(chuàng)建一個結(jié)構(gòu)體,因為這個不像單鏈表一樣,如果單鏈表沒有元素,那么就是空,就沒有結(jié)點一說,這個直接就一定不是空,因為我們操作的不是結(jié)點的結(jié)構(gòu)體,而是記錄隊列的結(jié)構(gòu)體,所以它永遠不會是空,就不需要弄一個結(jié)構(gòu)體指針再接收之類的操作了。
void QInit(Queue* q)
{
assert(q);
q->head = q->tail = NULL;
q->size = NULL;
}
3、銷毀
用完就需要銷毀,防止內(nèi)存泄漏。
void QDestroy(Queue* q)
{
assert(q);
while (q->head)
{
Queue* next = q->head->next;
free(q->head);
q->head = next;
}
q->tail = NULL;//防止野指針
q->size = 0;
}
4、創(chuàng)建新結(jié)點
入隊列時需要創(chuàng)建新結(jié)點。
QNode* BuyNewnode(QDataType x)
{
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)//檢測是否開辟成功
{
perror("malloc error");
assert(newnode);
}
newnode->data = x;
newnode->next = NULL;
}
5、入隊列
就像最開始的那個圖一樣,入隊列相當于尾插。
//從后面進入,算是尾插。
void QPush(Queue* q, QDataType x)
{
assert(q);
QNode* newnode = BuyNewnode(x);
if (q->head == NULL)//如果本來沒有元素,需要讓首尾指針都賦上這個結(jié)點;如果有元素,就管尾指針就行。
{
assert(q->head == q->tail);
q->head = q->tail = newnode;
}
else
{
q->tail->next = newnode;
q->tail = newnode;
}
q->size++;
}
6、出隊列
相當于頭刪。
//從前面出,算是頭刪。
void QPop(Queue* q)
{
assert(q);
assert(q->head && q->tail);//出隊列時隊列不能為空,如果不為空,那么首尾指針肯定都不為空。
if (q->head->next == NULL)判斷是否只有一個結(jié)點,如果只有一個,尾指針也要指向空,不然就會變成野指針。
{
assert()q->head==q->tail);//如果只有一個結(jié)點,那么首尾結(jié)點肯定相等。
free(q->head);
q->head = q->tail = NULL;
}
else
{
QNode* newhead = q->head->next;
free(q->head);
q->head = newhead;
}
q->size--;
}
7、隊列成員個數(shù)
直接返回結(jié)構(gòu)體里的size就行。
int QSize(Queue* q)
{
assert(q);
//int size = 0;
//QNode* cur = q->head;
//while (cur)
//{
// cur = cur->next;
// size++;
//}
//return size;
return q->size;
}
8、隊列是否為空
直接判斷size就行。
bool QEmpty(Queue* q)
{
assert(q);
return q->size == 0;
}
9、隊列最前面的元素數(shù)據(jù)
需要判斷是否為空。如果為空就不能訪問,不然越界。
QDataType QFront(Queue* q)
{
assert(q);
assert(q->head);
return q->head->data;
}
10、隊列最后面的元素數(shù)據(jù)
需要判斷隊列是否為空,如果為空就不能訪問,不然越界。
QDataType QBack(Queue* q)
{
assert(q);
assert(q->tail);
return q->tail->data;
}
總代碼
Queue.h
Queue.h
#pragma once
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
typedef int QDataType;
typedef struct QueueNode
{
struct QueueNode* next;
QDataType data;
}QNode;
typedef struct Queue
{
QNode* head;
QNode* tail;
int size;//目的:要個數(shù)時,不需要遍歷一遍,直接就能知道有幾個。
}Queue;
void QInit(Queue* q);
void QDestroy(Queue* q);
void QPush(Queue* q,QDataType x);
void QPop(Queue* q);
int QSize(Queue* q);
bool QEmpty(Queue* q);
QDataType QFront(Queue* q);
QDataType QBack(Queue* q);
Queue.c
Queue.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "Queue.h"
void QInit(Queue* q)
{
assert(q);
q->head = q->tail = NULL;
q->size = NULL;
}
void QDestroy(Queue* q)
{
assert(q);
while (q->head)
{
Queue* next = q->head->next;
free(q->head);
q->head = next;
}
q->tail = NULL;//防止野指針
q->size = 0;
}
QNode* BuyNewnode(QDataType x)
{
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)//檢測是否開辟成功
{
perror("malloc error");
assert(newnode);
}
newnode->data = x;
newnode->next = NULL;
}
//從后面進入,算是尾插。
void QPush(Queue* q, QDataType x)
{
assert(q);
QNode* newnode = BuyNewnode(x);
if (q->head == NULL)//如果本來沒有元素,需要讓首尾指針都賦上這個結(jié)點;如果有元素,就管尾指針就行。
{
assert(q->head == q->tail);
q->head = q->tail = newnode;
}
else
{
q->tail->next = newnode;
q->tail = newnode;
}
q->size++;
}
//從前面出,算是頭刪。
void QPop(Queue* q)
{
assert(q);
assert(q->head && q->tail);//出隊列時隊列不能為空,如果不為空,那么首尾指針肯定都不為空。
if (q->head->next == NULL)//判斷是否只有一個結(jié)點,如果只有一個,尾指針也要指向空,不然就會變成野指針。
{
assert(q->head == q->tail);//如果只有一個結(jié)點,那么首尾結(jié)點肯定相等。
free(q->head);
q->head = q->tail = NULL;
}
else
{
QNode* newhead = q->head->next;
free(q->head);
q->head = newhead;
}
q->size--;
}
int QSize(Queue* q)
{
assert(q);
//int size = 0;
//QNode* cur = q->head;
//while (cur)
//{
// cur = cur->next;
// size++;
//}
//return size;
return q->size;
}
bool QEmpty(Queue* q)
{
assert(q);
return q->size == 0;
}
QDataType QFront(Queue* q)
{
assert(q);
assert(q->head);
return q->head->data;
}
QDataType QBack(Queue* q)
{
assert(q);
assert(q->tail);
return q->tail->data;
}
Test.c
//測試隊列
#define _CRT_SECURE_NO_WARNINGS 1
#include "Queue.h"
void print(Queue* q)
{
while (!QEmpty(q))
{
printf("%d ", QFront(q));
QPop(q);
}
}
int main()
{
Queue q;
QInit(&q);
QPush(&q, 0);
QPush(&q, 1);
QPush(&q, 2);
QPush(&q, 3);
QPush(&q, 4);
QPush(&q, 5);
QPop(&q);
QPop(&q);
print(&q);
QDestroy(&q);
return 0;
}
總結(jié)
結(jié)尾
- 博主長期更新,博主的目標是不斷提升閱讀體驗和內(nèi)容質(zhì)量,如果你喜歡博主的文章,請點個贊或者關(guān)注博主支持一波,我會更加努力的為你呈現(xiàn)精彩的內(nèi)容。
??專欄推薦
??魔王的修煉之路–C語言
??魔王的修煉之路–數(shù)據(jù)結(jié)構(gòu)初階
??魔王的修煉之路–C++
??魔王的修煉之路–Linux
更新不易,希望得到友友的三連支持一波。收藏這篇文章,意味著你將永久擁有它,無論何時何地,都可以立即找到重新閱讀;關(guān)注博主,意味著無論何時何地,博主將永久和你一起學習進步,為你帶來有價值的內(nèi)容。文章來源:http://www.zghlxwxcb.cn/news/detail-451017.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-451017.html
到了這里,關(guān)于C語言實現(xiàn)隊列--數(shù)據(jù)結(jié)構(gòu)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!