【数据结构】栈和队列的交互实现

目录

1.用队列实现栈

1.1实现原理:在前文中我们已经实现了队列和栈,但是如何去用对列的功能实现栈呢?

1.2代码实现

2栈实现队列

2.1实现思路 

2.2代码实现 

1.用队列实现栈

1.1实现原理:在前文中我们已经实现了队列和栈,但是如何去用对列的功能实现栈呢?

对列是先进先出,栈是先进后出,所以我们不妨开辟两块空间,来回倒腾。

 我们用对列的先进先出存放数据,让后我们再利用栈先进后出的性质,先把前面的数据移到新区,然后删去最后一个数据。我们在这用C语言实现。

1.2代码实现

#pragma once
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>


typedef int QdateType;

typedef struct QueueNode// 节点
{
	QdateType data;
	struct QueueNode* next;
}QNode;

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

//初始化
void QueueInit(Queue* pd);
//销毁
void QueueDestroy(Queue* pd);
// 判空
int QueueEmpty(Queue* pd);
//入列
void QueuePush(Queue* pd, QdateType x);
//返回队尾
void QueueBack(Queue* pd);
//返回队首
void QueueFront(Queue* pd);
//返回个数
int QueueSize(Queue* pd);

//初始化
void QueueInit(Queue* pd)
{
	assert(pd);
	pd->head = pd->tail = NULL;
	pd->size = 0;
}

//销毁
void QueueDestroy(Queue* pd)
{
	assert(pd);
	QNode* cur = pd->head;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pd->head = pd->tail = NULL;
}

//判空
int QueueEmpty(Queue* pd)
{
	if (pd->head == NULL)
	{
		return 1;
	}
	else
		return 0;
}

//返回长度
int QueueSize(Queue* pd)
{
	return pd->size;
}


//入列
void QueuePush(Queue* pd, QdateType x)
{
	assert(pd);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		printf("malloc:falue");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;

	//一个没有就进行插入
	if (pd->tail == NULL)
	{
		pd->head = pd->tail = newnode;
	}

	else
	{
		pd->tail->next = newnode;
		pd->tail = newnode;
	}

}

//出列
void QueuePop(Queue* pd)
{
	assert(pd);
	assert(!QueueEmpty(pd));
	if (pd->head->next == NULL)
	{
		free(pd->head);
		pd->head = pd->tail = NULL;
	}
	else
	{
		QNode* next = pd->head->next;   //保存下一个节点地址,防止找不到
		free(pd->head);
		pd->head = next;
	}
}

//返回队首
void QueueFront(Queue* pd)
{
	assert(pd);
	assert(!QueueEmpty(pd));
	return pd->head->data;
}

//返回队尾
void QueueBack(Queue* pd)
{
	assert(pd);
	assert(!QueueEmpty(pd));
	return pd->tail->data;
}

typedef struct {
	Queue q1;
	Queue q2;
} MyStack;


MyStack* myStackCreate() {
	MyStack* obj = (MyStack*)malloc(sizeof(MyStack));
	QueueInit(&obj->q1);
	QueueInit(&obj->q2);
	return obj;
}

void myStackPush(MyStack* obj, int x) {
	if (QueueEmpty(&obj->q1))
	{
		QueuePush(&obj->q2, x);
	}
	else
	{
		QueuePush(&obj->q1, x);

	}

}

//删除
int myStackPop(MyStack* obj) 
{

	
}

//返回栈顶值
int myStackTop(MyStack* obj) {
	if (QueueEmpty(&obj->q1))
	{
		return QueueBack(&obj->q2);
	}
	else
	{
		return QueueBack(&obj->q1);
	}
}
bool myStackEmpty(MyStack* obj) {
	return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
}

void myStackFree(MyStack* obj) {
	if (QueueEmpty(&obj->q1))
		QueueDestory(&obj->q2);
	else
		QueueDestory(&obj->q1);
}

这其中就自己写的值在两块空间互换那个有点难。

2栈实现队列

2.1实现思路 

也就是用栈实现先进先出。,仿照上面创建两个对列,那我们再创建两个栈。

2.2代码实现 


#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>


typedef int STDataType;

typedef struct Stack
{
	STDataType* data;//数据	
	int top;//栈顶
	int capacity;//容量
}Stack;

// 初始化栈
void StackInit(Stack* ps)
{
	assert(ps);
	ps->capacity = 0;
	ps->data = NULL;
	ps->top = 0;
}
// 入栈
void StackPush(Stack* ps, STDataType data)
{
	assert(ps);
	if (ps->top == ps->capacity)//判断容量
	{
		int newcapacity = (ps->capacity == 0 ? 4 : 2 * ps->capacity);
		STDataType* tmp = realloc(ps->data, sizeof(STDataType) * newcapacity);//扩容
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(-1);
		}
		ps->capacity = newcapacity;
		ps->data = tmp;
	}
	ps->data[ps->top] = data;//压入数据
	ps->top++;
}
// 出栈
void StackPop(Stack* ps)
{
	assert(ps);
	if (ps->top == 0)return NULL;
	ps->top--;
}
// 获取栈顶元素
STDataType StackTop(Stack* ps)
{
	assert(ps);
	if (ps->top == 0)return NULL;
	return ps->data[ps->top - 1];//top位置是压入数据的位置,所以栈顶元素也就是它前一个元素
}
// 获取栈中有效元素个数
int StackSize(Stack* ps)
{
	return ps->top;
}
// 销毁栈
void StackDestroy(Stack* ps)
{
	assert(ps);
	free(ps->data);
	ps->data = NULL;
	ps->top = 0;
	ps->capacity = 0;
}
int StackEmpty(Stack* ps)
{
	if (ps->top == 0)return 1;
	else return 0;
}
typedef struct {
	Stack PushST;
	Stack PopST;

} MyQueue;


MyQueue* myQueueCreate() {
	MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));
	StackInit(&(obj->PushST));
	StackInit(&(obj->PopST));

	return obj;

}

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

int myQueuePop(MyQueue* obj) {
	if (StackEmpty(&(obj->PopST)))
	{
		while (!StackEmpty(&(obj->PushST)))
		{
			StackPush(&(obj->PopST), StackTop(&(obj->PushST)));
			StackPop(&(obj->PushST));
		}
	}
	STDataType Front = StackTop(&(obj->PopST));
	StackPop(&(obj->PopST));
	return Front;

}

//返回队列开头的元素
int myQueuePeek(MyQueue* obj) {
	if (StackEmpty(&(obj->PopST)))
	{
		while (!StackEmpty(&(obj->PushST)))
		{
			StackPush(&(obj->PopST), StackTop(&(obj->PushST)));
			StackPop(&(obj->PushST));
		}
	}

	return  StackTop(&(obj->PopST));
}

bool myQueueEmpty(MyQueue* obj) {
	return StackEmpty(&(obj->PushST)) && StackEmpty(&(obj->PopST));
}
void myQueueFree(MyQueue* obj) {
	StackDestroy(&(obj->PopST));
	StackDestroy(&(obj->PushST));
	free(obj);
}

这个栈实现对列的精华是push栈中的数据往pop栈中转移,转移过程中一定注意两者情况:1.pop栈中没有数据,那可以直接转栈,2.是pop栈中有数据,那必须是先把pop栈中数据转移出来在移动数据。

用C语言实现过程难免有一些冗余,有问题可以私信我。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值