【数据结构】_栈的结构与实现

目录

[1. 栈的相关概念与结构](#1. 栈的相关概念与结构)

[2. 栈的实现](#2. 栈的实现)

[2.1 栈实现的底层结构选择](#2.1 栈实现的底层结构选择)

[2.2 Stack.h](#2.2 Stack.h)

[2.3 Stack.c](#2.3 Stack.c)

[2.4 Test_Stack.c](#2.4 Test_Stack.c)


1. 栈的相关概念与结构

1、栈:一种特殊的线性表,只允许在固定的一端插入和删除数据;

允许进行数据插入和删除操作的一端称为栈顶,另一端称为栈底;

栈中的元素遵守后进先出LIFO(Last In First Out)的原则;

2、压栈:栈的插入操作叫做进栈、压栈、入栈。入数据在栈顶

3、出栈:栈的删除操作叫做出栈。出数据也在栈顶

2. 栈的实现

2.1 栈实现的底层结构选择

1、若采用数组实现栈,则可将数组头视为栈底,数组尾视为栈顶,出入栈都在数组尾进行操作。

2、++若采用单链表实现栈,则将链尾视为栈底,入栈利用头插实现,出栈利用头删实现++。

(若将链首视为栈底,入栈通过尾插实现,但出栈较为麻烦)

3、若采用双链表实现栈,则无论将哪端视为栈底,出栈、入栈等方法的实现都非常方便;

相较而言,数组、单链表的方式均可较为便利实现栈。相对而言数组的实现效果更优,数组在尾上插入数据的效率高且代价小。采用数组实现栈。

2.2 Stack.h

cpp 复制代码
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
typedef int STDataType;
typedef struct Stack {
	// 动态开辟数组
	STDataType* a;
	// top表示栈顶元素的下一个元素的下标
	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);

2.3 Stack.c

cpp 复制代码
#include"Stack.h"
// 初始化
void STInit(ST* pst) {
	assert(pst);
	pst->a = NULL;
	// top表示栈顶元素的下一个元素的下标
	pst->top = 0;
	// capacity表示栈内元素个数(等价于栈顶元素的下一个元素的下标)
	pst->capacity = 0;
}
// 销毁
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);
	// 判栈非空
	assert(pst->top>0);
	pst->top--;
}
// 获取栈顶数据
STDataType STTop(ST* pst) {
	assert(pst);
	assert(pst->top>0);
	return pst->a[pst->top - 1];
}
// 判空
bool STEmpty(ST* pst) {
	if (pst->top == 0) {
		return true;
	}
	return false;
	//return pst->top == 0;
}
// 获取栈元素个数
int STSize(ST* pst) {
	assert(pst);
	return pst->top;
}

2.4 Test_Stack.c

cpp 复制代码
#include"Stack.h"
int main() {
	ST st;
	STInit(&st);
	STPush(&st, 1);
	STPush(&st, 2);
	STPush(&st, 3);
	STPush(&st, 4);
	while (!STEmpty(&st)) {
		printf("%d ", STTop(&st));
		STPop(&st);
	}
	STDestory(&st);
	return 0;
}

注:在使用数组实现栈的方式中,定义栈时的top表示栈顶位置,关于top的具体含义与初始化、销毁、压栈、出栈等操作需要进行对应:

若top表示栈顶元素的下标,则初始化时(栈内无元素),top=-1,插入时在a[top++]处入栈元素;

若top表示栈顶元素的下一个元素的下标,则初始化时top为0,插入时在a[top]处入栈元素

(易有top表示栈顶元素下标,但将top初始化为0的错误写法,注意勿混淆)

相关推荐
小姚也要变强9 分钟前
结构体排序 C++ 蓝桥杯
数据结构·c++·算法·蓝桥杯
余辉zmh9 分钟前
【贪心算法篇】:“贪心”之旅--算法练习题中的智慧与策略(三)
数据结构·c++·算法·leetcode·贪心算法
小姚也要变强10 分钟前
后缀表达式 C++ 蓝桥杯 栈
数据结构·c++·算法·蓝桥杯
jukuya17 分钟前
java并发编程
java·开发语言
m0_7482468717 分钟前
java开发面试自我介绍模板_java面试自我介绍3篇
java·开发语言·面试
2401_8582861118 分钟前
C32.【C++ Cont】静态实现双向链表及STL库的list
开发语言·c++·链表
重生之我在20年代敲代码20 分钟前
【C++】STL——list的使用
开发语言·c++
幻想趾于现实1 小时前
C# Action和 Func的用法
开发语言·c#
低代码布道师1 小时前
家政预约小程序12服务详情
开发语言·javascript·低代码·小程序
鱼力舟2 小时前
【hot100】073矩阵置零
数据结构·算法·矩阵