用两个栈实现队列

用两个栈实现队列

在这里插入图片描述

方法一

设置一个数据栈,一个辅助栈,
每次数据入栈直接进入数据栈。即元素全部存储在数据栈内部,只有需要出栈时临时出栈,然后又进栈。
每次出栈的时候先将数据栈中的元素出栈,压入辅助栈,直到最后一个元素,丢弃最后一个元素,然后将辅助栈出栈,再压入数据栈。

#define MAXSIZE 10000

typedef struct {
    int* StackTmp;
    int* StackDate;
    int TSTop;
    int DSTop;
} CQueue;

//创建队列
CQueue* cQueueCreate() {
    CQueue* CQ = (CQueue*)malloc(sizeof(CQueue));
    CQ->StackDate = (int*)malloc(sizeof(int)*MAXSIZE);
    CQ->StackTmp = (int*)malloc(sizeof(int)*MAXSIZE);
    CQ->TSTop = 0;
    CQ->DSTop = 0;
    return CQ;
}

void cQueueAppendTail(CQueue* obj, int value) {
    //尾插
   	//因为栈顶初始是0,所以先入栈,再加加。
    *(obj->StackDate + obj->DSTop) = value;
    obj->DSTop++;
}

int cQueueDeleteHead(CQueue* obj) {
    //头删
    //
    int tmp;
    if(!obj->DSTop){
        return -1;
    }
    //数据栈先出栈,消除队头后再入栈。
    while(obj->DSTop > 1){
        obj->DSTop--;
        *(obj->StackTmp + obj->TSTop) = *(obj->StackDate + obj->DSTop);
        obj->TSTop++;
    }
    obj->DSTop--;
    tmp = *(obj->StackDate + obj->DSTop);
    while(obj->TSTop){
        obj->TSTop--;
        *(obj->StackDate + obj->DSTop) = *(obj->StackTmp + obj->TSTop);
        obj->DSTop++;
    }
    return tmp;
}

void cQueueFree(CQueue* obj) {
    free(obj->StackDate);
    free(obj->StackTmp);
    free(obj);
}

/**
 * Your CQueue struct will be instantiated and called as such:
 * CQueue* obj = cQueueCreate();
 * cQueueAppendTail(obj, value);
 
 * int param_2 = cQueueDeleteHead(obj);
 
 * cQueueFree(obj);
*/

方法二

将两个栈中的一个栈用作出栈,另一个栈用作入栈(出栈栈,入栈栈),
入栈栈只负责入栈,出栈栈只负责出栈
出栈时,先判断,如果出栈栈和入栈栈栈顶均为0,则返回-1,如果出栈栈的栈顶为0则将入栈栈的数据出栈后再压入出栈栈中。再出栈。如果出栈栈栈顶不为0,则直接出栈就行。

#include<stdlib.h>
#define MAXSIZE 10000


typedef struct {
    int* PushStack;
    int* PopStack;
    int PushTop;
    int PopTop;
} CQueue;


CQueue* cQueueCreate() {
    CQueue* CQ = (CQueue*)malloc(sizeof(CQueue));
    if(!CQ){
        return NULL;
    }
    CQ->PushStack = (int*)malloc(sizeof(int)*MAXSIZE);
    if(!CQ->PushStack){
        return NULL;
    }
    CQ->PopStack = (int*)malloc(sizeof(int)*MAXSIZE);
    if(!CQ->PopStack){
        return NULL;
    }
    CQ->PushTop = 0;
    CQ->PopTop = 0;
    return CQ;
}
//直接入栈
void cQueueAppendTail(CQueue* obj, int value) {
    *(obj->PushStack + obj->PushTop) = value;
    obj->PushTop++;
}

int cQueueDeleteHead(CQueue* obj) {
    //出栈先判空,然后判断是否需要将入栈栈的数据压入出栈栈。
    if((!obj->PopTop) && (!obj->PushTop)){
        return -1;
    }
    else if(!obj->PopTop){
        while(obj->PushTop > 1){
            obj->PushTop--;
            *(obj->PopStack + obj->PopTop) = *(obj->PushStack + obj->PushTop);
            obj->PopTop++;
        }
        obj->PushTop--;
        return *(obj->PushStack + obj->PushTop);
    }
    else{
        obj->PopTop--;
        return *(obj->PopStack + obj->PopTop);
    }
}

void cQueueFree(CQueue* obj) {
    free(obj->PushStack);
    free(obj->PopStack);
    free(obj);
}

/**
 * Your CQueue struct will be instantiated and called as such:
 * CQueue* obj = cQueueCreate();
 * cQueueAppendTail(obj, value);
 
 * int param_2 = cQueueDeleteHead(obj);
 
 * cQueueFree(obj);
*/

方法三

将其中一个栈作为输入,另外一个栈作为输出,因为最多只调用10000次,为了约空间,两个栈的大小都是5000,可以在输入栈第一次满的时候设置一个标记,使得第一次栈满的时候能够将输入栈的数据移动到输出栈,从而输入输出共同存储。达到减小内存消耗的目的,相应的时间会加长。

#define MAXSIZE 5000

typedef struct {
    int* PushStack;
    int* PopStack;
    int PushTop;
    int PopTop;
    int FLAG;//设置标记,当入栈栈的栈顶第一次达到5000,标记置一,随后将数据压入出栈栈中。
} CQueue;


CQueue* cQueueCreate() {
    CQueue* CQ = (CQueue*)malloc(sizeof(CQueue));
    CQ->PushStack = (int*)malloc(sizeof(int)*MAXSIZE);
    CQ->PopStack = (int*)malloc(sizeof(int)*MAXSIZE);
    CQ->PushTop = 0;
    CQ->PopTop = 0;
    CQ->FLAG = 0;
    return CQ;
}

void cQueueAppendTail(CQueue* obj, int value) {
	//如果入栈栈满,并且标志位为0,则将入栈栈的数据压入出栈栈。
    if((obj->PushTop == 500) && (!obj->FLAG)){
        obj->FLAG = 1;
        while(obj->PushTop){
            obj->PushTop--;
            *(obj->PopStack + obj->PopTop) = *(obj->PushStack + obj->PushTop);
            obj->PopTop++;
        }
    }
    *(obj->PushStack + obj->PushTop) = value;
    obj->PushTop++;
}

int cQueueDeleteHead(CQueue* obj) {
    if((!obj->PopTop) && (!obj->PushTop)){
        return -1;
    }
    else if(!obj->PopTop){
        if(obj->FLAG){
            obj->FLAG = 0;
        }
        while(obj->PushTop){
            obj->PushTop--;
            *(obj->PopStack + obj->PopTop) = *(obj->PushStack + obj->PushTop);
            obj->PopTop++;
        }
        obj->PopTop--;
        return *(obj->PopStack + obj->PopTop);
    }
    else{
        obj->PopTop--;
        return *(obj->PopStack + obj->PopTop);
    }
}

void cQueueFree(CQueue* obj) {
    free(obj->PushStack);
    free(obj->PopStack);
    free(obj);
}

/**
 * Your CQueue struct will be instantiated and called as such:
 * CQueue* obj = cQueueCreate();
 * cQueueAppendTail(obj, value);
 
 * int param_2 = cQueueDeleteHead(obj);
 
 * cQueueFree(obj);
*/

关于栈和队列的基本操作和特征。
栈先入后出
队列先入先出

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值