兩個棧構成一個佇列演算法
阿新 • • 發佈:2019-01-08
在《劍指Offer》中看到了一個演算法:用兩個棧實現一個佇列。然後我就在思考這個要怎麼實現,佇列的特點是先進先出,而棧的特點是先進後出,與佇列恰好相反。
但是如果是兩個棧的話就可以實現,用一個棧進行入棧操作,另一個棧進行出棧操作。當要入佇列時,便進入S1;當要出佇列時,檢查S2是否為空,如果為空,則將S1棧中的所有資料出棧並依次存入S2中,然後從S2中出一個元素,如果S2不空,則直接從S2中Pop元素即可。
程式碼如下:
#include <stdio.h>
#define INITSTACK 5//棧空間大小
typedef struct SqStack
{
char data[INITSTACK];//順序棧
int top;//棧頂“指標”
int base;//棧底“指標”
int size;//棧的空間大小
}SqStack;//棧結構體
typedef struct SqQueue
{
SqStack S1;//構成佇列的第一個棧,用於插入資料
SqStack S2;//構成佇列的第二個棧,用於刪除資料
}SqQueue;//佇列結構
//初始化棧
void InitStack(SqStack *S)
{
S->top = 0;
S->base = 0;
S->size = INITSTACK;
}
//棧實際存放的元素個數
int RealSizeStack(SqStack S)
{
return S.top - S.base;
}
//判斷棧是否為空,棧為空,返回1;棧不空,返回0
int EmptyStack(SqStack S)
{
if(S.base == S.top)
{
return 1;
}
else
{
return 0;
}
}
//判斷棧是否滿,棧滿返回1;棧不滿,返回0
int FullStack(SqStack S)
{
if(S.top - S.base == S.size)
{
return 1;
}
else
{
return 0;
}
}
//入棧操作
int Push(SqStack *S,char ch)
{
if(S->top - S->base == S->size)
{
return 0;
}
S->data[S->top] = ch;
S->top++;
return 1;
}
//出棧操作
int Pop(SqStack *S,char *ch)
{
if(S->base == S->top)
{
return 0;
}
S->top--;
*ch = S->data[S->top];
return 1;
}
//初始化一個佇列
void InitQueue(SqQueue *Q)
{
InitStack(&Q->S1);
InitStack(&Q->S2);
}
//入佇列
void EnQueue(SqQueue *Q,char ch)
{
int signal = 0;//標誌元素是否成功入佇列
int s1_size = 0;//棧S1的實際元素個數
int s2_size = 0;//棧S2的實際元素個數
int q_size = 0;//佇列的實際元素個數
if(1 == FullStack(Q->S1))
{
signal = 0;
}
else
{
s1_size = RealSizeStack(Q->S1);
s2_size = RealSizeStack(Q->S2);
q_size = s1_size + s2_size;
if(INITSTACK > q_size)
{
Push(&Q->S1,ch);
signal = 1;
}
else
{
signal = 0;
}
}
if(1 == signal)
{
printf("elem '%c' enqueue!\n",ch);
}
else
{
printf("elem '%c' enqueue failed!\n",ch);
}
}
//出佇列
void DeQueue(SqQueue *Q,char *pch)
{
int signal = 0;//標誌是否成功出佇列
if(0 == EmptyStack(Q->S2))
{
Pop(&Q->S2,pch);
signal = 1;
}
else
{
if(0 == EmptyStack(Q->S1))
{
while(!EmptyStack(Q->S1))
{
Pop(&Q->S1,pch);
Push(&Q->S2,*pch);
}
Pop(&Q->S2,pch);
signal = 1;
}
}
if(1 == signal)
{
printf("elem '%c' dequeue!\n",*pch);
}
else
{
printf("DeQueue failed!\n");
}
}
int main()
{
char ch;
SqQueue Q;
InitQueue(&Q);
EnQueue(&Q,'a');
EnQueue(&Q,'b');
EnQueue(&Q,'c');
DeQueue(&Q,&ch);
EnQueue(&Q,'d');
EnQueue(&Q,'e');
EnQueue(&Q,'f');
EnQueue(&Q,'g');
EnQueue(&Q,'h');
EnQueue(&Q,'i');
DeQueue(&Q,&ch);
DeQueue(&Q,&ch);
DeQueue(&Q,&ch);
DeQueue(&Q,&ch);
DeQueue(&Q,&ch);
DeQueue(&Q,&ch);
return 0;
}
這個程式碼寫的不具有普適性,但是基本功能都實現了。後續有時間再進行程式碼的完善!加油!