網(wǎng)站建設(shè)是屬于軟件開(kāi)發(fā)費(fèi)嗎百度推廣怎么收費(fèi)的
目錄
一.數(shù)據(jù)結(jié)構(gòu)--棧
1.棧的基本介紹
2.棧的實(shí)現(xiàn)
二.數(shù)據(jù)結(jié)構(gòu)--隊(duì)列
1.隊(duì)列的基本介紹
2.隊(duì)列的實(shí)現(xiàn)?
三.棧的運(yùn)用(Leetcode20. 有效的括號(hào)+225)?
1.問(wèn)題描述?
2.問(wèn)題分析
題解代碼:
四.用兩個(gè)隊(duì)列實(shí)現(xiàn)棧(225. 用隊(duì)列實(shí)現(xiàn)棧 - 力扣(Leetcode))
題解代碼:
五.用兩個(gè)棧實(shí)現(xiàn)隊(duì)列(232. 用棧實(shí)現(xiàn)隊(duì)列 - 力扣(Leetcode))
?題解代碼:
一.數(shù)據(jù)結(jié)構(gòu)--棧
1.棧的基本介紹
棧是一種數(shù)據(jù)先進(jìn)后出,后進(jìn)先出的數(shù)據(jù)結(jié)構(gòu):
- 棧一般用數(shù)組來(lái)實(shí)現(xiàn)(用單鏈表實(shí)現(xiàn)的棧缺陷明顯:數(shù)據(jù)的出棧操作時(shí)間復(fù)雜度為O(N),原因在于要找到表尾數(shù)據(jù)的前一個(gè)數(shù)據(jù)的地址)?
2.棧的實(shí)現(xiàn)
總體圖解:
棧的頭文件:
#pragma once #include <stdio.h> #include <assert.h> #include <stdbool.h> #include <stdlib.h>typedef int STDataType; typedef struct Stack {STDataType * arry; //棧的堆區(qū)空間指針int top; //維護(hù)棧頂下標(biāo),同時(shí)記錄棧中的元素個(gè)數(shù)int capacity; //記錄棧的容量 }ST;void StackInit(ST* Stack); //棧對(duì)象的初始化 STDataType StackTop(ST*Stack); //返回棧頂元素 void StackPush(ST* Stack,STDataType val); //元素入棧 void StackPop(ST* Stack); //元素出棧 int StackSize(ST* Stack); //返回棧對(duì)的元素個(gè)數(shù)的接口; bool StackEmpty(ST* Stack); //判斷棧是否為空的接口 void StackDestroy(ST* Stack); //銷毀棧
棧初始化接口:
void StackInit(ST* Stack) {assert(Stack);Stack->arry = NULL;Stack->capacity = 0;Stack->top = 0; }
返回棧頂元素的接口:
STDataType StackTop(ST* Stack) {assert(Stack);assert(Stack->top > 0);return Stack->arry[Stack->top - 1]; }
返回棧數(shù)據(jù)個(gè)數(shù)的接口:
int StackSize(ST* Stack) {assert(Stack);return Stack->top; }
判斷棧是否為空的接口:
bool StackEmpty(ST* Stack) {assert(Stack);return (Stack->top == 0); }
數(shù)據(jù)入棧操作接口:
void StackPush(ST* Stack, STDataType val) {assert(Stack);if (Stack->capacity == Stack->top) //檢查容量是否足夠{int newcapacity = (0 == Stack->capacity) ? 4 : 2 * Stack->capacity;//如果容量為零,則將容量設(shè)置為4,其他情況下按照兩倍擴(kuò)容方式增容STDataType* tem = (STDataType*)realloc(Stack->arry, newcapacity*sizeof(STDataType));if (NULL == tem)//判斷realloc是否成功{perror("realloc failed:");exit(-1);}Stack->capacity = newcapacity;Stack->arry = tem;}//元素入棧Stack->arry[Stack->top] = val;Stack->top++; }
數(shù)據(jù)出棧操作接口:
void StackPop(ST* Stack) {assert(Stack);assert(Stack->top > 0);Stack->top--; }
銷毀棧的接口:
void StackDestroy(ST* Stack) {assert(Stack);if (Stack->arry){free(Stack->arry);}Stack->arry = NULL;Stack->capacity = 0;Stack->top = 0; }
二.數(shù)據(jù)結(jié)構(gòu)--隊(duì)列
1.隊(duì)列的基本介紹
隊(duì)列是一種數(shù)據(jù)先進(jìn)先出,后進(jìn)后出的數(shù)據(jù)結(jié)構(gòu).
- 數(shù)據(jù)只能從隊(duì)尾入,從隊(duì)頭出?
- 隊(duì)列一般用單鏈表實(shí)現(xiàn),原因在于隊(duì)列涉及數(shù)據(jù)的頭刪操作,單鏈表的數(shù)據(jù)頭刪操作時(shí)間復(fù)雜度為O(1).
2.隊(duì)列的實(shí)現(xiàn)?
隊(duì)列總體圖解:
隊(duì)列的頭文件:?
#pragma once #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <assert.h>typedef int QDataType;typedef struct QueueNode //單鏈表結(jié)構(gòu)體 {struct QueueNode* next;QDataType data; }QNode;typedef struct Queue //維護(hù)隊(duì)列的結(jié)構(gòu)體 {QNode* head;QNode* tail; }Queue;void QueueInit(Queue* queue); //隊(duì)列的初始化接口 void QueueDestroy(Queue* queue); //銷毀隊(duì)列的接口 void QueuePush(Queue* queue,QDataType val); //數(shù)據(jù)入隊(duì)接口 void QueuePop(Queue* queue); //數(shù)據(jù)出隊(duì)接口 QDataType QueueFront(Queue* queue); //返回隊(duì)頭數(shù)據(jù)接口 QDataType QueueBawck(Queue* queue); //返回隊(duì)尾數(shù)據(jù)接口 int QueueSize(Queue* queue); //返回隊(duì)列數(shù)據(jù)個(gè)數(shù)的接口 bool QueueEmpty(Queue* queue); //判斷隊(duì)列是否為空的接口
隊(duì)列的初始化接口:
void QueueInit(Queue* queue) //隊(duì)列初始化 {assert(queue);queue->head = NULL;queue->tail = NULL; }
返回隊(duì)頭數(shù)據(jù)的接口:
QDataType QueueFront(Queue* queue) //返回隊(duì)列頭部數(shù)據(jù) {assert(queue);assert(queue->head);return queue->head->data; }
返回隊(duì)尾數(shù)據(jù)的接口:
QDataType QueueBawck(Queue* queue) //返回隊(duì)列尾部數(shù)據(jù) {assert(queue);assert(queue->tail);return queue->tail->data; }
返回隊(duì)列數(shù)據(jù)個(gè)數(shù)的接口:
int QueueSize(Queue* queue) //返回隊(duì)列節(jié)點(diǎn)個(gè)數(shù) {assert(queue);int count = 0;QNode* tem = queue->head;while(tem){count++;tem = tem->next;}return count; }
判斷隊(duì)列是否為空的接口:
bool QueueEmpty(Queue* queue) //判斷隊(duì)列是否為空 {assert(queue);return (NULL == queue->head); }
數(shù)據(jù)入隊(duì)接口:
??
void QueuePush(Queue* queue,QDataType val) //鏈表尾插數(shù)據(jù)(數(shù)據(jù)從隊(duì)列尾入隊(duì)) {assert(queue);QNode* NewNode = (QNode*)malloc(sizeof(QNode));//申請(qǐng)堆區(qū)鏈表節(jié)點(diǎn)if (NULL == NewNode){perror("malloc failed:");exit(-1);}NewNode->data = val;NewNode->next = NULL;if (NULL == queue->tail) //鏈表為空時(shí)的數(shù)據(jù)插入操作{assert(NULL == queue->head);queue->tail = NewNode;queue->head = NewNode;}else //鏈表非空時(shí)的數(shù)據(jù)插入操作{queue->tail->next = NewNode;queue->tail = NewNode;} }
數(shù)據(jù)出隊(duì)的接口:
void QueuePop(Queue* queue) //刪去鏈表頭節(jié)點(diǎn)(數(shù)據(jù)從隊(duì)列頭部出隊(duì)) {assert(queue);assert(queue->head && queue->tail);QNode* Next = queue->head->next;free(queue->head);queue->head = Next;if (NULL == queue->head) //若刪去的是鏈表的最后一個(gè)元素,則要將尾指針也置空{(diào)queue->tail = NULL;} }
銷毀隊(duì)列的接口:
void QueueDestroy(Queue* queue) //銷毀鏈表(隊(duì)列) {assert(queue);QNode* tem = queue->head;while (tem){QNode* Next = tem->next;free(tem);tem = Next;}queue->head = NULL;queue->head = NULL; }
三.棧的運(yùn)用(Leetcode20. 有效的括號(hào)+225)?
20. 有效的括號(hào) - 力扣(Leetcode)
1.問(wèn)題描述?
?
給定一個(gè)只包括?
'('?,? ?
')'?,? ??
'{'? ,? ? ??
'}'? ,?
??'['? ,?
??']'
?的字符串?s
?,判斷字符串是否有效。有效字符串需滿足:
- 左括號(hào)必須用相同類型的右括號(hào)閉合。
- 左括號(hào)必須以正確的順序閉合。
- 每個(gè)右括號(hào)都有一個(gè)對(duì)應(yīng)的相同類型的左括號(hào)。
示例:
輸入:s = "()[]{}" 輸出:true
C題解接口:
bool isValid(char * s) {}
2.問(wèn)題分析
從左向右遍歷字符串的情況下的括號(hào)匹配思路:
- 由于在遍歷字符串時(shí),我們無(wú)法確定當(dāng)前的左括號(hào)會(huì)和哪一個(gè)右括號(hào)匹配,因此匹配的思路應(yīng)該是先找到第一個(gè)右括號(hào),然后再向前尋找相應(yīng)的左括號(hào),若匹配失敗則返回false,若匹配成功則繼續(xù)尋找下一個(gè)右括號(hào)重復(fù)上述過(guò)程,直到結(jié)束
- ?暴力匹配算法動(dòng)畫解析:
- 根據(jù)上面的分析可知暴力匹配法的時(shí)間復(fù)雜度為O(N^2)?
然而本題如果使用輔助棧來(lái)求解,則可以達(dá)到用空間來(lái)?yè)Q取時(shí)間效率的目的。
基本思路如下:
- 用一個(gè)指針遍歷字符串,每當(dāng)遇到左括號(hào),我們就將其壓入棧中
- 每當(dāng)遇到右括號(hào),我們就將其與棧頂括號(hào)進(jìn)行匹配,若匹配失敗則說(shuō)明字符串不滿足條件,接口返回false,若匹配成功則彈出棧頂元素,并繼續(xù)遍歷字符串重復(fù)上述步驟直到找到'\0'則接口返回true
- 算法動(dòng)畫圖解:
?
我們可以將實(shí)現(xiàn)好的棧(本期第一節(jié)中)用于解題(順便還可以驗(yàn)證我們棧的實(shí)現(xiàn)有沒(méi)有bug)
題解代碼:
用于題解的棧:
typedef char STDataType; typedef struct Stack {STDataType * arry; //棧的堆區(qū)空間指針int top; //維護(hù)棧頂下標(biāo),同時(shí)記錄棧中的元素個(gè)數(shù)int capacity; //記錄棧的容量 }ST;void StackInit(ST* Stack) {assert(Stack);Stack->arry = NULL;Stack->capacity = 0;Stack->top = 0; }STDataType StackTop(ST* Stack) {assert(Stack);assert(Stack->top > 0);return Stack->arry[Stack->top - 1]; }void StackPush(ST* Stack, STDataType val) {assert(Stack);if (Stack->capacity == Stack->top) //檢查容量是否足夠{int newcapacity = (0 == Stack->capacity) ? 4 : 2 * Stack->capacity;STDataType* tem = (STDataType*)realloc(Stack->arry, newcapacity*sizeof(STDataType));if (NULL == tem){perror("realloc failed:");exit(-1);}Stack->capacity = newcapacity;Stack->arry = tem;}Stack->arry[Stack->top] = val;Stack->top++; }void StackPop(ST* Stack) {assert(Stack);assert(Stack->top > 0);Stack->top--; }int StackSize(ST* Stack) {assert(Stack);return Stack->top; }bool StackEmpty(ST* Stack) {assert(Stack);return (Stack->top == 0); }void StackDestroy(ST* Stack) {assert(Stack);if (Stack->arry){free(Stack->arry);}Stack->arry = NULL;Stack->capacity = 0;Stack->top = 0; }
兩個(gè)輔助判斷接口代碼:
//判斷指針指向的括號(hào)是否為右括號(hào)的接口bool CheckRightQutoe(const char quote) //左括號(hào)返回true,有括號(hào)返回false{if('{' == quote || '(' == quote || '[' == quote){return true;}else{return false;}}
//判斷兩個(gè)括號(hào)是否匹配的接口bool JudgeMatch(const char right,const char left){if(('}' == right && '{' == left) || (']' == right && '[' == left) || (')' == right && '(' == left) ){return true;}return false;}
題解接口代碼:
bool isValid(char * s) {ST ans;StackInit(&ans); //創(chuàng)建一個(gè)棧int lenth = strlen(s); //字符串有效字符個(gè)數(shù)為奇數(shù)直接返回falseif(lenth % 2 == 1) {return false;}char * tem = s; //tem用于遍歷字符串while('\0' != *tem){if(CheckRightQutoe(*tem)) //遇到右括號(hào)則入棧{StackPush(&ans,*tem);}else //遇到左括號(hào)則與棧頂右括號(hào)匹配{if(StackEmpty(&ans) || !JudgeMatch(*tem,StackTop(&ans))){return false; //匹配前注意判斷棧是否為空}StackPop(&ans); //匹配完后彈出棧頂括號(hào) }tem ++;}if(!StackEmpty(&ans)) //棧為空說(shuō)明全部括號(hào)都完成了匹配{return false;}return true; }
- 該方法充分利用了棧數(shù)據(jù)后進(jìn)先出的特點(diǎn)
- 算法的時(shí)間復(fù)雜度為O(N)
?
四.用兩個(gè)隊(duì)列實(shí)現(xiàn)棧(225. 用隊(duì)列實(shí)現(xiàn)棧 - 力扣(Leetcode))
本題并沒(méi)有什么實(shí)際意義,求解它的目的僅僅在于加深對(duì)棧和隊(duì)列這兩種數(shù)據(jù)結(jié)構(gòu)的理解
- 用兩個(gè)隊(duì)列實(shí)現(xiàn)數(shù)據(jù)的先進(jìn)后出
題解接口:
typedef struct {} MyStack;//創(chuàng)建MyStack結(jié)構(gòu)體 MyStack* myStackCreate() {}//向MyStack兩個(gè)隊(duì)列成員中的非空隊(duì)列中插入數(shù)據(jù) //(若兩個(gè)隊(duì)列都為空則向任意一個(gè)隊(duì)列插入數(shù)據(jù)都可以) void myStackPush(MyStack* obj, int x) {}//刪除棧頂元素(同時(shí)返回棧頂元素的值) int myStackPop(MyStack* obj) {}//棧頂?shù)臄?shù)據(jù)其實(shí)就是非空隊(duì)列尾的數(shù)據(jù) int myStackTop(MyStack* obj) {}//返回棧頂?shù)臄?shù)據(jù) bool myStackEmpty(MyStack* obj) {}//銷毀棧 void myStackFree(MyStack* obj) {}
我們可以給自己設(shè)置一個(gè)規(guī)定:用隊(duì)列實(shí)現(xiàn)的'棧'的接口中,我們只能使用隊(duì)列的標(biāo)準(zhǔn)操作接口來(lái)操作'棧'中的元素的進(jìn)出.
- 本題我們利用本期第二節(jié)實(shí)現(xiàn)好的隊(duì)列來(lái)實(shí)現(xiàn)棧
用兩個(gè)隊(duì)列實(shí)現(xiàn)棧的數(shù)據(jù)結(jié)構(gòu)總體圖解:
兩個(gè)隊(duì)列實(shí)現(xiàn)一個(gè)棧的結(jié)構(gòu)體的定義:
typedef struct {Queue queue1;Queue queue2; } MyStack;
數(shù)據(jù)入'棧'接口:
void myStackPush(MyStack* obj, int x)?
- 向MyStack兩個(gè)隊(duì)列成員中的非空隊(duì)列中插入數(shù)據(jù)
- (若兩個(gè)隊(duì)列都為空則向任意一個(gè)隊(duì)列插入數(shù)據(jù)都可以)
?
//向MyStack兩個(gè)隊(duì)列成員中的非空隊(duì)列中插入數(shù)據(jù) //(若兩個(gè)隊(duì)列都為空則向任意一個(gè)隊(duì)列插入數(shù)據(jù)都可以) void myStackPush(MyStack* obj, int x) {if(!QueueEmpty(&(obj->queue1))){QueuePush(&(obj->queue1),x);}else{QueuePush(&(obj->queue2),x);} }
數(shù)據(jù)出棧接口:
int myStackPop(MyStack* obj)
數(shù)據(jù)出棧過(guò)程動(dòng)畫圖解:?
//刪除棧頂元素(同時(shí)返回棧頂元素的值) int myStackPop(MyStack* obj) {int ret = 0;//將非空隊(duì)列里面的(除了隊(duì)尾的元素)移到另外一個(gè)空隊(duì)列中if(!QueueEmpty(&(obj->queue1)) && QueueEmpty(&(obj->queue2))){while(obj->queue1.head != obj->queue1.tail) //轉(zhuǎn)移數(shù)據(jù){QueuePush(&(obj->queue2),(obj->queue1).head->data);QueuePop(&(obj->queue1)); }ret = QueueFront(&(obj->queue1)); //記錄要彈出的數(shù)據(jù)QueuePop(&(obj->queue1)); //彈出數(shù)據(jù)}else{while(obj->queue2.head != obj->queue2.tail) //轉(zhuǎn)移數(shù)據(jù){QueuePush(&(obj->queue1),(obj->queue2).head->data);QueuePop(&(obj->queue2));}ret = QueueFront(&(obj->queue2)); //記錄要彈出的數(shù)據(jù)QueuePop(&(obj->queue2)); //彈出數(shù)據(jù)}return ret; //返回被彈出的數(shù)據(jù) }
- 通過(guò)兩個(gè)隊(duì)列的交互我們便完成了數(shù)據(jù)的先進(jìn)后出
題解代碼:
用于題解的隊(duì)列:
typedef int QDataType;typedef struct QueueNode //隊(duì)列鏈表節(jié)點(diǎn)結(jié)構(gòu)體 {struct QueueNode* next;QDataType data; }QNode;typedef struct Queue //維護(hù)隊(duì)列的結(jié)構(gòu)體 {QNode* head;QNode* tail; }Queue;void QueueInit(Queue* queue); //隊(duì)列初始化 void QueueDestroy(Queue* queue); //銷毀鏈表(隊(duì)列) void QueuePush(Queue* queue,QDataType val); //鏈表尾插數(shù)據(jù)(數(shù)據(jù)從隊(duì)列尾入隊(duì)) void QueuePop(Queue* queue); //刪去鏈表頭節(jié)點(diǎn)(數(shù)據(jù)從隊(duì)列頭部出隊(duì)) QDataType QueueFront(Queue* queue); //返回隊(duì)列頭部數(shù)據(jù) QDataType QueueBawck(Queue* queue); //返回隊(duì)列尾部數(shù)據(jù) int QueueSize(Queue* queue); //返回隊(duì)列節(jié)點(diǎn)個(gè)數(shù) bool QueueEmpty(Queue* queue); //判斷隊(duì)列是否為空void QueueInit(Queue* queue) //隊(duì)列初始化 {assert(queue);queue->head = NULL;queue->tail = NULL; } void QueueDestroy(Queue* queue) //銷毀鏈表(隊(duì)列) {assert(queue);QNode* tem = queue->head;while (tem) //逐個(gè)節(jié)點(diǎn)釋放鏈表{QNode* Next = tem->next;free(tem);tem = Next;}queue->head = NULL;queue->head = NULL; }void QueuePush(Queue* queue,QDataType val) //鏈表尾插數(shù)據(jù)(數(shù)據(jù)從隊(duì)列尾入隊(duì)) {assert(queue);QNode* NewNode = (QNode*)malloc(sizeof(QNode));if (NULL == NewNode) //在堆區(qū)申請(qǐng)節(jié)點(diǎn)空間{perror("malloc failed:");exit(-1);}NewNode->data = val;NewNode->next = NULL;if (NULL == queue->tail) //注意判斷隊(duì)列是否為空隊(duì)列并分類討論完成元素插入{assert(NULL == queue->head);queue->tail = NewNode; //隊(duì)列為空時(shí)tail和head指向同一個(gè)節(jié)點(diǎn)queue->head = NewNode;}else{queue->tail->next = NewNode; //隊(duì)列非空時(shí)令tail指向隊(duì)尾數(shù)據(jù)queue->tail = NewNode;} }void QueuePop(Queue* queue) //刪去鏈表頭節(jié)點(diǎn)(數(shù)據(jù)從隊(duì)列頭部出隊(duì)) {assert(queue);assert(queue->head && queue->tail);QNode* Next = queue->head->next;free(queue->head);queue->head = Next;if (NULL == queue->head) //注意判斷完成刪除元素后隊(duì)列是否變?yōu)榭贞?duì)列{queue->tail = NULL;} }QDataType QueueFront(Queue* queue) //返回隊(duì)列頭部數(shù)據(jù) {assert(queue);assert(queue->head);return queue->head->data; } QDataType QueueBawck(Queue* queue) //返回隊(duì)列尾部數(shù)據(jù) {assert(queue);assert(queue->tail);return queue->tail->data; }int QueueSize(Queue* queue) //返回隊(duì)列節(jié)點(diǎn)個(gè)數(shù) {assert(queue);int count = 0;QNode* tem = queue->head;while(tem) //計(jì)算節(jié)點(diǎn)個(gè)數(shù){count++;tem = tem->next;}return count; }bool QueueEmpty(Queue* queue) //判斷隊(duì)列是否為空 {assert(queue);return (NULL == queue->head); }
題解的棧:
typedef struct {Queue queue1;Queue queue2; } MyStack;//創(chuàng)建MyStack結(jié)構(gòu)體 MyStack* myStackCreate() {MyStack * tem = (MyStack *)malloc(sizeof(MyStack));if(NULL == tem){perror("malloc failed:");exit(-1);}QueueInit(&(tem->queue1));QueueInit(&(tem->queue2));return tem; }//向MyStack兩個(gè)隊(duì)列成員中的非空隊(duì)列中插入數(shù)據(jù) //(若兩個(gè)隊(duì)列都為空則向任意一個(gè)隊(duì)列插入數(shù)據(jù)都可以) void myStackPush(MyStack* obj, int x) {if(!QueueEmpty(&(obj->queue1))){QueuePush(&(obj->queue1),x);}else{QueuePush(&(obj->queue2),x);} }//刪除棧頂元素(同時(shí)返回棧頂元素的值) int myStackPop(MyStack* obj) {int ret = 0;//將非空隊(duì)列里面的(除了隊(duì)尾的元素)移到另外一個(gè)空隊(duì)列中if(!QueueEmpty(&(obj->queue1)) && QueueEmpty(&(obj->queue2))){while(obj->queue1.head != obj->queue1.tail) //轉(zhuǎn)移數(shù)據(jù){QueuePush(&(obj->queue2),(obj->queue1).head->data);QueuePop(&(obj->queue1)); }ret = QueueFront(&(obj->queue1)); //記錄要彈出的數(shù)據(jù)QueuePop(&(obj->queue1)); //彈出數(shù)據(jù)}else{while(obj->queue2.head != obj->queue2.tail) //轉(zhuǎn)移數(shù)據(jù){QueuePush(&(obj->queue1),(obj->queue2).head->data);QueuePop(&(obj->queue2));}ret = QueueFront(&(obj->queue2)); //記錄要彈出的數(shù)據(jù)QueuePop(&(obj->queue2)); //彈出數(shù)據(jù)}return ret; //返回被彈出的數(shù)據(jù) }//棧頂?shù)臄?shù)據(jù)其實(shí)就是非空隊(duì)列尾的數(shù)據(jù) int myStackTop(MyStack* obj) {if(!QueueEmpty(&(obj->queue1))){return obj->queue1.tail->data;}else{return obj->queue2.tail->data;} }//返回棧頂?shù)臄?shù)據(jù) bool myStackEmpty(MyStack* obj) {return QueueEmpty(&(obj->queue1)) && QueueEmpty(&(obj->queue2)); }//銷毀棧 void myStackFree(MyStack* obj) {QueueDestroy(&(obj->queue1));QueueDestroy(&(obj->queue2));free(obj);obj = NULL; }
五.用兩個(gè)棧實(shí)現(xiàn)隊(duì)列(232. 用棧實(shí)現(xiàn)隊(duì)列 - 力扣(Leetcode))
思路圖解:
?題解代碼:
typedef struct {ST PushStack;ST PopStack; } MyQueue;MyQueue* myQueueCreate() //隊(duì)列初始化接口 {MyQueue* tem = (MyQueue *)malloc(sizeof(MyQueue));if(NULL == tem){perror("malloc failed:");exit(-1);}StackInit(&(tem->PushStack));StackInit(&(tem->PopStack));return tem; }void myQueuePush(MyQueue* obj, int x) {StackPush(&(obj->PushStack),x);//數(shù)據(jù)入隊(duì) }int myQueuePop(MyQueue* obj) {assert(!StackEmpty(&(obj->PushStack)) || !StackEmpty(&(obj->PopStack)));//數(shù)據(jù)出隊(duì)前保證隊(duì)列不為空if(StackEmpty(&(obj->PopStack))) //PopStack為空則要將PushStack數(shù)據(jù)轉(zhuǎn)移進(jìn)來(lái){while(!StackEmpty(&(obj->PushStack))){StackPush(&(obj->PopStack),StackTop(&(obj->PushStack)));//將PushStack棧頂數(shù)據(jù)壓入PopStack棧中StackPop(&(obj->PushStack));//完成數(shù)據(jù)轉(zhuǎn)移后彈出PushStack的棧頂數(shù)據(jù)}}int ret = StackTop(&(obj->PopStack)); //記錄隊(duì)頭元素StackPop(&(obj->PopStack)); //元素出隊(duì)return ret; //返回隊(duì)頭元素 }int myQueuePeek(MyQueue* obj) {assert(!StackEmpty(&(obj->PushStack)) || !StackEmpty(&(obj->PopStack)));//保證隊(duì)列不為空if(StackEmpty(&(obj->PopStack))) //PopStack為空則要將PushStack數(shù)據(jù)轉(zhuǎn)移進(jìn)來(lái){while(!StackEmpty(&(obj->PushStack))){StackPush(&(obj->PopStack),StackTop(&(obj->PushStack)));//將PushStack棧頂數(shù)據(jù)壓入PopStack棧中StackPop(&(obj->PushStack));//完成數(shù)據(jù)轉(zhuǎn)移后彈出PushStack的棧頂數(shù)據(jù)}}return StackTop(&(obj->PopStack));//返回PopStack棧頂元素作為隊(duì)列隊(duì)頭元素 }bool myQueueEmpty(MyQueue* obj) {return StackEmpty(&(obj->PopStack)) && StackEmpty(&(obj->PushStack));//判斷隊(duì)列是否為空 }void myQueueFree(MyQueue* obj) {StackDestroy(&(obj->PopStack));StackDestroy(&(obj->PushStack));free(obj);obj = NULL; }
- 題解中我們運(yùn)用的是本期第一節(jié)中實(shí)現(xiàn)好的棧
?