日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【数据结构】— 『队列』的实现以及LeetCode队列练习题

發布時間:2023/12/8 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【数据结构】— 『队列』的实现以及LeetCode队列练习题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

??? ?各位大佬們好!很榮幸能夠得到您的訪問,讓我們一起在編程道路上任重道遠!?

??博客專欄:【數據結構初階】?

? 本篇內容簡介:數據結構初階中的隊列的實現以及LeetCode練習!

? 了解作者:勵志成為一名編程大牛的學子,目前是大二的編程小白。

?勵志術語:編程道路的乏味,讓我們一起學習變得有趣!


文章目錄

🌔 隊列的概念及結構

🌗 隊列的實現

🌒 隊列的鏈式結構

?🌒 隊列的初始化

?🌒 隊尾入數據

?🌒 隊頭出數據

🌒 獲取隊頭的數據

🌒 獲取隊尾的數據

🌒 獲取隊列有效元素個數

🌒 判斷隊列是否為空

🌒 隊列的銷毀

🌒 測試隊列接口功能

?🌔 隊列源代碼

🌗 Queue.c文件

🌗 Queue.h文件

🌗 test.c文件

🌔 225.用隊列實現棧

🌗 題解思路

?🌗 題解代碼

🌔 232.用棧實現隊列

?🌗 題解思路

🌗 題解代碼

🌗 結束語


🌔 隊列的概念及結構

隊列:只允許在一端進行插入數據操作,在另一端進行刪除數據操作的特殊線性表,隊列具有先進先出 FIFO(First in First out)。

入隊列:進行插入操作的一端稱為隊尾。

出隊列:進行刪除操作的一端稱為隊頭。

🌗 隊列的實現

隊列可以是數組或者鏈表的結構實現,但是使用鏈表的結構實現更優一點。因為如果使用數組的結構,出隊列在數組頭上的數據,效率會比較低。在這里我們使用鏈表來實現隊列。(數組不適合數組頭頻繁刪除或者數組中插入數據)。

🌒 隊列的鏈式結構

//隊列的鏈式結構 typedef int QDataType;typedef struct QListNode {struct QListNode* next;QDataType Data; }QNode;//隊列的結構 typedef struct Queue {QNode* front;QNode* back;int size;//記錄隊列節點的個數 }Queue;

?🌒 隊列的初始化

初始化隊列就是要使頭指針與尾指針都置為空,將size也置為空。

void QueueInit(Queue* pq) {//斷言隊列不能為空assert(pq);pq->front = pq->back = NULL;pq->size = 0; }

?🌒 隊尾入數據

首先我們要先創造新的要插入的節點,1.如果是第一個插入數據,將頭指針與尾指針都指向newnode;2.平常的尾插,先將newnode尾插到back指針后,再將back指針指向尾節點。

void QueuePush(Queue* pq, QDataType x) {assert(pq);//先創造節點,再進行鏈接QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail");exit(-1);}//初始化節點newnode->Data = x;newnode->next = NULL;//鏈接,考慮尾節點是空,還是非空if (pq->back == NULL){pq->front = pq->back = newnode;}else{pq->back->next = newnode;pq->back = newnode;}pq->size++;//隊列節點++ }

?🌒 隊頭出數據

隊頭出數據時,當隊頭為空時就不能再出數據了,需要進行判空處理。

1. 當隊列只剩余一個數據時,如果直接free,會造成back的野指針問題,所以我們需要單獨判斷這種情況。

2. 我們需要記錄要刪除的節點,再將front指向下一個,最后置空。

void QueuePop(Queue* pq) {assert(pq);//判斷只剩一個數據時if (pq->front == NULL){free(pq->front);pq->front = pq->back = NULL;}else{QNode* del = pq->front;pq->front = pq->front->next;free(del);del = NULL;}pq->size--;//出數據需要--size }

🌒 獲取隊頭的數據

//獲取隊頭的數據 QDataType QueueFront(Queue* pq) {assert(pq);assert(!QueueEmpty(pq));return pq->front->Data; }

🌒 獲取隊尾的數據

//獲取隊尾的數據 QDataType QueueBack(Queue* pq) {assert(pq);assert(!QueueEmpty(pq));return pq->back->Data;}

🌒 獲取隊列有效元素個數

因為我們在隊列的結構體中加上了size記錄元素個數,所以我們在這里可以直接返回。

//獲取隊列中有效元素的個數 int QueueSize(Queue* pq) {assert(pq);return pq->size; }

🌒 判斷隊列是否為空

如果隊列為空返回非0值,如果是非空返回0。

//隊列的判空 bool QueueEmpty(Queue* pq) {assert(pq);return pq->front == NULL && pq->back == NULL; }

🌒 隊列的銷毀

因為我們這里使用鏈表實現,所以我們要將鏈表的節點,一個一個釋放。

//隊列的銷毀 void QueueDestroy(Queue* pq) {assert(pq);QNode* cur = pq->front;while (cur != NULL){QNode* del = cur;cur = cur->next;free(del);}pq->front = pq->back = NULL; }

🌒 測試隊列接口功能

int main() {Queue q;QueueInit(&q);//隊尾插入數據QueuePush(&q, 1);QueuePush(&q, 2);QueuePush(&q, 3);QueuePush(&q, 4);QueuePush(&q, 5);while (!QueueEmpty(&q)){//獲取隊頭的數據printf("%d ", QueueFront(&q));QueuePop(&q);}printf("\n");QueueDestroy(&q);return 0; }


?🌔 隊列源代碼

🌗 Queue.c文件

#include"Queue.h"void QueueInit(Queue* pq) {//斷言隊列不能為空assert(pq);pq->front = pq->back = NULL;pq->size = 0; }void QueuePush(Queue* pq, QDataType x) {assert(pq);//先創造節點,再進行鏈接QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail");exit(-1);}//初始化節點newnode->Data = x;newnode->next = NULL;//鏈接,考慮尾節點是空,還是非空if (pq->back == NULL){pq->front = pq->back = newnode;}else{pq->back->next = newnode;pq->back = newnode;}pq->size++;//隊列節點++ }void QueuePop(Queue* pq) {assert(pq);assert(!QueueEmpty(pq));//判斷只剩一個數據時if (pq->front == NULL){free(pq->front);pq->front = pq->back = NULL;}else{QNode* del = pq->front;pq->front = pq->front->next;free(del);del = NULL;}pq->size--;//出數據需要--size }//獲取隊頭的數據 QDataType QueueFront(Queue* pq) {assert(pq);assert(!QueueEmpty(pq));return pq->front->Data; }//獲取隊尾的數據 QDataType QueueBack(Queue* pq) {assert(pq);assert(!QueueEmpty(pq));return pq->back->Data;}//獲取隊列中有效元素的個數 int QueueSize(Queue* pq) {assert(pq);return pq->size; }//隊列的判空 bool QueueEmpty(Queue* pq) {assert(pq);return pq->front == NULL && pq->back == NULL; }//隊列的銷毀 void QueueDestroy(Queue* pq) {assert(pq);QNode* cur = pq->front;while (cur != NULL){QNode* del = cur;cur = cur->next;free(del);}pq->front = pq->back = NULL; }

🌗 Queue.h文件

#define _CRT_SECURE_NO_WARNINGS 1 #pragma once#include<stdio.h> #include<assert.h> #include<stdlib.h> #include<stdbool.h>//隊列的鏈式結構 typedef int QDataType;typedef struct QListNode {struct QListNode* next;QDataType Data; }QNode;//隊列的結構 typedef struct Queue {QNode* front;QNode* back;int size;//記錄隊列節點的個數 }Queue;//初始化隊列 void QueueInit(Queue* pq);//隊尾入數據 void QueuePush(Queue* pq, QDataType x);//隊尾出數據 void QueuePop(Queue* pq);//獲取隊頭的數據 QDataType QueueFront(Queue* pq);//獲取隊尾的數據 QDataType QueueBack(Queue* pq);//獲取隊列中有效元素的個數 int QueueSize(Queue* pq);//隊列的判空 bool QueueEmpty(Queue* pq);//隊列的銷毀 void QueueDestroy(Queue* pq);

🌗 test.c文件

#include"Queue.h"int main() {Queue q;QueueInit(&q);//隊尾插入數據QueuePush(&q, 1);QueuePush(&q, 2);QueuePush(&q, 3);QueuePush(&q, 4);QueuePush(&q, 5);while (!QueueEmpty(&q)){//獲取隊頭的數據printf("%d ", QueueFront(&q));QueuePop(&q);}printf("\n");QueueDestroy(&q);return 0; }


🌔 225.用隊列實現棧

LeeCode題目鏈接:使用兩個棧實現隊列。OJ

題目描述:

🌗 題解思路

實現棧的結構:在此之前我們需要隊列的結構,不過還好我們在前面實現過一個隊列了,這里我們直接用。這里我們定義兩個隊列,一個q1,一個q2。

?

創造棧:這里我們不能像創造隊列一樣,

Queue q;

return &q;

因為局部變量出了作用域就銷毀,所以我們需要malloc一個棧,并且初始化,再返回。

?

入棧:哪個隊列不為空,就往哪個隊列入數據。

?

出棧:假設一個隊列為空,一個隊列不為空,將不為空隊列的數據導入為空隊列中,至原來不為空的隊列還剩一個數據。再記錄最后一個數據,并且返回。

?

獲取棧頂數據:哪個隊列不為空,就獲取哪個隊列中的隊尾的數據。

?

判斷棧是否為空:當兩個隊列都為空時,棧就為空。

?

棧的銷毀:因為在棧中,有兩個隊列,所以先銷毀兩個隊列,再釋放棧。

?

?🌗 題解代碼

// 兩個隊列 typedef struct {Queue q1;Queue q2; } MyStack;MyStack* myStackCreate() {// 需要malloc objMyStack* obj=(MyStack*)malloc(sizeof(MyStack));//初始化QueueInit(&obj->q1);QueueInit(&obj->q2);return obj; }void myStackPush(MyStack* obj, int x) {//兩個不為空就push哪個if(!QueueEmpty(&obj->q1)){//入數據QueuePush(&obj->q1,x);}else{QueuePush(&obj->q2,x);} }int myStackPop(MyStack* obj) { //要返回棧頂的數據//Pop不為空隊列 假設q1為空MyStack* empty=&obj->q1;MyStack* nonempty=&obj->q2;if(!QueueEmpty(&obj->q1)){empty=&obj->q2;nonempty=&obj->q1;}//倒數據 還剩下一個數據while(QueueSize(nonempty)>1){//不為空隊列的頭數據QueuePush(empty,QueueFront(nonempty));QueuePop(nonempty);}//返回棧頂元素int top=QueueFront(nonempty);QueuePop(nonempty);return top; }int myStackTop(MyStack* obj) {//獲取不為空的隊列的尾數據if(!QueueEmpty(&obj->q1)){return QueueBack(&obj->q1);}else{return QueueBack(&obj->q2);} }bool myStackEmpty(MyStack* obj) {//兩個隊列都為空return QueueEmpty(&obj->q1)&&QueueEmpty(&obj->q2); }void myStackFree(MyStack* obj) {//先銷毀隊列,再free棧QueueDestroy(&obj->q1);QueueDestroy(&obj->q2);free(obj); }

🌔 232.用棧實現隊列

LeetCode題目鏈接:用兩個棧實現隊列。OJ

題目描述:

?🌗 題解思路

隊列結構:還是一樣需要棧的所有接口實現,在這里我們定義兩個棧,

一個棧叫Push棧:專門用來隊列的插入數據。

另一個棧叫Pop棧:專門用來實現出隊列的操作。

?

創造隊列:還是一樣需要malloc一個隊列,并且初始化,最后返回。

?

入隊列:直接往Push棧里面插入數據。?

?

出隊列:判斷需不需要將數據從Push棧中全部導入Pop棧中,如果Pop棧中沒有數據,就說明需要倒數據。因為是棧的性質,所以隊頭的數據就是棧頂的數據,就是倒過去之后棧頂的數據。(需要Pop操作)

?

獲取隊頭的數據:也是一樣判斷是否需要倒數據,再記錄Pop棧頂的數據,返回。(不需要Pop操作)

?

隊列的判空:兩個棧都為空時,隊列就為空。?

?

隊列的銷毀:先銷毀兩個棧,再釋放隊列。

?

🌗 題解代碼

typedef struct {//一個棧用來Push,一個棧用來PopStack PushST;Stack PopST; } MyQueue;MyQueue* myQueueCreate() {MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));//進行初始化StackInit(&obj->PushST);StackInit(&obj->PopST);return obj; }void myQueuePush(MyQueue* obj, int x) {//直接往PushST的棧入數據StackPush(&obj->PushST,x); }void PushST_To_PopST(MyQueue* obj) {if(StackEmpty(&obj->PopST)){while(!StackEmpty(&obj->PushST)){//倒PushST棧頂的數據StackPush(&obj->PopST,StackTop(&obj->PushST));//刪除這個數據StackPop(&obj->PushST);}} }int myQueuePop(MyQueue* obj) {//考慮是否倒數據PushST_To_PopST(obj);//返回隊列開頭的數據int front=StackTop(&obj->PopST);StackPop(&obj->PopST);return front; }int myQueuePeek(MyQueue* obj) {//直接返回隊列頭的數據PushST_To_PopST(obj);int front=StackTop(&obj->PopST);return front; }bool myQueueEmpty(MyQueue* obj) {return StackEmpty(&obj->PushST) && StackEmpty(&obj->PopST); }void myQueueFree(MyQueue* obj) {StackDestroy(&obj->PushST);StackDestroy(&obj->PopST);free(obj); }

🌗 結束語

🎈?相隔千里,不能陪各位大佬在中秋節一起賞月,但是我們還能看到同一個月亮。中秋節祝各位大佬中秋快樂。

【寫在最后·想告訴你】

在互聯網這個行業里

任何時候都要學好技術

永遠都是?技術為王

總結

以上是生活随笔為你收集整理的【数据结构】— 『队列』的实现以及LeetCode队列练习题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。