“队列栈”:用一个队列实现一个栈

“队列栈”:用一个队列实现一个栈

出栈思路:
1.将队列的队头元素取出,保存在变量data中,然后Pop掉,再将data Push进队列
2.若队列有n个元素,则需要进行步骤1 n -1 次后,此时队头元素就为此队列最后进入的值


1.Queue.h

#pragma once

#include <assert.h>
#include <String.h>
#include <stdlib.h>

// 利用单链表实现队列

typedef int QDataType;

// 队列结点定义
typedef struct QNode {
    QDataType data;     // 结点数据
    struct QNode *pNext;    //下一结点地址
}   QNode;

// 队列链表的定义
typedef struct Queue {
    QNode *pFront;  //队头 :进行删除
    QNode *pRear;   //队尾 :进行插入
    int size;       //结点个数,即队列大小
}   Queue;


// 队列初始化
void QueueInit(Queue *pQ) 
{
    assert(pQ != NULL);
    pQ->pFront = pQ->pRear = NULL;
    pQ->size = 0;
}

// 入队 : 从队尾插入一个元素
void  QueuePush(Queue *pQ, QDataType data) 
{
    assert(pQ != NULL);

    pQ->size++;
    QNode *pNewNode = (QNode *)malloc(sizeof(QNode));
    assert(pNewNode);
    pNewNode->data = data;
    pNewNode->pNext = NULL;

    // 若队列为空
    if (pQ->pRear == NULL) {
        pQ->pFront = pQ->pRear = pNewNode;
        return;
    }

    // 通常情况,即队列不为空,至少有一个结点
    pQ->pRear->pNext = pNewNode;
    pQ->pRear = pNewNode;

}

// 出队 :从队头删除一个元素
void QueuePop(Queue *pQ)
{
    assert(pQ != NULL);
    assert(pQ->size > 0); // 必须判断队列是否为空
    pQ->size--;

    // 通常情况
    QNode *pNode = pQ->pFront;
    pQ->pFront = pNode->pNext;
    free(pNode);

    // 若队列里面只有一个结点,删除后,队列为空,此时要改变队尾结点的状态
    if (pQ->pFront == NULL) {
        pQ->pRear = NULL;
    }
}

// 返回队首元素
QDataType QueueFront(Queue *pQ)
{
    assert(pQ != NULL);
    assert(pQ->size > 0);

    return pQ->pFront->data;
}

// 判断队列是否为空
// 1 为空, 0 不空
int QueueIsEmpty(Queue *pQ)
{
    return pQ->size == 0 ? 1 : 0;
}

// 返回队列数据个数
int QueueSize(Queue *pQ)
{
    return pQ->size;
}

void TestQueue()
{
    Queue queue;

    QueueInit(&queue);

    QueuePush(&queue, 1);
    QueuePush(&queue, 2); 
    QueuePush(&queue, 3);
    QueuePush(&queue, 4);

    QueuePop(&queue);
    QueuePop(&queue);
    QueuePop(&queue);
    QueuePop(&queue);

}

2.QStack.h

#pragma once
#include "Queue.h"
#include <stdio.h>

/*
    “队列栈”:用一个队列实现一个栈
    出栈思路:
    1.将队列的队头元素取出,保存在变量data中,然后Pop掉,再将data Push进队列
    2.若队列有n个元素,则需要进行步骤1 n -1 次后,此时队头元素就为此队列最后进入的值
*/

typedef struct QStack {
    Queue queue;
}   QStack;

// 初始化
void QStackInit(QStack *pQS)
{
    QueueInit(&(pQS->queue));
}

// 入栈
void QStackPush(QStack *pQS, QDataType data)
{
    QueuePush(&(pQS->queue), data);
}

// 出栈
void QStackPop(QStack *pQS)
{
    QDataType data;
    Queue *pQ = &(pQS->queue);

    for (int i = 1; i < QueueSize(pQ); i++) { //关键在于 i = 1,从1开始,若有n个元素,则循环 n - 1 次
        data = QueueFront(pQ);
        QueuePop(pQ);
        QueuePush(pQ, data);
    }

    QueuePop(pQ);
}

// 返回栈顶元素
QDataType QStackTop(QStack *pQS)
{
    QDataType data;
    Queue *pQ = &(pQS->queue);

    for (int i = 1; i < QueueSize(pQ); i++) { //关键在于 i = 1,从1开始,若有n个元素,则循环 n - 1 次
        data = QueueFront(pQ);
        QueuePop(pQ);
        QueuePush(pQ, data);
    }

    // 关键点:取完栈顶数据后,必须恢复到入栈时顺序
    data = QueueFront(pQ);
    QueuePop(pQ);
    QueuePush(pQ, data);

    return data;
}

void TestQStack()
{
    QStack qStack;

    QStackInit(&qStack);

    QStackPush(&qStack, 9);
    QStackPush(&qStack, 5);
    QStackPush(&qStack, 2);
    QStackPush(&qStack, 7);

    printf("%d\n",QStackTop(&qStack));
    QStackPop(&qStack);
    printf("%d\n", QStackTop(&qStack));

    system("pause");
}

3.Main.c

//#include "Queue.h"
#include "QStack.h"

int main()
{
    //TestQueue();

    TestQStack();

    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39026129/article/details/81242302
今日推荐