棧的概念和結(jié)構(gòu)
棧是一種常見(jiàn)的數(shù)據(jù)結(jié)構(gòu),它遵循后進(jìn)先出LIFO(Last In First Out)的原則。進(jìn)行數(shù)據(jù)插入和操作的一端稱為棧頂,另一端稱為棧底。
壓棧:棧的插入操作被稱為壓棧/進(jìn)棧/入棧,入數(shù)據(jù)在棧頂。
出棧:棧的刪除操作。出數(shù)據(jù)也在棧頂;
棧的實(shí)現(xiàn)
??梢杂?strong>數(shù)組或者是鏈表來(lái)實(shí)現(xiàn);這里將使用數(shù)組來(lái)實(shí)現(xiàn),因?yàn)閿?shù)組在插入刪除時(shí)消耗代價(jià)較??;對(duì)于鏈表,由于Top放在尾,刪除時(shí)還需要由頭指針循環(huán)遍歷找到尾結(jié)點(diǎn)前一個(gè);
棧的數(shù)據(jù)結(jié)構(gòu)
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top;
int capacity;
}ST;
a為存儲(chǔ)數(shù)據(jù)的數(shù)組,top表示棧頂,capacity表示當(dāng)前數(shù)組的存儲(chǔ)容量;
棧的初始化和銷毀
void STInit(ST* ps)
{
assert(ps);
ps->a = NULL;
ps->top = 0;
ps->capacity = 0;
}
void STDestory(ST* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->capacity = 0;
ps->top = 0;
}
assert(ps)驗(yàn)證的是傳過(guò)來(lái)的地址,地址為NULL那就無(wú)法進(jìn)行操作;
free完ps->a記得置空;
出棧和入棧
void STPush(ST* ps, STDataType x)
{
assert(ps);
//滿擴(kuò)容
if (ps->top == ps->capacity)
{
int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
STDataType* tmp = realloc(ps->a, sizeof(STDataType) * newcapacity);
if (tmp == NULL)
{
perror("Stack fail");
exit(-1);
}
ps->a =tmp;
ps->capacity = newcapacity;
}
ps->a[ps->top] = x;
ps->top++;
}
void STPop(ST* ps)
{
assert(ps);
assert(ps->top > 0);
ps->top--;
}
這里的Top是放在最后一位元素之后的;
當(dāng)出棧時(shí),不用管那個(gè)位置的內(nèi)容和空間是否被刪除,當(dāng)下次入棧到這個(gè)位置,內(nèi)容會(huì)被頂替;而如果用free掉這一塊空間,會(huì)造成只釋放部分空間的錯(cuò)誤;
獲取棧頂、大小,判空
STDataType STTop(ST* ps)
{
assert(ps);
assert(ps->top > 0);
return ps->a[ps->top - 1];
}
int STSize(ST* ps)
{
assert(ps);
return ps->top;
}
bool STEmpty(ST* ps)
{
assert(ps);
return ps->top==0;
}
對(duì)于數(shù)據(jù)結(jié)構(gòu)來(lái)說(shuō),即使是簡(jiǎn)單的操作也要用函數(shù)進(jìn)行封裝;這樣做的原因能夠找出一些錯(cuò)誤的操作,能夠方便別人的操作;
例如你在主函數(shù)創(chuàng)建的棧為空,然后給到別人使用,別人不知道棧為空,別人沒(méi)有用函數(shù)判斷棧的大小,出來(lái)的棧的大小無(wú)法辨別是對(duì)的還是錯(cuò)誤的;而創(chuàng)建函數(shù)就能夠避免一些極端問(wèn)題;
接下來(lái)我們簡(jiǎn)單的驗(yàn)證一下:
void Test1()
{
ST st;
STInit(&st);
STPush(&st, 1);
STPush(&st, 2);
STPush(&st, 3);
STPush(&st, 4);
while (!STEmpty(&st))
{
printf("%d ", STTop(&st));
STPop(&st);
}
printf("\n");
STDestory(&st);
}
int main()
{
Test1();
return 0;
}
隊(duì)列的概念和結(jié)構(gòu)
隊(duì)列只允許在一端進(jìn)行插入操作,在另一端刪除數(shù)據(jù)操作的特殊線性表,具有先進(jìn)先出FIFO(First In First Out) ;
入隊(duì)列:在隊(duì)尾進(jìn)行插入的操作
出隊(duì)列:在隊(duì)頭進(jìn)行刪除的操作
隊(duì)列的實(shí)現(xiàn)
隊(duì)列的實(shí)現(xiàn)可以用數(shù)組和鏈表來(lái)實(shí)現(xiàn);這里將使用鏈表來(lái)實(shí)現(xiàn);因?yàn)槿绻褂脭?shù)組的結(jié)構(gòu),在數(shù)組頭進(jìn)行刪除出數(shù)據(jù),效率比較低;
隊(duì)列的數(shù)據(jù)結(jié)構(gòu)
typedef int QDataType;
typedef struct QueneNode
{
struct QueneNode* next;
QDataType data;
}QNode;
typedef struct Quene
{
QNode* head;
QNode* tail;
int size;
}Quene;
這里先用一個(gè)結(jié)構(gòu)體將一個(gè)結(jié)點(diǎn)的類型進(jìn)行封裝;然后再用一個(gè)結(jié)構(gòu)體進(jìn)行隊(duì)列的封裝;因?yàn)檫@里我們將會(huì)使用隊(duì)頭和隊(duì)尾,如果使用這兩個(gè)進(jìn)行傳參,將會(huì)用到二級(jí)指針,比較麻煩,所以就使用一個(gè)結(jié)構(gòu)體進(jìn)行封裝,用結(jié)構(gòu)體進(jìn)行傳參,用到隊(duì)頭和隊(duì)尾只需調(diào)用結(jié)構(gòu)體的成員;
隊(duì)列的初始化和銷毀
void QueneInit(Quene* pq)
{
assert(pq);
pq->head = pq->tail = NULL;
pq->size = 0;
}
void QueneDestory(Quene* pq)
{
assert(pq);
QNode* cur = pq ->head;
while (cur)
{
QNode* next = cur->next;
free(cur);
cur = next;
}
pq->head = pq->tail = NULL;
pq->size = 0;
}
初始化將head和tail都置空;size統(tǒng)計(jì)多少個(gè)結(jié)點(diǎn);
銷毀用循環(huán)遍歷逐漸將結(jié)點(diǎn)釋放;最后將指針置空;
隊(duì)列的插入
void QuenePush(Quene* pq, QDataType x)
{
assert(pq);
//擴(kuò)容
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
perror("malloc fail");
exit(-1);
}
newnode->data = x;
newnode->next = NULL;
//第一個(gè)插入
if (pq->head == NULL)
{
pq->head = pq->tail = newnode;
}
else
{
pq->tail->next = newnode;
pq->tail = newnode;
}
pq->size++;
}
首先是每插入一次就擴(kuò)容一個(gè)結(jié)點(diǎn);接著是判斷是否為第一個(gè)結(jié)點(diǎn)的插入,如果是需要將head和tail都等于新節(jié)點(diǎn);最后將size加加;
隊(duì)列的刪除
void QuenePop(Quene* pq)
{
assert(pq);
//判斷是否沒(méi)有數(shù)據(jù)
assert(!QueneEmpty(pq));
QNode* next = pq->head->next;
//只有一個(gè)數(shù)據(jù)
if (pq->head->next == NULL)
{
free(pq->head);
pq->head = pq->tail = next;
}
else
{
free(pq->head);
pq->head = next;
}
pq->size--;
}
我們需要判斷有沒(méi)有結(jié)點(diǎn)可以刪除;然后記住頭結(jié)點(diǎn)的下一個(gè)結(jié)點(diǎn),刪除頭結(jié)點(diǎn)后將頭結(jié)點(diǎn)指針等于下一個(gè)結(jié)點(diǎn);如果只有一個(gè)結(jié)點(diǎn)可以刪除,那么還要將tail置空;
獲取隊(duì)頭和隊(duì)尾的數(shù)據(jù)
QDataType QueneFront(Quene* pq)
{
assert(pq);
assert(!QueneEmpty(pq));
return pq->head->data;
}
QDataType QueneBack(Quene* pq)
{
assert(pq);
assert(!QueneEmpty(pq));
return pq->tail->data;
}
獲取隊(duì)列長(zhǎng)度和判空
int QueneSize(Quene* pq)
{
assert(pq);
return pq->size;
}
bool QueneEmpty(Quene* pq)
{
assert(pq);
return pq->head == NULL;
}
最后做一下簡(jiǎn)單的驗(yàn)證
void Test1()
{
Quene q;
QueneInit(&q);
QuenePush(&q, 1);
QuenePush(&q, 2);
QuenePush(&q, 3);
QuenePop(&q);
while (QueneSize(&q)>0)
{
printf("%d ", QueneBack(&q));
QuenePop(&q);
}
QueneDestory(&q);
}
int main()
{
Test1();
return 0;
}
棧和隊(duì)列的一些題目
1.有效的括號(hào)
思路:這道題可以采用棧這種結(jié)構(gòu)來(lái)解決問(wèn)題,滿足后進(jìn)先出的原理;
我們可以這么做,分為左括號(hào)和右括號(hào);遇到左括號(hào)就放入棧中,一旦遇到右括號(hào),我們可以將棧頂取出,進(jìn)行判斷;這是我們的大體思路;
這道題我們還需要考慮一些極端情況:
第一種:字符串中只有右括號(hào)或者說(shuō)一開始就是右括號(hào),那么這種就相當(dāng)于棧為空;當(dāng)遇到右括號(hào)時(shí),需要先進(jìn)行判斷;
第二種:字符串只有左括號(hào),那么表明棧中的元素沒(méi)有進(jìn)行匹配出棧,棧不為空;
所以把特殊情況弄好后,就可以進(jìn)行操作了,我們可以把我們寫的棧結(jié)構(gòu)復(fù)制到程序中,然后創(chuàng)建一個(gè)棧來(lái)進(jìn)行操作;最后記得釋放空間,避免內(nèi)存泄漏;
代碼:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-700043.html
#define _CRT_SECURE_NO_WARNINGS 1
typedef char STDataType;
typedef struct Stack
{
STDataType* a;
int top;
int capacity;
}ST;
void STInit(ST* ps)
{
assert(ps);
ps->a = NULL;
ps->top = 0;
ps->capacity = 0;
}
void STDestory(ST* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->capacity = 0;
ps->top = 0;
}
void STPush(ST* ps, STDataType x)
{
assert(ps);
if (ps->top == ps->capacity)
{
int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
STDataType* tmp = realloc(ps->a, sizeof(STDataType) * newcapacity);
if (tmp == NULL)
{
perror("Stack fail");
exit(-1);
}
ps->a =tmp;
ps->capacity = newcapacity;
}
ps->a[ps->top] = x;
ps->top++;
}
void STPop(ST* ps)
{
assert(ps);
assert(ps->top > 0);
ps->top--;
}
STDataType STTop(ST* ps)
{
assert(ps);
assert(ps->top > 0);
return ps->a[ps->top - 1];
}
int STSize(ST* ps)
{
assert(ps);
return ps->top;
}
bool STEmpty(ST* ps)
{
assert(ps);
return ps->top==0;
}
bool isValid(char * s){
ST st;
//棧初始化
STInit(&st);
while(*s)
{
//左括號(hào)就入棧
if(*s=='('||*s=='['||*s=='{')
{
STPush(&st,*s);
}
//右括號(hào)就出棧,判斷
else
{
??眨砻鳑](méi)有左括號(hào)
if(STEmpty(&st))
{
STDestory(&st);
return false;
}
char val=STTop(&st);
STPop(&st);
//不符合
if((*s==')'&&val!='(')
||(*s==']'&&val!='[')
||(*s=='}'&&val!='{'))
{
return false;
}
}
s++;
}
if(!STEmpty(&st))
{
return false;
}
STDestory(&st);
return true;
}
2.用隊(duì)列實(shí)現(xiàn)棧
思路:我們可以在紙上模擬一下入棧和出棧的操作;
由于入棧的時(shí)候和隊(duì)列的性質(zhì)一樣,都在尾插入,所以不需要執(zhí)行什么操作;出棧時(shí),總需要進(jìn)行轉(zhuǎn)移,才能刪除最后一個(gè)元素;那么可以先判斷那個(gè)隊(duì)列空與不為空,然后將不為空的進(jìn)行轉(zhuǎn)移到空的隊(duì)列;那么就可以完成出棧;同時(shí),由于這樣的操作,入棧時(shí)如果有一個(gè)隊(duì)列不為空需要將元素插入不為空的后面,方便出棧的操作;
代碼:
#include<assert.h>
#include<stdbool.h>
typedef int QDataType;
typedef struct QueneNode
{
struct QueneNode* next;
QDataType data;
}QNode;
typedef struct Quene
{
QNode* head;
QNode* tail;
int size;
}Quene;
void QueneInit(Quene* pq)
{
assert(pq);
pq->head = pq->tail = NULL;
pq->size = 0;
}
void QueneDestory(Quene* pq)
{
assert(pq);
QNode* cur = pq ->head;
while (cur)
{
QNode* next = cur->next;
free(cur);
cur = next;
}
pq->head = pq->tail = NULL;
pq->size = 0;
}
void QuenePush(Quene* pq, QDataType x)
{
assert(pq);
//擴(kuò)容
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
perror("malloc fail");
exit(-1);
}
newnode->data = x;
newnode->next = NULL;
//第一個(gè)插入
if (pq->head == NULL)
{
pq->head = pq->tail = newnode;
}
else
{
pq->tail->next = newnode;
pq->tail = newnode;
}
pq->size++;
}
bool QueneEmpty(Quene* pq)
{
assert(pq);
return pq->head==NULL;
}
int QueneSize(Quene* pq)
{
assert(pq);
return pq->size;
}
void QuenePop(Quene* pq)
{
assert(pq);
//判斷是否沒(méi)有數(shù)據(jù)
assert(!QueneEmpty(pq));
//只有一個(gè)數(shù)據(jù)
if (pq->head->next == NULL)
{
free(pq->head);
pq->head = pq->tail = NULL;
}
else
{
QNode* next = pq->head->next;
free(pq->head);
pq->head = next;
}
pq->size--;
}
QDataType QueneFront(Quene* pq)
{
assert(pq);
assert(!QueneEmpty(pq));
return pq->head->data;
}
QDataType QueneBack(Quene* pq)
{
assert(pq);
assert(!QueneEmpty(pq));
return pq->tail->data;
}
typedef struct {
Quene q1;
Quene q2;
} MyStack;
//創(chuàng)建一個(gè)自己的棧
//用一個(gè)結(jié)構(gòu)體進(jìn)行包裝
MyStack* myStackCreate() {
MyStack* obj=malloc(sizeof(MyStack));
QueneInit(&obj->q1);
QueneInit(&obj->q2);
return obj;
}
//插入判斷哪個(gè)隊(duì)列不為空
void myStackPush(MyStack* obj, int x) {
if(!QueneEmpty(&obj->q2))
{
QuenePush(&obj->q2,x);
}
else
{
QuenePush(&obj->q1,x);
}
}
//將隊(duì)列分為空隊(duì)列和不空隊(duì)列
int myStackPop(MyStack* obj) {
Quene* empty=&obj->q1;
Quene* nonempty=&obj->q2;
if(!QueneEmpty(&obj->q1))
{
empty=&obj->q2;
nonempty=&obj->q1;
}
//數(shù)據(jù)轉(zhuǎn)移
while(QueneSize(nonempty)>1)
{
QuenePush(empty,QueneFront(nonempty));
QuenePop(nonempty);
}
//刪除數(shù)據(jù),并返回
int Top=QueneFront(nonempty);
QuenePop(nonempty);
return Top;
}
int myStackTop(MyStack* obj) {
if(!QueneEmpty(&obj->q2))
{
return QueneBack(&obj->q2);
}
else
{
return QueneBack(&obj->q1);
}
}
bool myStackEmpty(MyStack* obj) {
return QueneEmpty(&obj->q1)&&QueneEmpty(&obj->q2);
}
void myStackFree(MyStack* obj) {
QueneDestory(&obj->q1);
QueneDestory(&obj->q2);
free(obj);
}
/**
* Your MyStack struct will be instantiated and called as such:
* MyStack* obj = myStackCreate();
* myStackPush(obj, x);
* int param_2 = myStackPop(obj);
* int param_3 = myStackTop(obj);
* bool param_4 = myStackEmpty(obj);
* myStackFree(obj);
*/
3.用棧實(shí)現(xiàn)隊(duì)列
思路:一樣的我們先在紙上模擬
如果再繼續(xù)刪除,那么可以刪除到棧2為空,然后就將棧1的內(nèi)容全部轉(zhuǎn)移到棧2;如果棧2沒(méi)空,再插入棧1會(huì)發(fā)現(xiàn)沒(méi)有任何影響;
所以我們總結(jié)得出:將棧1表示為插入的棧,棧2表示為刪除的棧,如果要?jiǎng)h除棧2為空就將棧1的內(nèi)容轉(zhuǎn)移到棧2;
代碼:
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top;
int capacity;
}ST;
void STInit(ST* ps)
{
assert(ps);
ps->a = NULL;
ps->top = 0;
ps->capacity = 0;
}
void STDestory(ST* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->capacity = 0;
ps->top = 0;
}
void STPush(ST* ps, STDataType x)
{
assert(ps);
if (ps->top == ps->capacity)
{
int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
STDataType* tmp = realloc(ps->a, sizeof(STDataType) * newcapacity);
if (tmp == NULL)
{
perror("Stack fail");
exit(-1);
}
ps->a =tmp;
ps->capacity = newcapacity;
}
ps->a[ps->top] = x;
ps->top++;
}
void STPop(ST* ps)
{
assert(ps);
assert(ps->top > 0);
ps->top--;
}
STDataType STTop(ST* ps)
{
assert(ps);
assert(ps->top > 0);
return ps->a[ps->top - 1];
}
int STSize(ST* ps)
{
assert(ps);
return ps->top;
}
bool STEmpty(ST* ps)
{
assert(ps);
return ps->top==0;
}
//棧分為插入棧和輸出棧
typedef struct {
ST instack;
ST outstack;
} MyQueue;
MyQueue* myQueueCreate() {
MyQueue* obj=malloc(sizeof(MyQueue));
STInit(&obj->instack);
STInit(&obj->outstack);
return obj;
}
void myQueuePush(MyQueue* obj, int x) {
STPush(&obj->instack,x);
}
int myQueuePop(MyQueue* obj) {
//先判斷輸出棧是否為空
if(STEmpty(&obj->outstack))
{
while(STSize(&obj->instack))
{
STPush(&obj->outstack,STTop(&obj->instack));
STPop(&obj->instack);
}
}
int head=STTop(&obj->outstack);
STPop(&obj->outstack);
return head;
}
int myQueuePeek(MyQueue* obj) {
if(STEmpty(&obj->outstack))
{
while(STSize(&obj->instack))
{
STPush(&obj->outstack,STTop(&obj->instack));
STPop(&obj->instack);
}
}
return STTop(&obj->outstack);
}
bool myQueueEmpty(MyQueue* obj) {
return STEmpty(&obj->instack)&&STEmpty(&obj->outstack);
}
void myQueueFree(MyQueue* obj) {
STDestory(&obj->instack);
STDestory(&obj->outstack);
free(obj);
}
/**
* Your MyQueue struct will be instantiated and called as such:
* MyQueue* obj = myQueueCreate();
* myQueuePush(obj, x);
* int param_2 = myQueuePop(obj);
* int param_3 = myQueuePeek(obj);
* bool param_4 = myQueueEmpty(obj);
* myQueueFree(obj);
*/
4.設(shè)計(jì)循環(huán)隊(duì)列
我們先根據(jù)題意確定我們將選擇數(shù)組來(lái)存儲(chǔ)(固定長(zhǎng)度);然后考慮怎么讓這個(gè)數(shù)組能夠循環(huán)著走?我們可以設(shè)置兩個(gè)指針來(lái)判斷(由于是數(shù)組,可以利用下標(biāo)來(lái)進(jìn)行代表指針),分別為頭和尾;假設(shè)隊(duì)列長(zhǎng)度為k,一開始,頭和尾下標(biāo)都為0,表示這個(gè)隊(duì)列為空;
那么當(dāng)插入一個(gè)元素后尾向后走一步
刪除一個(gè)元素頭向后走一步,
當(dāng)數(shù)組填滿后,會(huì)發(fā)現(xiàn)頭尾又重疊在一起,與一開始隊(duì)列為空情況是一樣的,這樣就無(wú)法判斷空與滿了;
所以我們可以再增加一個(gè)多出來(lái)的空間
當(dāng)尾走到最后一個(gè)多出來(lái)的空間時(shí)就表示滿;
循環(huán)的尾走到最后時(shí)我們用取模來(lái)進(jìn)行返回到下標(biāo)為0的位置;這樣子就能完成我們循環(huán)的目的。
代碼:
typedef struct {
int* a;
int head;
int rear;
int k;
} MyCircularQueue;
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue* obj=malloc(sizeof(MyCircularQueue));
obj->a=malloc(sizeof(int)*(k+1));
obj->head=obj->rear=0;
obj->k=k;
return obj;
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
return obj->head==obj->rear;
}
bool myCircularQueueIsFull(MyCircularQueue* obj) {
//當(dāng)rear超過(guò)k+1時(shí),歸0
return (obj->rear+1)%(obj->k+1)==obj->head;
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
if(myCircularQueueIsFull(obj))
{
return false;
}
obj->a[obj->rear]=value;
obj->rear++;
//限制在0-k
obj->rear%=(obj->k+1);
return true;
}
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
{
return false;
}
obj->head++;
//限制在0-k
obj->head%=(obj->k+1);
return true;
}
int myCircularQueueFront(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
{
return -1;
}
return obj->a[obj->head];
}
int myCircularQueueRear(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
{
return -1;
}
//考慮rear-1等于-1的情況
return obj->a[(obj->rear+obj->k)%(obj->k+1)];
}
void myCircularQueueFree(MyCircularQueue* obj) {
free(obj->a);
free(obj);
}
/**
* Your MyCircularQueue struct will be instantiated and called as such:
* MyCircularQueue* obj = myCircularQueueCreate(k);
* bool param_1 = myCircularQueueEnQueue(obj, value);
* bool param_2 = myCircularQueueDeQueue(obj);
* int param_3 = myCircularQueueFront(obj);
* int param_4 = myCircularQueueRear(obj);
* bool param_5 = myCircularQueueIsEmpty(obj);
* bool param_6 = myCircularQueueIsFull(obj);
* myCircularQueueFree(obj);
*/
這里需要注意的就是取模的問(wèn)題,需要記住尾和頭是不斷增加的,是由于取模k+1才限制在0-k的下標(biāo)中;
第一個(gè)就是在刪除和插入數(shù)據(jù)的時(shí)候,當(dāng)頭尾超出范圍時(shí),需要進(jìn)行取模k+1的操作,返回到第一個(gè)元素;
第二個(gè)是判斷滿時(shí),尾+1相當(dāng)于返回到頭,當(dāng)尾剛好處于最后下標(biāo)時(shí),需要進(jìn)行取模;
最后一個(gè)是取尾的問(wèn)題,當(dāng)尾剛好處于第一個(gè)下標(biāo)時(shí),由于尾需要進(jìn)行-1的操作才能得到尾元素,所欲在第一個(gè)下標(biāo)-1會(huì)導(dǎo)致下標(biāo)變?yōu)?1,所以可以多加一輪K+1進(jìn)行取模的操作避免這個(gè)問(wèn)題;文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-700043.html
到了這里,關(guān)于數(shù)據(jù)結(jié)構(gòu)--棧和隊(duì)列的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!