用队列实现栈

队列的定义:

typedef int QNDataType;


//队列的链式结构
typedef struct QueueNode {
    QNDataType data;
    struct QueueNode* next;
}QN;


//创建一个结构用于记录队列的头尾
typedef struct queue {
    QN* head;
    QN* tail;
    size_t size;
}queue;


//初始化
void queueInit(queue* pq);
//销毁
void queueDestroy(queue* pq);
//节点入队
void queuePush(queue* pq, QNDataType x);
//出队
void queuePop(queue* pq);
//取队头数据
QNDataType queueFront(queue* pq);
//取队尾数据
QNDataType queueBack(queue* pq);
//判空
bool queueEmpty(queue* pq);
//计算节点个数
size_t queueSize(queue* pq);


//初始化
void queueInit(queue* pq) {
    assert(pq);
 
    pq->head = NULL;
    pq->tail = NULL;
    pq->size = 0;
}
 
 
//销毁
void queueDestroy(queue* pq) {
    assert(pq);
    //定义一个cur节点指向头节点
    QN* cur = pq->head;
    while (cur) {
        QN* del = cur;
        cur = cur->next;
        free(del);
    }
 
    pq->head = NULL;
    pq->tail = NULL;
}
 
 
//节点入队
void queuePush(queue* pq, QNDataType x) {
    assert(pq);
 
 
    //动态开辟一个新节点
    QN* newnode = (QN*)malloc(sizeof(QN));
    if (newnode == NULL) {
        perror("malloc newnode is fail!\n");
        exit(-1);
    }
    //初始化newnode
    newnode->data = x;
    newnode->next = NULL;
    //如果pq->tail为空,把tail和head都设为newnode
    //如果不为空则先把newnode入队,再让tail指向newnode
    if (pq->tail) {
        pq->tail->next = newnode;
        pq->tail = newnode;
    }
    else {
        pq->tail = pq->head = newnode;
    }
    pq->size++;
}
 
 
//出队
void queuePop(queue* pq) {
    assert(pq);
    if (queueEmpty(pq)) {
        printf("队列已空!\n");
    }
    else {
        //如果删完之后队列为空,把head和tail都置空
        QN* del = pq->head;
        pq->head = pq->head->next;
        free(del);
        if (pq->head == NULL) {
            pq->tail = NULL;
        }
        pq->size--;
    }
}
 
 
//取队头数据
QNDataType queueFront(queue* pq) {
    assert(pq);
    assert(!queueEmpty(pq));
        
    return pq->head->data;
}
 
 
//取队尾数据
QNDataType queueBack(queue* pq) {
    assert(pq);
    assert(!queueEmpty(pq));
 
    return pq->tail->data;
}
 
 
//判空
bool queueEmpty(queue* pq) {
    assert(pq);


    return pq->head == NULL && pq->tail == NULL;
}
 
 
//计算节点个数
size_t queueSize(queue* pq) {
    assert(pq);
 
    //当queue结构体中有size成员的时候可以通过在插入删除时改变size
    return pq->size;
}

思路:

队列设为q1、q2
将有数据的队列看为uept,无数据的队列设为ept
一开始把所有数据都插入uept
入栈:直接在uept后面入队
出栈:先把uppt除了队尾的所有元素都导入ept,然后剩下的最后一个元素出队
返回栈顶元素:调用QueueBack直接找到uept队尾元素的并返回
判空:对q1、q2判空,同为空则空

typedef struct {
    queue q1;
    queue q2;
} MyStack;



MyStack* myStackCreate() {
    //动态创建结构体
    MyStack* obj = (MyStack*)malloc(sizeof(MyStack));
    //初始化
    queueInit(&obj->q1);
    queueInit(&obj->q2);


    return obj;
}


void myStackPush(MyStack* obj, int x) {
    //往非空队列中Push
    if(!queueEmpty(&obj->q1)){
        queuePush(&obj->q1,x);
    }else{
        queuePush(&obj->q2,x);
    }
}


int myStackPop(MyStack* obj) {
    //先默认设q1不为空
    MyStack* uept = &obj->q1;
    MyStack* ept = &obj->q2;
    //如果q1为空则设q1为空
    if(queueEmpty(&obj->q1)){
        ept = &obj->q1;
        uept = &obj->q2;
    }
    //开始导数据
    //当uept的元素个数大于1,把数据导入ept
    while(queueSize(uept)>1){
        //把uept的队头元素导入ept
        queuePush(ept,queueFront(uept));
        //uept队头元素出队
        queuePop(uept);


    }
    //当uept剩一个元素,记录一下该元素并出队
    int top= queueFront(uept);
    queuePop(uept);


    return top;
}


int myStackTop(MyStack* obj) {
    // //可用myStackPop
    // int top = myStackPop(obj);
    // myStackPush(obj,top);


    // return top;
    
    //也可直接使用queueBack找到uept的队尾元素并返回
    if(!queueEmpty(&obj->q1)){
        return queueBack(&obj->q1);
    }else{
        return queueBack(&obj->q2);
    }
}


bool myStackEmpty(MyStack* obj) {
    if(queueEmpty(&obj->q1) && queueEmpty(&obj->q2)){
        return true;
    }else{
        return false;
    }
    //return queueEmpty(&obj->q1) && queueEmpty(&obj->q2);
}


void myStackFree(MyStack* obj) {
    queueDestroy(&obj->q1);
    queueDestroy(&obj->q2);
    free(obj);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值