栈和队列的相互实现(C)

1.[用栈实现队列]https://leetcode.cn/problems/implement-queue-using-stacks/description/

在这里插入图片描述

思路:

建立两个栈,pushst(只进栈),popst(只出栈)
每次进栈时都进pushst,出栈时都出popst。在出栈之前要判断栈是否为NULL,如果为空,就把pushst,倒到popst.

特别注意:栈是“后进先出”

思路图解

  • 向pushst中插入1,2,3,4
    在这里插入图片描述
  • pop掉一个数据
    在这里插入图片描述
  • push 5,6
    在这里插入图片描述
  • pop 两次
    在这里插入图片描述

2.全套代码

说明:因为是用C语言实现的,所以首先需要自己创建一个栈


//栈的创建

typedef int STDataType;//提高代码的维护性

typedef struct Stack
{
	STDataType* a;//动态
	int top;//栈顶
	int capacity;//空间大小
}ST;

//栈的初始化和销毁
void STInit(ST* st);
void STDestroy(ST* st);

//栈的插入和删除
void STPush(ST* st, STDataType x);
void STPop(ST* st);

//取栈顶元素
STDataType Get(ST* st);

//判空
bool STEmpty(ST* st);

//求栈的长度
int STSize(ST* st);

//栈的初始化和销毁
void STInit(ST* st)
{
	assert(st);
	st->a = NULL;
	st->top = st->capacity = 0;
}

void STDestroy(ST* st)
{
	free(st->a);
	st->a = NULL;
	st->top = st->capacity = 0;
}

//栈的插入和删除
void STPush(ST* st, STDataType x)
{
	assert(st);
	//如果空间不够就进行扩容
	if (st->capacity == st->top)
	{
		int newcapacity = st->capacity == 0 ? 4 : st->capacity * 2;
		ST* tmp = (ST*)realloc(st->a,sizeof(STDataType) * newcapacity);
		if (tmp == NULL)
		{
			perror("realloc");
			return;
		}
		//扩容成功
		st->a = tmp;
		st->capacity = newcapacity;
	}

	st->a[st->top] = x;
	st->top++;
}

void STPop(ST* st)
{
	assert(st);
	assert(st->top > 0);
	st->top--;
}

//取栈顶元素
STDataType Get(ST* st)
{
	assert(st);
	assert(st->top > 0);
	return st->a[st->top - 1];
}

//判空
bool STEmpty(ST* st)
{
	assert(st);
	return st->top == 0;
}

//求栈的长度
int STSize(ST* st)
{
	assert(st);
	return st->top;
}
//创建栈完成

//…………………………………………………………………………………………………………………………………………………………………………………………………………………………
//定义两个栈
typedef struct {
    ST pushst;
    ST popst;
} MyQueue;


MyQueue* myQueueCreate() {
    MyQueue* tmp=(MyQueue* )malloc(sizeof(MyQueue));
    STInit(&tmp->pushst);
    STInit(&tmp->popst);
    return tmp;
}

void myQueuePush(MyQueue* obj, int x) {
    STPush(&obj->pushst,x);
}

int myQueuePop(MyQueue* obj) {
    int top=myQueuePeek(obj);
    STPop(&obj->popst);
    return top;
}
//要想取元素,一定要让s2中存在数据
int myQueuePeek(MyQueue* obj) {
   if(STEmpty(&obj->popst))
    {
        while(STSize(&obj->pushst)>0)
        {
            STPush(&obj->popst,Get(&obj->pushst));
            STPop(&obj->pushst);
        }
    }
    return Get(&obj->popst);
}

bool myQueueEmpty(MyQueue* obj) {
    return STEmpty(&obj->pushst)&&STEmpty(&obj->popst);
}

void myQueueFree(MyQueue* obj) {
    STDestroy(&obj->pushst);
    STDestroy(&obj->popst);
    free(obj);
    obj=NULL;
}

/**
 * Your MyQueue struct will be instantiated and called as such:
 * MyQueue* obj = myQueueCreate();
 * myQueuePush(obj, x);
 
 * int param_2 = myQueuePop(obj);
 
 * int param_3 = myQueuePeek(obj);
 
 * bool param_4 = myQueueEmpty(obj);
 
 * myQueueFree(obj);
*/

3.[用队列实现栈]https://leetcode.cn/problems/implement-stack-using-queues/description/

在这里插入图片描述

思路:

创建两个空队列,q1,q2
刚开始两个队列都是空,插入数据就随便向那个里面插入。后面插入数据时,看那个队列不是空,就插入到那个队列内
删除数据时,把数据从不为空的队列,倒到为空的队列里面(只用倒前N-1个,最后一个直接pop掉)

思路图解
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

4.全套代码

说明:用C语言实现,需要直接先创建一个队列

//创建队列

typedef int QDataType;
//创建节点结构体
typedef struct QueueNode
{
	struct Queue* next;
	QDataType val;
}QNode;
//定义了头指针和尾指针,避免二级指针
//1.二级指针 2.带哨兵位的头节点 3.创建一个结构体,封装头,尾指针
typedef struct Queue
{
	QNode* phead;
	QNode* ptail;
	int size;//方便计算队列中元素个数
}Queue;

//初始化,销毁
void QInint(Queue* pq);
void Qdestroy(Queue* pq);

//插入,删除
void QPush(Queue* pq, QDataType x);
void QPop(Queue* pq);

//求长度
int QSize(Queue* pq);

//取队列头和尾的元素
QDataType GetFront(Queue* pq);
QDataType GetBack(Queue* pq);

//判空
bool QEmpty(Queue* pq);

//初始化,销毁
void QInint(Queue* pq)
{
	assert(pq);
	pq->phead = NULL;
	pq->ptail = NULL;
	pq->size = 0;
}

void Qdestroy(Queue* pq)
{
	assert(pq);
	while (pq->phead)
	{
		QNode* next = pq->phead->next;
		free(pq->phead);
		pq->phead = next;
	}
	pq->ptail = NULL;
    pq->size=0;
}

//插入,删除
void QPush(Queue* pq, QDataType x)
{
	//创建一个新的节点
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		return;
	}
	newnode->val = x;
	newnode->next = NULL;

	if (pq->ptail == NULL)
	{
		pq->phead = pq->ptail = newnode;
	}
	else
	{
		pq->ptail->next = newnode;
		pq->ptail = newnode;
	}
	pq->size++;
}

void QPop(Queue* pq)
{
	assert(pq);
	assert(pq->size > 0);
	if (pq->phead == pq->ptail)//只有一个节点
	{
		free(pq->phead);
		pq->phead = pq->ptail = NULL;
	}
	else//有一个以上的节点
	{
		QNode* next = pq->phead->next;
		free(pq->phead);
		pq->phead = next;
	}
	//如果直接像下面这么写,ptail就会变成野指针
	/*QNode* next = pq->phead->next;
	free(pq->phead);
	pq->phead = next;*/

	pq->size--;
}

//求长度
int QSize(Queue* pq)
{
	assert(pq);
	return pq->size;
}

//取队列头和尾的元素
QDataType GetFront(Queue* pq)
{
	assert(pq);
	assert(pq->size > 0);
	return pq->phead->val;
}
QDataType GetBack(Queue* pq)
{
	assert(pq);
	assert(pq->size > 0);
	return pq->ptail->val;
}
//判空
bool QEmpty(Queue* pq)
{
	assert(pq);
	return pq->size == 0;
}
//创建队列完成
//……………………………………………………………………………………………………………………………………………………………………………………………………………………
//定义两个队列结构
//匿名结构体
typedef struct {
    Queue q1;
    Queue q2;
} MyStack;


MyStack* myStackCreate() {
    MyStack*tmp=(MyStack*)malloc(sizeof(MyStack));
    QInint(&tmp->q1);//初始化
    QInint(&tmp->q2);
    return tmp;
}
//关于向队列里面插入数
//向队列不为空的里面插入数据,然后两个队列之间相互倒
void myStackPush(MyStack* obj, int x) {
    //假设法
    Queue* NoEmpty=&obj->q1,*Empty=&obj->q2;
    if(!QEmpty(&obj->q2))
    {
       NoEmpty=&obj->q2;
       Empty=&obj->q1;
    }

    QPush(NoEmpty,x);

}

int myStackPop(MyStack* obj) {
    Queue* NoEmpty=&obj->q1,*Empty=&obj->q2;
    if(!QEmpty(&obj->q2))
    {
       NoEmpty=&obj->q2;
       Empty=&obj->q1;
    }
    while(QSize(NoEmpty)>1)
    {
        QPush(Empty,GetFront(NoEmpty));
        QPop(NoEmpty);
    }
    //现在非空链表中还剩一个元素
    int ret=GetFront(NoEmpty);
    QPop(NoEmpty);
    return ret;
}

int myStackTop(MyStack* obj) {
    Queue* NoEmpty=&obj->q1,*Empty=&obj->q2;
    if(!QEmpty(&obj->q2))
    {
       NoEmpty=&obj->q2;
       Empty=&obj->q1;
    }
    return GetBack(NoEmpty);
}

bool myStackEmpty(MyStack* obj) {
    return QEmpty(&obj->q1)&&QEmpty(&obj->q2);
}

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

/**
 * Your MyStack struct will be instantiated and called as such:
 * MyStack* obj = myStackCreate();
 * myStackPush(obj, x);
 
 * int param_2 = myStackPop(obj);
 
 * int param_3 = myStackTop(obj);
 
 * bool param_4 = myStackEmpty(obj);
 
 * myStackFree(obj);
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值