【数据结构】用两个栈实现一个队列(链式)

本文介绍了一种使用两个栈来实现队列的方法,并提供了详细的C语言实现代码。通过定义链式栈结构,实现了栈的基本操作如压栈、出栈、获取栈顶元素等。此外,还介绍了如何利用两个栈模拟队列的行为,包括入队、出队和获取队首元素等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

queue.h

#pragma once

#include<stdio.h>


typedef char StackType;

/*创建一个结点储存数据*/
typedef struct Node{
	StackType data;
	struct Node* next;
}Node;

typedef struct Stack{
	struct Node* top;
	struct Node* bottom;
}LinkStack;

/*初始化链式栈*/
LinkStack* InitStack();
/*压栈一个元素*/
StackType LinkStackPush(LinkStack* stack, StackType value);
/*创建一个结点*/
Node* CreateNode(StackType value);
/*
*打印栈
*为了测试压栈出栈正确与否才遍历栈
*/
void PrintStack(LinkStack* stack, char* msg);
/*出栈一个元素*/
void LinkStackPop(LinkStack* stack);
/*获取栈顶元素*/
StackType LinkStakGetTopValue(LinkStack* stack);
/*销毁栈*/
void LinkStackDestory(LinkStack* stack);

/*
*两个栈实现一个队列
*/
/*压入元素操作和链表的一样,不写了*/
/*出队首元素*/
void QueuePop(LinkStack* stack1, LinkStack* stack2);
/*获取队首元素*/
StackType QueueGetHead(LinkStack* stack1);


queue.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"NewQueue.h"

/*创建一个结点*/
Node* CreateNode(StackType value) {

	Node* p = (Node*)malloc(sizeof(Node));
	/*可能申请内存空间不成功,所以必须判断*/
	if (p != NULL) {
		p->data = value;
		p->next = NULL;

		return p;
	}
}

/*初始化链式栈*/
LinkStack* InitStack() {
	
	/*构造一个空的链式栈*/
	LinkStack* stack1 = (LinkStack*)malloc(sizeof(LinkStack));
	/*创建一个尾结点*/
	stack1->bottom = CreateNode("0");
	stack1->top = stack1->bottom;
	return stack1;
}

/*压栈一个元素*/
StackType LinkStackPush(LinkStack* stack, StackType value) {

	if (stack == NULL) {
		return;
	}
	if (stack->bottom == NULL || stack->top == NULL) {
		/*初始化不成功*/
		return;
	}
	/*创建了一个结点*/
	Node* node = CreateNode(value);
	/*压入栈*/
	if (stack->bottom == stack->top) {
		node->next = stack->bottom;
		stack->top = node;
	}
	else {
		node->next = stack->top;
		stack->top = node;
	}
}
/*
*打印栈
*为了测试压栈出栈正确与否才遍历栈
*/
void PrintStack(LinkStack* stack, char* msg) {

	if (stack == NULL) {
		return;
	}
	printf("%s \n", msg);
	printf("[top]->");
	Node* cur = stack->top;
	while (cur != stack->bottom) {

		printf("[%c]->", cur->data);
		cur = cur->next;
	}
	printf("[bottom]\n\n");
}

//*销毁一个结点
void DestoryNode(Node** node) {
	if (node == NULL) {
		return;
	}
	if (*node == NULL) {
		return;
	}
	free(*node);
	*node = NULL;
}

/*出栈一个元素*/
void LinkStackPop(LinkStack* stack) {

	if (stack == NULL) {
		return;
	}
	/*拆除栈顶结点*/
	Node* del_node = stack->top;
	stack->top = del_node->next;

	del_node->next = NULL;
	/*销毁结点*/
	DestoryNode(&del_node);
}

/*获取栈顶元素*/
StackType LinkStakGetTopValue(LinkStack* stack) {

	if (stack == NULL) {
		return;
	}
	StackType value = stack->top->data;

	return value;
}
/*销毁栈*/
void LinkStackDestory(LinkStack** stack) {

	if (stack == NULL) {
		return;
	}
	if (*stack == NULL) {
		return;
	}
	/*先销毁所有的结点*/
	Node* cur = (*stack)->top;
	while (cur != (*stack)->bottom) {
		/*销毁所有结点*/
		Node* del = cur;
		cur = cur->next;
		DestoryNode(&del);
	}
	/*销毁栈底结点*/
	DestoryNode(&(*stack)->bottom);
	/*销毁栈*/
	free(*stack);
	/*因为要把指针指为空,所以用的二级指针*/
	(*stack) = NULL;
}

/*
*两个栈实现一个队列
*/
/*压入元素操作和链表的一样,不写了*/
/*出队首元素*/
void QueuePop(LinkStack* stack1, LinkStack* stack2) {

	if (stack1 == NULL) {
		return;
	}
	if (stack2 == NULL) {
		return;
	}
	/*把栈1除栈底元素之外所有的元素压入栈2*/
	while (stack1->top->next != stack1->bottom) {
		/*把栈1的栈顶元素取出,然后销毁结点,然后压入栈2*/
		Node* del = stack1->top;
		StackType value = del->data;
		/*栈顶指针往下移*/
		stack1->top = del->next;
		DestoryNode(&del);

		/*压入栈2*/
		LinkStackPush(stack2, value);
	}
	/*现在栈1中只有一个元素*/
	Node* del_node = stack1->top;
	stack1->top = del_node->next;
	/*出队列首元素*/
	DestoryNode(&del_node);

	/*把栈2的元素压入栈1中*/
	while (stack2->top != stack2->bottom) {
		Node* del = stack2->top;
		StackType value = del->data;
		stack2->top = del->next;
		DestoryNode(&del);

		/*把取出的元素压入栈2*/
		LinkStackPush(stack1, value);
	}
	/*模拟队列出队首元素完成*/
}

/*获取队首元素*/
StackType QueueGetHead(LinkStack* stack1) {

	if (stack1 == NULL) {
		return;
	}
	Node* cur = stack1->top;
	while (cur->next != stack1->bottom) {
		cur = cur->next;
	}
	return cur->data;
}



test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include"NewQueue.h"

#define TESTHEAD printf("---------------%s---------------\n\n",__FUNCTION__);

void TestPush() {
	LinkStack* stack = InitStack();
	TESTHEAD;
	LinkStackPush(stack, 'a');
	LinkStackPush(stack, 'b');
	LinkStackPush(stack, 'c');
	LinkStackPush(stack, 'd');
	LinkStackPush(stack, 'e');

	PrintStack(stack, "压栈五个元素");

}

void TestPop() {
	LinkStack* stack = InitStack();
	TESTHEAD;
	LinkStackPush(stack, 'a');
	LinkStackPush(stack, 'b');
	LinkStackPush(stack, 'c');
	LinkStackPush(stack, 'd');
	LinkStackPush(stack, 'e');
	PrintStack(stack, "压栈五个元素");

	LinkStackPop(stack);
	LinkStackPop(stack);
	PrintStack(stack, "出栈两个元素");
}

void TestGetTopValue() {
	LinkStack* stack = InitStack();
	TESTHEAD;
	LinkStackPush(stack, 'a');
	LinkStackPush(stack, 'b');
	LinkStackPush(stack, 'c');
	LinkStackPush(stack, 'd');
	LinkStackPush(stack, 'e');
	PrintStack(stack, "压栈五个元素");

	StackType value = LinkStakGetTopValue(stack);

	printf("expect e, actual: %c", value);
}

void TestDestory() {
	LinkStack* stack = InitStack();
	TESTHEAD;
	LinkStackPush(stack, 'a');
	LinkStackPush(stack, 'b');
	LinkStackPush(stack, 'c');
	LinkStackPush(stack, 'd');
	LinkStackPush(stack, 'e');
	PrintStack(stack, "压栈五个元素");

	LinkStackDestory(&stack);
}

void TestQueuePop() {
	LinkStack* stack1 = InitStack();
	LinkStack* stack2 = InitStack();
	TESTHEAD;
	LinkStackPush(stack1, 'a');
	LinkStackPush(stack1, 'b');
	LinkStackPush(stack1, 'c');
	LinkStackPush(stack1, 'd');
	LinkStackPush(stack1, 'e');
	PrintStack(stack1, "模拟入队列五个元素");

	QueuePop(stack1, stack2);
	PrintStack(stack1, "模拟出队首元素");

	StackType value = QueueGetHead(stack1);
	printf("expect b, actual:%c\n\n", value);
}

int main() {
	TestPush();
	TestPop();
	TestGetTopValue();
	TestDestory();
	TestQueuePop();
	system("pause");
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值