【数据结构】-- 栈

引入:

一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。 进行数据插入和删除操作的一端 称为栈顶,另一端称为栈底。栈中的元素遵循先进后出的原则,先入栈的元素总是先后出栈。

压栈:栈的插入操作叫做进栈 / 压栈 / 入栈, 入数据在栈顶
出栈:栈的删除操作叫做出栈。 出数据也在栈顶

注意:入栈顺序是DCBA,出栈顺序不一定是ABCD,可以边入边出

所以,入栈顺序是DCBA ,出栈顺序有很多种。

栈的实现:

数组,单向链表,双向链表都能够实现栈:

数组:

单链表:

用单链表实现栈有一个问题,单链表不能回头,如图这么设计,在压栈之后,不方便出栈。

所以我们可以以开头作为栈顶,然后对链表头插来实现栈,出栈的时候使用头删。

双向链表:

双向链表可以通过前一个元素直接访问上一个元素,这使得在双向链表中实现栈的出栈功能更加高效和方便。因为双向链表可以从尾部直接访问到最后一个元素,从而实现了栈的后进先出(LIFO)特性。

由于CPU的高速缓存,在这里我们使用数组来实现栈 。

头文件:

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <assert.h>

typedef int STDataType;

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

void STInit(ST* pst);//初始化

void STDestory(ST* pst);//销毁

void STPush(ST* pst, STDataType x);//压栈

void STPop(ST* pst);//出栈

STDataType STTop(ST* pst);//获取栈顶的元素

bool STEmpty(ST* pst);//判断栈是否为空

int STSize(ST* pst);//判断栈里面有多少中数据(数据个数)

实现文件:

初始化栈的时候可以开辟空间也可以后面再开辟,在初始化top的时候有两种写法。

把top初始化为0:

这时,top指向栈顶元素的下一位

把top初始化-1:

这时,top指向栈顶元素。

不必过分在意top,无论top指向哪里,top只是一个数字,数据依然从栈顶开始存储。只不过,第一种方法有了第一个数据的时候top的值是1,第二种方法有了第一个数据时top的值为0。

在这里我们选择第一种写法。

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include "Stack.h"
//初始化
void STInit(ST* pst)
{
	assert(pst);
	pst->a = NULL;
	//top指向栈顶数据的下一个位置

	pst->capacity = 0;
	pst->top = 0;
	//top指向栈顶数据
	//pst->top = -1;


}
//销毁
void STDestory(ST* pst)
{
	assert(pst);
	free(pst->a);
	pst->a = NULL;
	pst->capacity = pst->top = 0;
}

//压栈
void STPush(ST* pst, STDataType x)
{
	assert(pst);
	//扩容
	if (pst->top == pst->capacity)
	{
		int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(pst->a, newcapacity * sizeof(STDataType));
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}
		pst->a = tmp;
		pst->capacity = newcapacity;
	}
	pst->a[pst->top] = x;
	pst->top++;
}

//出栈
void STPop(ST* pst)
{
	assert(pst);

	pst->top--;
}
//获取栈顶的元素
STDataType STTop(ST* pst)
{
	assert(pst);
	return pst->a[pst->top - 1];
}
//判断栈是否为空
bool STEmpty(ST* pst)
{
	assert(pst);
	return pst->top == 0;

}
//判断栈里面有多少中数据(数据个数)

int STSize(ST* pst)
{
	assert(pst);

	return pst->top;
}

测试文件:

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1


#include"Stack.h"


int main()
{
	ST s;
	STInit(&s);
	STPush(&s, 1);
	STPush(&s, 2);
	STPush(&s, 3);
	STPush(&s, 4);

	printf("%d \n", STTop(&s));


	//列出栈中元素

	while (!STEmpty(&s))
	{
		printf("%d ", STTop(&s));
		STPop(&s);
	}

	return 0;
}
相关推荐
1nullptr1 小时前
三次翻转实现数组元素的旋转
数据结构
TT哇1 小时前
【数据结构练习题】链表与LinkedList
java·数据结构·链表
A懿轩A2 小时前
C/C++ 数据结构与算法【栈和队列】 栈+队列详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·栈和队列
1 9 J3 小时前
数据结构 C/C++(实验五:图)
c语言·数据结构·c++·学习·算法
汝即来归3 小时前
选择排序和冒泡排序;MySQL架构
数据结构·算法·排序算法
aaasssdddd966 小时前
C++的封装(十四):《设计模式》这本书
数据结构·c++·设计模式
芳菲菲其弥章6 小时前
数据结构经典算法总复习(下卷)
数据结构·算法
yyyyyyykk6 小时前
数据结构--链表
数据结构·链表
我是一只来自东方的鸭.6 小时前
1. K11504 天平[Not so Mobile,UVa839]
数据结构·b树·算法
武昌库里写JAVA7 小时前
使用React Strict DOM改善React生态系统
数据结构·vue.js·spring boot·算法·课程设计