请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。
思路:队列是先进先出,栈是后进先出
实现入栈:
向不为空的队列中入队,保持另一个队列为空
实现出栈:
非空队列依次出队,将数据转移到空队列中保存,只剩最后一个数据出队列
代码实现
//队列数据类型
typedef int QDataType;
//队列中数据结构体
typedef struct QueueNode
{
struct QueueNode* next;
QDataType data;
}QueueNode;
typedef struct Queue
{
QueueNode* head;//队头指针
QueueNode* tail;//队尾指针
//size_t size;
}Queue;
//队列初始化
void QueueInit(Queue* pq);
//销毁队列
void QueueDestroy(Queue* pq);
//入队
void QueuePush(Queue* pq,QDataType x);
//出队
void QueuePop(Queue* pq);
//获取队头元素
QDataType QueueFront(Queue* pq);
//获取队尾元素
QDataType QueueBack(Queue* pq);
//获取队列中有效元素个数
int QueueSize(Queue* pq);
//检测队列是否为空,如果为空返回非零结果,如果非空返回0
bool QueueEmpty(Queue* pq);
void QueueInit(Queue* pq)
{
//我们需要改变结构体的内容(需要改变结构成员head,tail),所以传入结构体指针
//对于结构的指针成员,要初始化
assert(pq);
pq->head = NULL;
pq->tail = NULL;
}
void QueueDestroy(Queue* pq)
{
assert(pq);
QueueNode* cur = pq->head;
while (cur != NULL)
{
QueueNode* next = cur->next;
free(cur);
cur = NULL;
}
pq->head = pq->tail = NULL;
}
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
newnode->data = x;
newnode->next = NULL;
if (pq->head == NULL)
{
//1.队列为空
pq->head = pq->tail = newnode;
}
else
{
//2.队列不为空,尾部直接插入
pq->tail->next = newnode;
pq->tail = newnode;
}
}
bool QueueEmpty(Queue* pq)
{
//队列为空时 head == NULL
assert(pq);
return pq->head == NULL;
}
void QueuePop(Queue* pq)
{
assert(pq);//结构体指针是不可能为空的,结构体成员指针指向NULL,与
//结构体指针为空没有任何关系
//1.队列空
//assert(pq->head!=NULL);
assert(!QueueEmpty(pq));
QueueNode* next = pq->head->next;
free(pq->head);
pq->head = next;
if (pq->head == NULL)
{
//2.只有一个元素 head = tail 注意处理tail变成野指针的情况
//链表已经删完了
pq->tail = NULL;
}
}
QDataType QueueBack(Queue* pq)
{
assert(pq);
//assert(pq->tail!=NULL);
assert(!QueueEmpty(pq));
return pq->tail->data;
}
QDataType QueueFront(Queue* pq)
{
assert(pq);
//assert(pq->head!=NULL);
assert(!QueueEmpty(pq));
return pq->head->data;
}
int QueueSize(Queue* pq)
{
assert(pq);
QueueNode* cur = pq->head;
int sz = 0;
//遍历队列
while (cur!= NULL)
{
sz++;
cur = cur->next;
}
return sz;
}
//对匿名结构体重命名
//定义栈结构体类型
typedef struct {
Queue q1;
Queue q2;
} MyStack;
MyStack* myStackCreate() {
//st是野指针,这样错误
// MyStack s;
// MyStack* st = &s;
// return st;
//为了保证除了函数作用域,结构体指针还存在,这里选择在堆上开辟空间
//不建议使用全局变量
MyStack* st = (MyStack*)malloc(sizeof(MyStack));
// if(st == NULL)
// {
// exit(-1);
// }
//初始化
//(st->q1).head = NULL
//使用接口进行初始化
QueueInit(&(st->q1));
QueueInit(&(st->q2));
return st;
}
void myStackPush(MyStack* obj, int x)
{
//非空队列入队
if(!QueueEmpty(&obj->q1))
{
QueuePush(&obj->q1,x);
}
else
{
QueuePush(&obj->q2,x);
}
}
int myStackPop(MyStack* obj) {
//将非空队列的数据转移到另一个队列
Queue* emptyQ = &obj->q1;
Queue* nonEmptyQ = &obj->q2;
//
if(!QueueEmpty(&obj->q1))
{
//q1不为空
emptyQ = &obj->q2;
nonEmptyQ = &obj->q1;
}
while(QueueSize(nonEmptyQ)>1)
{
//非空队列依次出队,空队列依次入队
QueuePush(emptyQ,QueueFront(nonEmptyQ));
QueuePop(nonEmptyQ);
}
//非空队列最后一个元素出队
int top = QueueFront(nonEmptyQ);
QueuePop(nonEmptyQ);
return top;
}
//返回栈顶元素
int myStackTop(MyStack* obj)
{
//返回非空队列队尾元素
if(!QueueEmpty(&obj->q1))
{
return QueueBack(&obj->q1);
}
else{
return QueueBack(&obj->q2);
}
}
bool myStackEmpty(MyStack* obj)
{
//两个队列都不为空,则栈不为空
return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
}
void myStackFree(MyStack* obj)
{
//先销毁两个队列
QueueDestroy(&obj->q1);
QueueDestroy(&obj->q2);
free(obj);
//obj = NULL;
}
测试代码:
int main()
{
MyStack* obj = myStackCreate();
myStackPush(obj, 1);
myStackPush(obj, 2);
myStackPush(obj, 3);
int param_2 = myStackPop(obj);
int param_3 = myStackTop(obj);
bool param_4 = myStackEmpty(obj);
myStackFree(obj);
return 0;
}