用两个栈实现队列
方法一
设置一个数据栈,一个辅助栈,
每次数据入栈直接进入数据栈。即元素全部存储在数据栈内部,只有需要出栈时临时出栈,然后又进栈。
每次出栈的时候先将数据栈中的元素出栈,压入辅助栈,直到最后一个元素,丢弃最后一个元素,然后将辅助栈出栈,再压入数据栈。
#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);
*/
关于栈和队列的基本操作和特征。
栈先入后出
队列先入先出