【数据结构和算法】 - 栈

学习目标:

  • 栈的设计和实现

栈的特点:后进先出。

学习内容:

一、栈的头文件

#pragma once

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>

typedef int STDataType;
//#define MAX 10
//typedef struct Stack
//{
    
    
//	STDataType a[MAX];//数组,静态栈
//	int top;//栈顶的位置,即栈顶的下标
//}ST;
typedef struct Stack
{
    
    
	STDataType* a;//指针a,用来维护动态数组栈
	int top;//既表示栈的当前元素个数,又表示当前栈顶的位置,即栈顶的下标
	//当表示栈的元素个数时,范围:top >= 0,当top>0表示栈不为空
	//当表示栈顶的位置时,范围:[0,top-1] 
	int capacity;//动态数组栈的容量
}ST;


//栈顶:栈的第一个元素的位置

//数组栈初始化
void StackInit(ST* ps);
//数组栈销毁
void StackDestroy(ST* ps);
//数组栈(顶)的插入
void StackPush(ST* ps, STDataType x);
//数组栈(顶)的删除
void StackPop(ST* ps);
//获取栈顶的数据
STDataType StackTop(ST* ps);
//数组栈的大小
int StackSize(ST* ps);
//判断栈是否为空
bool StackEmpty(ST* ps);

注意:利用动态数组实现栈的结构


二、代码实现
1、void StackInit(ST* ps);数组栈初始化

//形参不会影响实参,传实参的地址,形参就能改变实参
//方式1:
void StackInit(ST* ps)
{
    
    
	assert(ps);
	ps->a = NULL;
	ps->top = 0;//初始top = 0,表示top指向栈顶数据的下一个,即先放数据再++。初始top = -1.表示top指向栈顶数据,即先++再放数据
	ps->capacity = 0;
}
//方式2:
void StackInit(ST* ps)
{
    
    
	assert(ps);
	ps->a = (STDataType*)malloc(sizeof(STDataType)*4);
	if (ps->a == NULL)
	{
    
    
		printf("malloc failed\n");
		exit(-1);
	}
	ps->top = 0;
	//top = 0,表示top指向栈顶数据的下一个,即先放数据再++。
	//如;top=1,则top-1是栈顶
	//top = -1.表示top指向栈顶数据,即先++再放数据
	//如;top=1,则top是栈顶
	ps->capacity = 4;
}

2、void StackPush(ST* ps, STDataType x);数组栈(顶)的插入

//方式1:
void StackPush(ST* ps, STDataType x)
{
    
    
	assert(ps);
	if (ps->top == ps->capacity)//满了,扩容
	{
    
    
		int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		STDataType* tmp = realloc(ps->a, sizeof(STDataType) * newCapacity);
		if (tmp == NULL)
		{
    
    
			printf("realloc failed\n");
			exit(-1);
		}
		ps->a = tmp;
		ps->capacity = newCapacity;
	}
	ps->a[ps->top] = x;
	ps->top++;
}
//方式2:
void StackPush(ST* ps, STDataType x)
{
    
    
	assert(ps);
	if (ps->top == ps->capacity)//满了,扩容
	{
    
    
		STDataType* tmp = realloc(ps->a, sizeof(STDataType) * (ps->capacity * 2));
		if (tmp == NULL)
		{
    
    
			printf("realloc failed\n");
			exit(-1);
		}
		ps->a = tmp;
		ps->capacity = ps->capacity * 2;
	}
	ps->a[ps->top] = x;
	ps->top++;
}

3、void StackDestroy(ST* ps);数组栈销毁

void StackDestroy(ST* ps)
{
    
    
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->capacity = ps->top = 0;
}

4、void StackPop(ST* ps);数组栈(顶)的删除

void StackPop(ST* ps)
{
    
    
	assert(ps);
	//当栈顶没有数据,栈空了,不能再删除栈顶的数据,下标越界
	//assert(ps->top > 0);相当于assert(!StackEmpty(ps));
	assert(!StackEmpty(ps));
	ps->top--;
}

5、STDataType StackTop(ST* ps);获取栈顶的数据

STDataType StackTop(ST* ps)
{
    
    
	assert(ps);
	//当栈顶没有数据,栈空了,不能再获取栈顶的数据,否则非法访问
	//assert(ps->top > 0);相当于assert(!StackEmpty(ps));
	assert(!StackEmpty(ps));
	return ps->a[ps->top - 1];
	//当top初始化为0,则return ps->a[ps->top - 1];
	//当top初始化为-1,则return ps->a[ps->top];
}

6、int StackSize(ST* ps);数组栈的大小

int StackSize(ST* ps)
{
    
    
	assert(ps);
	return ps->top;//top既是栈的栈顶下标的前一个,也是栈的大小
}

7、bool StackEmpty(ST* ps);判断栈是否为空

bool StackEmpty(ST* ps)
{
    
    
	assert(ps);
	/*if (ps->top == 0)
	{
		return true;
	}
	else
	{
		return false;
	}*/
	return ps->top == 0;
}

三、代码测试

#define _CRT_SECURE_NO_WARNINGS 1

#include "Stack.h"

void TestStack()
{
    
    
	ST st;
	StackInit(&st);
	StackPush(&st, 1);
	StackPush(&st, 2);
	StackPush(&st, 3);
	StackPush(&st, 4);

	StackPop(&st);
	StackPop(&st);
	StackPop(&st);
	StackPop(&st);
	//StackPop(&st);//栈为空,继续删除,报错
	
	StackDestroy(&st);
}
//后进先出
void TestStack()
{
    
    
	ST st;
	StackInit(&st);
	StackPush(&st, 1);
	StackPush(&st, 2);
	StackPush(&st, 3);
	StackPush(&st, 4);

	printf("%d ", StackTop(&st));
	StackPop(&st);
	printf("%d ", StackTop(&st));
	StackPop(&st);

	StackPush(&st, 5);
	StackPush(&st, 6);

	//栈的遍历
	//先打印当前栈顶的数据,再删除栈顶的数据。
	while (!StackEmpty(&st))
	{
    
    
		printf("%d ", StackTop(&st));
		StackPop(&st);
	}
	printf("\n");//4 3 6 5 2 1
	//队列的数据是相对位置
	
	StackDestroy(&st);
}
int main()
{
    
    
	TestStack();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_48163964/article/details/130135843
今日推荐