解析栈和队列面试题

一、实现一个栈,要求实现Push(入栈)、Pop(出栈)、Min(返回最小值)的时间复杂度为O(1)

思路:
1、首先定义两个栈(s,min),栈s存放数据,栈min存放当前所有数据的最小值
2、对于栈s正常入栈,出栈就可以
3、对于栈min,当栈min为空或者入栈的数据x小于等于栈min栈顶元素的值就将x入栈;当栈s栈顶元素的值等于栈min栈顶元素的值,栈min进行出栈操作
4、取栈min栈顶元素的值即为当前的最小值

// 入栈
void Push(Stack *s, Stack *min, DataType x)
{
        StackPush(s, x);
        if (StackEmpty(min) || x <= StackTop(min))
        {
            StackPush(min, x);
        }
}

// 出栈
void Pop(Stack *s, Stack *min)
{
    if (StackTop(s) == StackTop(min))
    {
        StackPop(min);
    }
    StackPop(s);
}

// 返回最小值
int GetMin(Stack *min)
{
    if (!StackEmpty(min))
    {
        return StackTop(min);
    }
}

二、判断元素出栈,入栈顺序的合法性。如入栈的序列(1,2,3,4,5),出栈的序列(3,4,2,1,5)

int Test_Legality(int *in, int *out, int size) // in为入栈序列数组指针,out为出栈序列数组指针,size为数组大小
{
    Stack s;
    StackInit(&s);
    int i = 0;
    int j = 0;
    for (i = 0; i < size; i++)
    {
        StackPush(&s, in[i]);
        while (!StackEmpty(&s) && StackTop(&s) == out[j])
        {
            StackPop(&s);
            j++;
        }
    }
    return StackEmpty(&s); // 当所有出栈序列元素都匹配完之后,此时栈为空,即合法;否则不合法
}

三、使用两个栈实现一个队列

// 入队
void TwoStack_Queue_Push(Stack *s1, DataType x) // 入数据只在s1中入
{
    StackPush(s1, x);  
}

// 出队
void TwoStack_Queue_Pop(Stack *s1, Stack *s2)  // 出数据只在s2中出
{
    if (StackEmpty(s2)) // 当s2为空时,先把s1中的数据倒到s2中去
    {
        while (!StackEmpty(s1))
        {
            StackPush(s2, StackTop(s1));
            StackPop(s1);
        }
    }
    StackPop(s2);
}

// 返回队头元素
DataType TwoStack_Queue_Front(Stack *s1, Stack *s2)
{
    if (StackEmpty(s2))
    {
        while (!StackEmpty(s1))
        {
            StackPush(s2, StackTop(s1));
            StackPop(s1);
        }
    }
    return StackTop(s2);
}

四、使用两个队列实现一个栈

思路:
1、第一次入数据时,两个队列(q1,q2)都为空,先将数据入到q2中去;之后入数据都往不为空的那个队列入,保证一个队列为空,一个队列不为空
2、出数据时,将不为空的那个队列中的前size-1个数据依次Push到为空的那个队列里,依次Pop后保留最后一个,再将其Pop掉

// 入栈
void TwoQueue_Stack_Push(Queue *q1, Queue *q2, DataType x)
{
    if (!QueueEmpty(q1)) // q1不为空,将x入到q1中去
    {
        QueuePush(q1, x);
    }
    else // q1为空,将x入到q2中去
    {
        QueuePush(q2, x);
    }
}

// 出栈
void TwoQueue_Stack_Pop(Queue *q1, Queue *q2)
{
    if (QueueEmpty(q1)) // 如果q1为空,将q2中的元素依次入到q1中(除了最后一个元素)
    {
        int size = QueueSize(q2);
        while (--size)
        {
            QueuePush(q1, QueueFront(q2));
            QueuePop(q2);
        }
        QueuePop(q2);
    }
    else // 如果q1不为空,将q1中的元素依次入到q2中(除了最后一个元素)
    {
        int size = QueueSize(q1);
        while (--size)
        {
            QueuePush(q2, QueueFront(q1));
            QueuePop(q1);
        }
        QueuePop(q1);
    }
}

// 获取栈顶元素
DataType TwoQueue_Stack_Top(Queue *q1, Queue *q2)
{
    if (!QueueEmpty(q1))
    {
        return QueueFront(q1);
    }
    else
    {
        return QueueFront(q2);
    }
}

五、一个数组实现两个栈(共享栈)

方法:奇偶栈、中间栈、头尾栈

以奇偶栈为例,具体实现如下:
Stack.h

#ifndef __Stack_h__
#define __Stack_h__

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <Windows.h>

#define Initsize 4 //初始存储空间
#define Increment 2 //每次增量

typedef int DataType;

typedef struct Stack
{
    DataType* _array;
    size_t _size1; // 栈1的有效数据个数
    size_t _size2; // 栈2的有效数据个数
    size_t _capacity; //总容量 
}Stack;

void StackInit(Stack* s);
void CheckCapacity(Stack* s);
void StackPush(Stack* s, DataType x, int which);
void StackPop(Stack* s, int which);
DataType StackTop(Stack* s, int which);
int StackEmpty(Stack* s, int which);
void StackPrint(Stack *s, int which);

#endif __Stack_h__

Stack.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "Stack.h"

//初始化
void StackInit(Stack* s)
{
    assert(s);
    s->_size1 = 0;
    s->_size2 = 0;
    s->_capacity = Initsize;
    s->_array = (DataType*)malloc(Initsize*sizeof(DataType));
    if (s->_array == NULL)
    {
        perror("StackInit");
        return;
    }
    memset(s->_array, 0, s->_capacity * sizeof(DataType));
}

//扩容
void CheckCapacity(Stack* s)
{
    assert(s);
    if (s->_size1 >= s->_capacity / 2 || s->_size2 >= s->_capacity / 2)
    {
        DataType* ptr = (DataType*)realloc(s->_array, (s->_capacity + Increment)*sizeof(DataType));
        if (ptr == NULL)
        {
            perror("CheckCapacity");
        }
        else
        {
            s->_array = ptr;
            s->_capacity += Increment;
        }
    }
}

//入栈
void StackPush(Stack* s, DataType x ,int which)
{
    assert(s);
    CheckCapacity(s);
    if (which == 1)
    {
        static int i = 0; // 栈1在偶数位
        s->_array[i] = x;
        s->_size1++;
        i = i + 2;
    }
    else if (which == 2)
    {
        static int j = 1; // 栈2在奇数位
        s->_array[j] = x;
        s->_size2++;
        j = j + 2;
    }
}

//出栈
void StackPop(Stack* s, int which)
{
    assert(s);
    if (which == 1)
    {
        if (s->_size1 == 0)
        {
            printf("栈1为空\n");
        }
        else
        {
            s->_size1--;
        }
    }
    else if (which == 2)
    {
        if (s->_size2 == 0)
        {
            printf("栈2为空\n");
        }
        else
        {
            s->_size2--;
        }
    }
}

//获取栈顶元素
DataType StackTop(Stack* s, int which)
{
    assert(s);
    if (which == 1)
    {
        if (s->_size1 == 0)
        {
            printf("栈1为空\n");
            return -1;
        }
        return s->_array[((s->_size1) - 1) * 2];
    }
    else if (which == 2)
    {
        if (s->_size2 == 0)
        {
            printf("栈2为空\n");
            return -1;
        }
        return s->_array[((s->_size2) - 1) * 2 + 1];
    }
}

//判空
int StackEmpty(Stack* s, int which)
{
    assert(s);
    if (which == 1)
    {
        if (s->_size1)
        {
            return 0;
        }
        else
        {
            return 1;
        }
    }
    else if (which == 2)
    {
        if (s->_size2)
        {
            return 0;
        }
        else
        {
            return 1;
        }
    }
}

//打印
void StackPrint(Stack *s, int which)
{
    assert(s);
    if (which == 1)
    {
        if (StackEmpty(s, 1))
        {
            printf("栈1为空\n");
        }
        else
        {
            int i = 0;
            while (s->_size1--)
            {
                printf("%d ", s->_array[i]);
                i = i + 2;
            }
            printf("\n");
        }
    }
    else if (which == 2)
    {
        if (StackEmpty(s, 2))
        {
            printf("栈2为空\n");
        }
        else
        {
            int j = 1;
            while (s->_size2--)
            {
                printf("%d ", s->_array[j]);
                j = j + 2;
            }
            printf("\n");
        }
    }
}

猜你喜欢

转载自blog.csdn.net/X_Perseverance/article/details/79937973
今日推荐