数据结构之栈与队列相关面试题

实现一个栈,要求返回最小值

有3种方法,分别为:

  • 用一个栈实现,偶数下标存普通数据,奇数下标为最小的值
typedef struct MinStack
{
    int array[100];//偶数下标存普通数据,奇数下标为最小的值
    int top;
}MinStack;

void Init(MinStack *pS)
{
    pS->top = 0;
}
//入栈
void Push(MinStack *pS, int data)
{
    assert(pS != NULL);
    assert(pS->top < 100);
    int min = data;
    if (pS->top != 0 && pS->array[pS->top - 1] < data)
    {
        min = pS->array[pS->top - 1];
    }
    pS->array[pS->top++] = data;
    pS->array[pS->top++] = min;
}
//出栈
void Pop(MinStack *pS)
{
    assert(pS);
    pS->top -= 2;
}
//最小元素
int  Min(MinStack *pS)
{
    return pS->array[pS->top - 1];
}
//栈顶元素(普通数据)
int Top(MinStack *pS)
{
    return pS->array[pS->top - 2];
}
  • 用两个栈实现 ,其中一个栈存普通数据,另一个栈存最小数
typedef struct MinStack
{ 
    int array1[100];//存放普通数据
    int top1;
    int array2[100];//存放最小数据
    int top2;
}MinStack;
void Init(MinStack *pS)
{
    pS->top1 = pS->top2 = 0;
}
void Push(MinStack *pS, int data)
{

    int min = data;
    if (pS->top2 != 0 && pS->array2[pS->top2 - 1] < data)
    {
        min = pS->array2[pS->top2 - 1];
    }
    pS->array1[pS->top1++] = data;
    pS->array2[pS->top2++] = min;
}
void Pop(MinStack *pS)
{
    pS->top1--;
    pS->top2--;
}
int Min(MinStack *pS)
{
    return pS->array2[pS->top2 - 1];
}
int Top(MinStack *pS)
{
    return pS->array1[pS->top1 - 1];
}
  • 用两个数组实现,原理与两个栈基本一致,不过不再每次都入最小栈
typedef struct MinStack {
    int array1[100];    // 普通数据(黑色)
    int top1;
    int array2[100];    // 最小数据(红色)
    int top2;
}   MinStack;

void Init(MinStack *pStack)
{
    pStack->top1 = pStack->top2 = 0;
}

void Push(MinStack *pStack, int data)
{
    pStack->array1[pStack->top1++] = data;
    if (pStack->top2 == 0 || data <= pStack->array2[pStack->top2 - 1]) //当最小数组中没数据或插入的数据小于最小数组的顶元素时,入最小数组{
        pStack->array2[pStack->top2++] = data;
    }
}

void Pop(MInStack *pStack)
{
    if (pStack->array1[pStack->top1 - 1] == pStack->array2[pStack->top2 - 1]) //当最小栈与普通数组中数据相等{
        pStack->top2--;//最小数组中出
    }
    pStack->top1--;//如果不相等,普通数组出
}

用两个栈实现一个队列

思想:定义两个栈p1和p2,先向p1中入栈,然后将从p1中出栈的数据又入到p2中,再直接把数据从p2中弹出,由此就可以实现队列先进先出的功能。
如图:
这里写图片描述

typedef struct SQueue
{
    Stack stack1;//入数据栈
    Stack stack2;//出数据栈
}SQueue;

void Init(SQueue *pSQ)
{
    Stack *p1, *p2;
    p1 = &(pSQ->stack1);
    p2 = &(pSQ->stack2);
    StackInit(p1);
    StackInit(p2);
}

void Push(SQueue *pSQ, SDataType data)
{
    Stack *p1, *p2;
    p1 = &(pSQ->stack1);
    p2 = &(pSQ->stack2);
    StackPush(p1,data);//只入第一个栈
}

void Pop(SQueue *pSQ)
{
    SDataType data;
    Stack *p1, *p2;
    p1 = &(pSQ->stack1);
    p2 = &(pSQ->stack2);
    if (StackIsEmpty(p2))
    {
        //当p2为空但p1不为空时,将p1中的数据弹出并压入到栈p2中
        while (!StackIsEmpty(p1))
        {
            data = StackTop(p1);
            StackPop(p1);
            StackPush(p2, data);
        }
    }
    StackPop(p2);//将p2中数据弹出栈
}

用两个队列实现一个栈

实现方法:定义两个队列,

  • :数据找一个非空的队列入,如果两个都为空,入第一个队列。
  • :出非空队列的数据到另一个队列中,直到剩下一个数据,直接将该数据弹出,重复该过程,直到最后一个数字被弹出。。
  • 这里写图片描述这里写图片描述

这里我们重点关注一下:

用一个队列实现一个栈

如图:
这里写图片描述
重复以上过程,直到最后一个数字被弹出。
代码实现:

typedef struct QStack
{
    Queue queue;
}QStack;

void Init(QStack *pQS)
{
    QueueInit(&(pQS->queue));
}

void Push(QStack *pQS, QDataType data)
{
    QueuePush(&(pQS->queue), data);
}

void Pop(QStack *pQS)
{
    int i;
    QDataType data;
    Queue *pQ = &(pQS->queue);
    for (i = 1; i < QueueSize(pQ); i++)
    {
        data = QueueFront(pQ);
        QueuePop(pQ);
        QueuePush(pQ, data);
    }
    QueuePop(pQ);
}
//查看队列顶端元素
QDataType Top(QStack *pQS)
{
    int i;
    QDataType data;
    Queue *pQ = &(pQS->queue);
    for (i = 1; i < QueueSize(pQ); i++)
    {
        data = QueueFront(pQ);
        QueuePop(pQ);
        QueuePush(pQ, data);
    }
    data = QueueFront(pQ);
    QueuePop(pQ);
    QueuePush(pQ, data);
    return data;
}

猜你喜欢

转载自blog.csdn.net/mmwwxx123/article/details/81264769