棧和佇列面試題
採用順序棧實現棧基本操作; 採用鏈式佇列實現佇列基本操作;
#define MAXSIZE100; typedef int SDataType; typedef struct Stack { SDataType array[MAXSIZE]; int top; }Stack; typedef struct MinStack { Stack data; Stack min; }MinStack; void StackInit(Stack *s) { assert(s); s->top = 0; } void StackPush(Stack *s,SDataType data) { assert(s); if(MAXSIZE == s->top) { return; } s->array[s->top++] = data; } void StackPop(Stack *s) { assert(s); if(StackEmpty(&s)) { return; } ps->top--; } int StackEmpty(Stack *s) { assert(s); return 0==s->top; } int StackTop(Stack *s) { assert(s); return s->array[s->top]; } int StackSize(Stack *s) { assert(s); return s->top; }
一、實現一個棧,要求Push(入棧),Pop(出棧),Min(返回最小值)的時間複雜度為O(1),假設有min棧、data棧。 (1)入棧:將資料壓入data棧中,如果min棧為空或者該資料小於min棧棧頂元素,同時壓入min棧中。 (2)出棧:檢測data棧頂元素與min棧頂元素是否相同,若相同,min棧頂元素與data棧頂元素同時出棧,若不相同,只有data棧頂元素出棧。
void MinStackInit(MinStack *ms) { assert(ms); StackInit(*ms->min); StackInit(*ms->data); } void MinStackPush(MinStack *ms,SDataType data) { assert(ms); iStackPush(&ms->data,data); if(StackEmpty(&ms->min)||data<StackTop(&ms->min)) { StackPush(&ms->min,data); } } void MinStackPop(MinStack *ms) { assert(ms); if(StackEmpty(&ms->data)) return; if(StackTop(&ms->min)==StackTop(&ms->data)) { StackPop(&ms->min); } StackPop(&ms->data); } void MInStackEmpty(MinStack *ms) { return 0==StackEmpty(&ms->data); } SDataType MinStackTop(MinStack *ms) { return StackTop(&ms->data); } SDataType MinStackMin(MinStack *ms) { return StackTop(&ms->min); } int MinStackSize(MinStack *s) { return StackSize(&ms->data); }
二、使用兩個棧實現一個佇列。stack1棧頂:佇列隊尾 stack2棧頂:佇列隊頭 。 (1)入隊,直接對stack1壓棧。 (2)出隊:檢測stack2是否有資料。 step1:stack2有元素,直接彈出。 step2:stack2沒有元素,將stack1資料“倒入”stack2,轉到step1。 (3) 取隊頭元素:取stack2棧頂元素。 step1:stack2有元素,直接彈出。 step2:stack2沒有元素,將stack1資料“倒入”stack2,轉到step1。 (4) 取隊尾元素:取stack1棧頂元素。 step1:stack1有元素,直接彈出。 step2:stack1沒有元素,將stack2資料“倒入”stack1,轉到step1。
typedef struct QueueBy2Stack
{
Stack s1;
Stack s2;
}QueueBy2Stack;
void QueueBy2StackInit(QueueBy2Stack *q)
{
assert(q);
StackInit(&q->s1);
StackInit(&q->s2);
}
void QueueBy2StackPush(QueueBy2Stack *q,SDataType data)
{
assert(q);
StackPush(&q->s1);
}
void QueueBy2StackPop(QueueBy2Stack *q)
{
assert(q);
if(QueueBy2StackEmpty(q))
return;
if(StackEmpty(&q->s2))
{
while(!StackEmpty(&q->s1))
{
StackPush(&q->s2,StackTop(&q->s1));
StackPop(&q->s1);
}
}
StackPop(&q->s2);
}
int QueueBy2StackEmpty(QueueBy2Stack *q)
{
return StackEmpty(&q->s1)&&StackEmpty(&q->s2);
}
SDataType QueueBy2StackFront(QueueBy2Stack *q)
{
assert(q);
if(StackEmpty(&q->s2))
{
while(!StackEmpty(&q->s1)
{
StackPush(&q->s2,StackTop(&q->s1));
StackPop(&q->s1);
}
}
return StackTop(&q->s2);
}
SDataType QueueBy2StackBack(QueueBy2Stack *q)
{
assert(q);
if(StackEmpty(&q->s1))
{
while(!StackEmpty(&q->s2))
{
StackPush(&q->s1,StackTop(&q->s2));
StackPop(&p->s2);
}
}
return StackTop(&q->s1);
}
int QueueBy2StackSize(QueueBy2Stack *q)
{
assert(q);
return StackSize(&q->s1)+StackSize(&q->s2);
}
三、使用兩個佇列實現一個棧。 (1) 壓棧:檢測那個佇列有資料,將資料放到該佇列。 (2) 出棧:檢測那個佇列有資料,將除隊尾的的資料匯入另一個佇列中,最後刪除隊尾。 (3) 返回有資料的隊尾節點。(前提是資料在一個佇列中)
typedef int QDataType;
typedef struct QListNode
{
struct QListNode *next;
QDataType data;
}QListNode;
typedef struct Queue
{
QListNode* front;
QListNode* rear;
QDataType sz;
}Queue;
QListNode *BuyNewNode(QDataType data)
{
QListNode* newNode = (QListNode *)malloc(sizeof(QListNode));
if(NULL == newNode)
{
return NULL;
}
newNode->data = data;
newNode->next = NULL;
return newNode;
}
void QueueInit(Queue* q)
{
assert(q);
q->front = q->rear = BuyNewNode(0);
q->sz = 0;
}
void QueuePush(Queue* q,QDataType data)
{
assert(q);
q->rear->next = BuyNewNode(data);
q->rear = q->rear->next;
q->sz++;
}
void QueuePop(Queue* q)
{
assert(q);
if(q->front != q->rear)
{
QListNode* pDel = q->front->next;
q->front->next = pDel->next;
q->sz--;
free(pDel);
pDel = NULL:
}
}
QDataType QueueFront(Queue* q)
{
assert(q);
return q->front->next->data;
}
QDataType QueueBack(Queue* q)
{
assert(q);
return q->rear->data;
}
int QueueSize(Queue* q)
{
assert(q);
return q->sz;
}
int QueueEmpty(Queue* q)
{
assert(q);
return 0==QueueSize(q);
}
//////////////////////////////////
//以上為佇列的基本操作;
//以下為兩個佇列實現的棧的操作;
//////////////////////////////////
typedef struct StackBy2Queue
{
Queue q1;
Queue q2;
}StackBy2Queue;
void StackBy2QueueInit(StackBy2Queue* s)
{
assert(s);
QueueInit(s->q1);
QueueInit(s->q2);
}
void StackBy2QueuePush(StackBy2Queue* s,QDataType data)
{
assert(s);
if(QueueSize(&s->q1))
{
QueuePush(&s->q1,data);
}
else
{
QueuePush(&s->q2,data);
}
}
void StackBy2QueuePop(StackBy2Queue* s)
{
assert(s);
if(QueueSize(&s->q1))
{
while(QueueSize(&s->q1)>1)
{
QueuePush(&s->q2,QueueFront(&s->q1));
QueuePop(&s>q1);
}
QueuePop(&s->q1);
}
else
{
while(QueueSize(&s->q2)>1)
{
QueuePush(&s->q1,QueueFront(&s->q2));
QueuePop(&s>q2);
}
QueuePop(&s->q2);
}
}
QDataType StackBy2QueueTop(StackBy2Queue *s)
{
assert(s);
if(QueueSize(&s->q1)
{
return QueueBack(&s->q1);
}
else
{
return QueueBack(&s->q2);
}
}
四、判斷入棧出棧的合法性。 (1)按順序將入棧序列的元素壓入stack中。 (2)比較stack棧頂元素與出棧序列的元素,若相同,則進行(3),若不同則進行(1)。 (3)彈出stack棧頂元素,出棧序列向後移。 (4)此迴圈完成後,判斷stack棧是否為空,若為空,則順序正確,否則是錯誤的。
int InAndOutIsLegal(int *in,int *out,int insz,int outsz)
{
assert(in && out);
if(insz != outsz)
{
return 0;
}
stack s;
StackInit(&s);
int in_index = 0;
int out_index = 0;
for(;in_index < insz;in_index++)
{
StackPush(&s,in[in_index]);
while(StackSize(&s) && StackTop(&s) == out[out_index])
{
StackPop(&s);
out_index++;
}
}
if(StackSize(&s))
{
return 0;
}
else
{
return 1;
}
}
五、一個數組實現兩個棧,有三種實現方法。 (1)奇偶儲存法。 (2)中點向兩邊逼近。 (3)兩邊向中點逼近。 簡單比較:如果兩個棧的元素個數相差較大(2)(3)效果一樣,(1)的空間利用率較低。我就用第(3)種方法了。
typedef struct ShareStack
{
int array[MAXSIZE];
int top1;
int top2;
}ShareStack;
void ShareStackInit(ShareStack *s)
{
assert(s);
s->top1 = 0;
s->top = MAXSIZE-1;
}
void ShareStackPush(ShareStack *s,SDataType data,int which)
{
assert(s);
if(1 == which)
{
s->array[s->top1++] = data;
}
else
{
s->array[s->top2--] = data;
}
}
void ShareStackPop(ShareStack *s,int which)
{
assert(s);
if(1 == which)
{
if(s->top1>0)
s->top1--;
}
else
{
if(s->top2<MAXSIZE)
s->top2++;
}
}
SDataType ShareStackTop(ShareStack *s,int which)
{
assert(s);
if(1 == which)
{
return s->array[s->top1--];
}
else
{
return s->array[s->top2++];
}
}
int ShareStackSIze(ShareStack *s,int which)
{
assert(s);
if(1 == which)
{
return s->top1;
}
else
{
return MAXSIZE-s->top2-1;
}
}
int ShareStackEmpty(ShareStack *s,int which)
{
return 0 == ShareStackSIze(s,which);
}
可能有些知識點掌握不到位,還請各位讀者在評論區多給意見!!!