【劍指offer】兩個佇列實現一個棧
轉載請註明出處:http://blog.csdn.net/ns_code/article/details/25076689
題目:用兩個佇列模擬一個棧,即用兩個佇列的出隊和入隊操作,來實現棧的出棧和入棧操作。
思路:稍微畫下草圖,便不難想出該題的解決方法,思路如下:
假設有兩個佇列Q1和Q2,當二者都為空時,入棧操作可以用入隊操作來模擬,可以隨便選一個空佇列,假設選Q1進行入棧操作,現在假設a,b,c依次入棧了(即依次進入佇列Q1),這時如果想模擬出棧操作,則需要將c出棧,因為在棧頂,這時候可以考慮用空佇列Q2,將a,b依次從Q1中出隊,而後進入佇列Q2,將Q1的最後一個元素c出隊即可,此時Q1變為了空佇列,Q2中有兩個元素,隊頭元素為a,隊尾元素為b,接下來如果再執行入棧操作,則需要將元素進入到Q1和Q2中的非空佇列,即進入Q2佇列,出棧的話,就跟前面的一樣,將Q2除最後一個元素外全部出隊,並依次進入佇列Q1,再將Q2的最後一個元素出隊即可。
實現程式碼如下:
/*
用兩個佇列模擬入棧操作
*/
void push(PQUEUE pS1,PQUEUE pS2,int val)
{
if(is_empty(pS2))
en_queue(pS1, val);
else
en_queue(pS2, val);
}
/*
用兩個佇列模擬出棧操作
*/
bool pop(PQUEUE pS1,PQUEUE pS2,int *pData)
{
if(is_empty(pS1) && is_empty(pS2))
return false;
int DelData;
if(!is_empty(pS2))
{
int len = length(pS2);
while(len-- > 1)
{
de_queue(pS2,&DelData);
en_queue(pS1,DelData);
}
//將佇列的最後一個元素出隊,作為出棧元素
de_queue(pS2,pData);
return true;
}
if(!is_empty(pS1))
{
int len = length(pS1);
while(len-- > 1)
{
de_queue(pS1,&DelData);
en_queue(pS2,DelData);
}
//將佇列的最後一個元素出隊,作為出棧元素
de_queue(pS1,pData);
return true;
}
}
完整的程式碼(用的以前寫的鏈式佇列)如下:
/*******************************************************************
題目:用兩個佇列模擬一個棧
*******************************************************************/
#include<stdio.h>
#include<stdlib.h>
typedef struct Node
{
int data;
struct Node *pNext;
}NODE,*PNODE;
typedef struct Queue
{
PNODE front; //隊頭指標
PNODE rear; //隊尾指標
}QUEUE,*PQUEUE;
PQUEUE create_queue();
bool is_empty(PQUEUE);
void en_queue(PQUEUE, int);
bool de_queue(PQUEUE,int *);
void destroy_queue(PQUEUE);
void traverse_queue(PQUEUE);
int length(PQUEUE);
void push(PQUEUE,PQUEUE,int);
bool pop(PQUEUE,PQUEUE,int *);
int main()
{
int pData; //用來儲存出隊的元素值
//建立佇列並進行入隊測試
PQUEUE pS1 = create_queue();
PQUEUE pS2 = create_queue();
push(pS1,pS2,4);
push(pS1,pS2,5);
printf("the length of pS1: %d\n",length(pS1));
printf("the length of pS2: %d\n",length(pS2));
if(pop(pS1,pS2,&pData))
printf("%d is pop out\n",pData);
else
printf("Stack is empty,can not pop\n");
printf("the length of pS1: %d\n",length(pS1));
printf("the length of pS2: %d\n",length(pS2));
push(pS1,pS2,6);
printf("the length of pS1: %d\n",length(pS1));
printf("the length of pS2: %d\n",length(pS2));
push(pS1,pS2,7);
printf("the length of pS1: %d\n",length(pS1));
printf("the length of pS2: %d\n",length(pS2));
if(pop(pS1,pS2,&pData))
printf("%d is pop out\n",pData);
else
printf("Stack is empty,can not pop\n");
printf("the length of pS1: %d\n",length(pS1));
printf("the length of pS2: %d\n",length(pS2));
if(pop(pS1,pS2,&pData))
printf("%d is pop out\n",pData);
else
printf("Stack is empty,can not pop\n");
printf("the length of pS1: %d\n",length(pS1));
printf("the length of pS2: %d\n",length(pS2));
if(pop(pS1,pS2,&pData))
printf("%d is pop out\n",pData);
else
printf("Stack is empty,can not pop\n");
printf("the length of pS1: %d\n",length(pS1));
printf("the length of pS2: %d\n",length(pS2));
if(pop(pS1,pS2,&pData))
printf("%d is pop out\n",pData);
else
printf("Stack is empty,can not pop\n");
return 0;
}
/*
建立一個空佇列,隊頭指標和隊尾指標都指向頭結點,
頭結點中不存放資料,只存放指標
*/
PQUEUE create_queue()
{
PQUEUE pS = (PQUEUE)malloc(sizeof(Queue));
pS->front = (PNODE)malloc(sizeof(NODE));
if(!pS || !pS->front)
{
printf("pS or front malloc failed!!");
exit(-1);
}
else
{
pS->rear = pS->front;
pS->front->pNext = NULL;
}
return pS;
}
/*
判斷佇列是否為空
*/
bool is_empty(PQUEUE pS)
{
if(pS->front == pS->rear)
return true;
else
return false;
}
/*
進隊函式,從隊尾進隊,隊頭指標保持不變
*/
void en_queue(PQUEUE pS, int e)
{
PNODE pNew = (PNODE)malloc(sizeof(NODE));
if(!pNew)
{
printf("pNew malloc failed");
exit(-1);
}
else
{
pNew->data = e;
pNew->pNext = NULL;
pS->rear->pNext = pNew;
pS->rear = pNew;
}
return;
}
/*
出隊函式,從隊頭出隊,隊尾指標保持不變,但當最後一個元素出隊時,
需要對隊尾指標重新賦值,使其指向頭結點
*/
bool de_queue(PQUEUE pS,int *pData)
{
if(is_empty(pS))
return false;
else
{
PNODE p = pS->front->pNext;
*pData = p->data;
pS->front->pNext = p->pNext;
//這裡是佇列頭元素出隊的特殊情況,一般情況下,刪除隊頭元素時
//僅需修改頭結點中的指標,但當佇列中最後一個元素被刪除時,
//佇列尾指標也丟失了,因此需對隊尾指標重新賦值(指向頭結點)。
if(pS->rear == p)
pS->rear = pS->front;
free(p);
}
return true;
}
/*
遍歷佇列,從對頭向隊尾依次輸出隊中的元素
*/
void traverse_queue(PQUEUE pS)
{
if(is_empty(pS))
printf("there is no data in the queue!\n");
else
{
PNODE pCurrent = pS->front->pNext;
printf("Now datas int the queue are:\n");
while(pCurrent)
{
printf("%d ",pCurrent->data);
pCurrent = pCurrent->pNext;
}
printf("\n");
}
return;
}
/*
求佇列的長度
*/
int length(PQUEUE pS)
{
int count = 0;
PNODE pCurrent = pS->front->pNext;
while(pCurrent)
{
count++;
pCurrent = pCurrent->pNext;
}
return count;
}
/*
銷燬佇列,頭結點也被銷燬,最後也將pS節點銷燬,並將其指向為空,避免垂直指標的產生
*/
void destroy_queue(PQUEUE pS)
{
if(is_empty(pS))
return;
else
{
while(pS->front)
{
pS->rear = pS->front->pNext;
free(pS->front);
pS->front = pS->rear;
}
}
free(pS);
pS = 0;
return;
}
/*
用兩個佇列模擬入棧操作
*/
void push(PQUEUE pS1,PQUEUE pS2,int val)
{
if(is_empty(pS2))
en_queue(pS1, val);
else
en_queue(pS2, val);
}
/*
用兩個佇列模擬出棧操作
*/
bool pop(PQUEUE pS1,PQUEUE pS2,int *pData)
{
if(is_empty(pS1) && is_empty(pS2))
return false;
int DelData;
if(!is_empty(pS2))
{
int len = length(pS2);
while(len-- > 1)
{
de_queue(pS2,&DelData);
en_queue(pS1,DelData);
}
//將佇列的最後一個元素出隊,作為出棧元素
de_queue(pS2,pData);
return true;
}
if(!is_empty(pS1))
{
int len = length(pS1);
while(len-- > 1)
{
de_queue(pS1,&DelData);
en_queue(pS2,DelData);
}
//將佇列的最後一個元素出隊,作為出棧元素
de_queue(pS1,pData);
return true;
}
}
測試結果:
相關文章
- 【劍指offer】兩個棧實現一個佇列佇列
- 劍指offer | 09. 用兩個棧實現佇列佇列
- 劍指offer-用兩個棧實現佇列-php佇列PHP
- 《劍指 Offer》棧實現佇列佇列
- 劍指offer(java實現)第5題“用兩個棧實現佇列”-牛客網Java佇列
- offer通過--7兩個棧實現佇列-2佇列
- offer通過--8兩個棧實現佇列-2佇列
- 兩個棧實現佇列佇列
- 兩個棧實現佇列操作佇列
- 用兩個棧實現佇列佇列
- leetcode155. 最小棧 1441. 用棧操作構建陣列 劍指 Offer 09. 用兩個棧實現佇列LeetCode陣列佇列
- 面試題之【用兩個棧實現佇列】面試題佇列
- 題目9:用兩個棧實現佇列佇列
- 《劍指offer》:[41]陣列中和為S的兩個數陣列
- [每日一題] 第七題:用兩個棧實現佇列每日一題佇列
- 【ZJOF】用來個棧來實現一個佇列佇列
- 用2個棧實現佇列佇列
- 劍指 Offer 25. 合併兩個排序的連結串列 JavaScript實現排序JavaScript
- 資料結構 使用2個棧實現一個佇列資料結構佇列
- 劍指offer——兩個連結串列的第一個公共結點C++C++
- 【劍指offer】第一個只出現一次的字元字元
- 劍指 Offer 59 - II. 佇列的最大值佇列
- 怎樣用一個佇列和一個棧實現求一個表示式的值?佇列
- 【劍指offer】刪除在另一個字串中出現的字元字串字元
- 通過佇列實現棧OR通過棧實現佇列佇列
- 劍指offer解析-下(Java實現)Java
- 劍指offer解析-上(Java實現)Java
- 演算法學習記錄五(C++)--->兩個棧實現佇列演算法C++佇列
- [CareerCup] 3.5 Implement Queue using Two Stacks 使用兩個棧來實現佇列佇列
- 劍指Offer-把陣列中的數排成一個最小的數陣列
- 劍指offer面試17 合併兩個排序的連結串列面試排序
- 劍指 offer(1) -- 陣列篇陣列
- 劍指offer——包含min函式的棧函式
- 【劍指offer】包含min函式的棧函式
- 9. 題目:對佇列實現棧&用棧實現佇列佇列
- 用佇列實現棧佇列
- 用棧實現佇列佇列
- [劍指Offer]面試題35:第一個只出現一次的字元面試題字元