【1++的数据结构初阶】之用队列实现栈

👍作者主页:进击的1++
🤩 专栏链接:1++的数据结构初阶

一,如何用队列实现栈

1.1 什么是栈

栈是一种后进先出的数据结构,只能在栈顶进行进栈,出栈操作。关于栈的详解请看往期文章【1++的数据结构初阶】之栈

1.2 什么是队列

队列是一种先进先出的数据结构,只能在队尾插入,在队头删除。关于队列的详解请看往期文章【1++的数据结构初阶】之队列

1.3 用队列实现栈的原理

队列只能在队尾插入,队头删除,而栈则都是在栈顶进行插入,删除操作。因此,一个队列是不可能去实现栈的,既然一个队列无法实现,那么我们应该考虑多个队列能否实现呢?其中一个队列实现插入操作,另一个实现删除操作;或者说两个队列通过相互之间倒数据来实现栈的插入与删除。
首先要入栈时,若两个队列都为空,则随便入哪个队列都可以;否则,入队列里的非空队列;出栈时,先将非空队列里的前k-1个数据全部经出队,再进队到另一个空队列中,最后将队列里剩余的一个数据出队,就完成了出栈。

详解图如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二,代码实现

2.1 入栈的实行

typedef int	QDatatype;

typedef struct Node
{
	struct Node* next;
	QDatatype data;
}Node;

typedef struct Queue
{
	Node* head;
	Node* tail;
	int size;
}Queue;

void QInit(Queue* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
	pq->size = 0;
}

void QDestroy(Queue* pq)
{
	assert(pq);
	Node* cur = pq->head;
	while (cur != NULL)
	{
		Node* next = cur->next;
		free(cur);
		cur = next;	
	}
	pq->head = pq->tail = NULL;
	pq->size = 0;
}

void QPush(Queue* pq , QDatatype x)
{
	assert(pq);
	Node* tmp = (Node*)malloc(sizeof(Node));
	if (tmp == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	Node* newnode = tmp;
	newnode->next = NULL;
	newnode->data = x;
	if (pq->head==NULL)
	{
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
	pq->size++;

}

void QPop(Queue* pq)
{
	assert(pq);
	assert(pq->head!=NULL);
	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		Node* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
	pq->size--; 
}

bool QEmpty(Queue* pq)
{
	assert(pq);
	return pq->size == 0;
}

int QSize(Queue* pq)
{
	assert(pq);
	return pq->size;
}

QDatatype QFront(Queue* pq)
{
	assert(pq);
	assert(!QEmpty(pq));
	return pq->head->data;
}

QDatatype QBack(Queue* pq)
{
	assert(pq);
	assert(!QEmpty(pq));
	return pq->tail->data;
}
typedef struct MyStack
{
	Queue* q;
	Queue* p;
}MyStack;

MyStack* CreatMyStack()
{
	MyStack* obj =(MyStack*)malloc(sizeof(MyStack));
	assert(obj);
	QInit(&obj->p);
	QInit(&obj->q);
	return obj;
}

void MyStackPush(MyStack* obj,QDatatype x)
{
	assert(obj);
	if(QEmpty(&obj->p))
	{
		QPush(&obj->p,x);
	}
	else
	{
		QPush(&obj->q, x);
	}
}

2.2 出栈的实行

bool MyStackEmpty(MyStack* obj)
{
	return (QEmpty(&obj->p) == NULL && QEmpty(&obj->q) == NULL);
}

void MyStackPop(MyStack* obj)
{
	assert(obj);
	assert(!MyStackEmpty(obj));
	//将数据挪到另一个空队列
	Queue* empt = &obj->p;
	Queue* fill = &obj->q;
	if (QEmpty(&obj->q))
	{
		empt = &obj->q;
		fill = &obj->p;
	}
	while (QSize(fill) > 1)
	{
		QPush(empt, QFront(fill));
		QPop(fill);
	}
	QPop(fill);

}

2.3 出栈顶及其销毁栈

int MyStackTop(MyStack* obj)
{
	assert(obj);
	if (!QEmpty(&obj->p))
	{
		return QBack(&obj->p);
	}
	else
	{
		return QBack(&obj->q);
	}
}

void myStackFree(MyStack* obj)
{
	assert(obj);
	QDestroy(&obj->q);
	QDestroy(&obj->p);
	free(obj);

}

三,总结

本篇文章主要难点在于结构,代码本身没有什么难度,在学习本篇文章前建议对队列及栈有较好的基础与理解,如果读者觉得本篇文章不错,希望能够点赞分享,若发现文章有不足之处及错误,欢迎指正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

进击的1++

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值