栈和队列详解(看这一篇就够了)!

文章介绍了栈和队列两种基本数据结构。栈是一种后进先出(LIFO)的数据结构,常使用数组或链表实现,文中提供了栈的初始化、压栈、出栈等操作的C语言代码实现。队列则是先进先出(FIFO)的数据结构,同样可以使用数组或链表实现,文中展示了队列的初始化、入队、出队等操作的实现代码。
摘要由CSDN通过智能技术生成

栈和队列

一、栈

1.栈的定义

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素的操作。进行数据插入和删除的一端为栈顶,另一端为栈底。

2.栈的特点

栈中的元素遵守后进先出(Last In First Out)、先进后出(First In Last Out)的原则。
压栈:栈的插入操作叫进栈/压栈/入栈,入数据在栈顶
出栈:栈的删除的操作叫出栈,出数据也在栈顶

在这里插入图片描述

3.栈的实现以及分析

栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上
插入数据的代价比较小。

代码如下

Stack.h
#pragma once
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <assert.h>

typedef int STDataType;

typedef struct Stack
{
	STDataType* a;
	int top;
	int Capacity;
}ST;

void StackInit(ST* ps);

void StackDestory(ST* ps);

void StackPush(ST* ps, STDataType x);

void StackPop(ST* ps);

void StackSize(ST* ps);

void StackTop(ST* ps);

void StackEmpty(ST* ps);

void StackPrint(ST*ps);

Stack.c
#include "Stack.h"

void StackInit(ST* ps)
{
	assert(ps);
	ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);
	if (ps->a == NULL)
	{
		printf("malloc fail.\n");
		exit(-1);
	}
	ps->Capacity = 4;
	ps->top = 0;
	printf("初始化成功\n");
	system("pause");
	system("cls");
}

void StackDestory(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a =NULL;
	printf("栈销毁成功\n");
	system("pause");
	system("cls");
}

void StackPush(ST* ps, STDataType x)
{
	assert(ps);
	if (ps->top == ps->Capacity)
	{
		STDataType* tep = realloc(ps->a, ps->Capacity * 2 * sizeof(STDataType));
		if (tep == NULL)
		{
			printf("realloc fail.\n");
			exit(-1);
		}
		else
		{
			ps->a = tep;
			ps->Capacity *= 2;
		}
	}
	ps->a[ps->top] = x;
	ps->top++;
	printf("入栈成功\n");
	system("pause");
	system("cls");
}

void StackPop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	ps->top--;
	printf("出栈成功\n");
}

void StackSize(ST* ps)
{
	assert(ps);
	printf("栈中有%d个数据\n", ps->top);
	system("pause");
	system("cls");
}

void StackTop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	printf("栈顶元素是:%d\n", ps->a[ps->top - 1]);
	system("pause");
	system("cls");
}

void StackEmpty(ST* ps)
{
	if (ps->top == 0)
		printf("栈为空\n");
	else
		printf("栈中还有:%d个数据\n", ps->top);
	system("pause");
	system("cls");
}

void StackPrint(ST* ps)
{
	assert(ps);
	assert(ps->top>0);
	while(ps->top!=0)
	{
		printf("%d ", ps->a[ps->top - 1]);
		ps->top--;
	}
	printf("\n");
	printf("打印成功\n");
	system("pause");
	system("cls");
}
Test.c
#include "Stack.h"

void WelcomeInfo()
{
	printf("\n\n");
	printf("    *******************************************\n");
	printf("    *          欢迎使用栈操作系统             *\n");
	printf("    *******************************************\n");
	printf("    *             请选择功能列表              *\n");
	printf("    *******************************************\n");
	printf("    *             1:初始化栈内信息           *\n");
	printf("    *             2:压栈                     *\n");
	printf("    *             3:出栈                     *\n");
	printf("    *             4:计算栈内数据个数         *\n");
	printf("    *             5:栈顶元素                 *\n");
	printf("    *             6:判断栈是否为空           *\n");
	printf("    *             7:销毁栈                   *\n");
	printf("    *             8:打印栈内信息             *\n");
	printf("    *             0:退出栈操作系统           *\n");
	printf("    *******************************************\n");
 }
int main()
{
	ST st;
	while (1)
	{
		// 清除输出
		system("cls");

		WelcomeInfo();
		printf("请输入数字:");
		char ch = getchar();
		switch (ch)
		{
		case '1':
			//初始化栈内信息
			StackInit(&st);
			break;
		case '2':
			//压栈
		{
			STDataType x = 0;
			printf("请输入进栈的数据:\n");
			scanf("%d", &x);
			StackPush(&st, x);
			break;
		}
		case '3':
			//出栈
			StackPop(&st);
			break;
		case '4':
		{
            //计算栈内数据个数
			StackSize(&st);
			break;
		}
		case '5':
		{
			//栈顶元素
			StackTop(&st);
			break;
		}
		case '6':
		{
			//判断栈是否为空
			StackEmpty(&st);
			break;
		}
		case '7':
		{
			//销毁栈
			StackDestory(&st);
			printf("销毁成功\n");
			break;
		}
		case '8':
		{
			//打印栈内信息
			StackPrint(&st);
			break;
		}
		case '0':
			//退出栈操作系统
			exit(0);
			break;
		default:
			break;
		}
	}

	return 0;
}

二、队列

1.什么是队列

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先
进先出FIFO(First In First Out)
入队列:进行插入操作的一端称为队尾
出队列:进行删除操作的一端称为队头

在这里插入图片描述

2.队列的特点(与栈对比)

特点:先进先出(First In First Out)
在这里插入图片描述

3.队列的实现以及分析

队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,
出队列在数组头上出数据,效率会比较低。
代码如下:

Queue.h
#pragma once
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>

typedef int QDataType;
typedef struct QueueNode
{
	struct QNode* next;
	QDataType data;
}QNode;

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

void QueueInit(Queue* qp);

void QueueDestory(Queue* qp);

void QueuePush(Queue* qp,QDataType x);

void QueuePop(Queue* qp);

QDataType QueueFront(Queue* qp);

QDataType QueueBack(Queue* qp);

int QueueSize(Queue* qp);

bool QueueEmpty(Queue* qp);

Queue.c
#include "Queue.h"


void QueueInit(Queue* qp)
{
	assert(qp);
	qp->head = qp->tail = NULL;
}

void QueueDestory(Queue* qp)
{
	assert(qp);
	QNode* cur = qp->head;
	while(cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	qp->head = qp->tail = NULL;
}

void QueuePush(Queue* qp, QDataType x)
{
	assert(qp);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		printf("malloc fail.\n");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;
	
	if (qp->tail == NULL)
	{
		qp->head = qp->tail = newnode;
	}
	else
	{
		qp->tail->next = newnode;
		qp->tail = newnode;
	}
	

}

void QueuePop(Queue* qp)
{
	assert(qp);
	assert(qp->head);
	if (qp->head->next == NULL)
	{
		free(qp->head);
		qp->head = qp->tail = NULL;
	}
	else
	{
		QNode* next = qp->head->next;
		free(qp->head);
		qp->head = next;
	}
}

QDataType QueueFront(Queue* qp)
{
	assert(qp);
	assert(qp->head);
	return qp->head->data;
}

QDataType QueueBack(Queue* qp)
{
	assert(qp);
	assert(qp->head);
	return qp->tail->data;
}

int QueueSize(Queue* qp)
{
	assert(qp);
	int size = 0;
	QNode* cur = qp->head;
	while (cur)

	{
		size++;
		cur = cur->next;
	}
	return size;
}

bool QueueEmpty(Queue* qp)
{
	assert(qp);
	return qp->head == NULL;
}

Test.c
#include "Queue.h"

int main()
{
	Queue q;
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 2);
	printf("%d ",QueueFront(&q));
	QueuePop(&q);
	printf("%d ", QueueFront(&q));
	QueuePop(&q);
    QueuePush(&q, 3);
	QueuePush(&q, 4);
	while (!QueueEmpty(&q))
	{
		printf("%d ", QueueFront(&q));
		QueuePop(&q);
	}
	printf("\n");

	QueueDestory(&q);
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值