数据结构的奇妙冒险(C语言版)——线性结构(中)

目录

四、堆栈

1、定义

2、堆栈的抽象数据类型描述

 五、栈的顺序存储实现

1、定义结构体

2、入栈

3、出栈 

4、例子

 六、堆栈的链式存储实现

1、定义结构体

2、创建堆栈头结点

3、判断是否为空栈

4、入栈

5、出栈

6、堆栈的应用


四、堆栈

1、定义

        具有一定操作约束的线性表

特点:

        (1)只在一端(栈顶,Top)做插入,删除

        (2)插入数据:入栈(Push)

        (3)删除数据:出栈(Pop)

        (4)先入后出:Last In First Out(LIFO)

2、堆栈的抽象数据类型描述

类型名称:堆栈(Stack)

数据对象集:一个有0个或者多个元素的有穷线性表

操作集:长度为MaxSize的堆栈S\epsilonStack,堆栈元素item\epsilonElementType

Stack CreateStack(int MaxSize);//生成空堆栈,其最大长度为MaxSize
int IsFull(Stack S,int MaxSize);//判断堆栈S是否已满
void Push(Stack S,ElementType item);//将元素item压入堆栈
int IsEmpty(Stack S);//判断堆栈是否为空
ElementType Pop(Stack S);//删除并返回栈顶元素

 五、栈的顺序存储实现

        栈的顺序存储结构通常由一个一维数组和一个记录栈顶元素位置的变量组成

1、定义结构体

#define MaxSize 100//<存储数据元素的最大值>
typedef struct SNode *Stack;
struct SNode
{
	ElementType Data[MaxSize];
	int Top; //栈顶的数组下标位置 
};

2、入栈

//入栈 
void Push(Stack PtrS,ElementType item)
{
	if(PtrS->Top==MaxSize-1)
	{
		printf("堆栈满");
		return; 
	}
	else 
	{
		PtrS->Data[++(PtrS->Top)]=item;
		return;
	}
}

3、出栈 

//出栈
ElementType Pop(Stack PtrS)
{
	if(PtrS->Top==-1)
	{
		print("堆栈空");
		return ERROR; //ERROR可以是ElementType的特殊值,用于标志错误 
	}
	else 
		return (PtrS->Data[(Ptrs->Top)--]);
 } 

4、例子

        使用一个数组实现两个堆栈,要求最大化利用数组空间,使得数组只要有空间入栈操作就可以成功。

解决方法:使两个栈分别从数组两头开始,当两个栈的栈顶相遇时,表示两个栈都满了

#include <iostream>

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

#define MaxSize 100//<存储数据元素的最大值>
typedef struct DStack *Stack;
struct DStack
{
	ElementType Data[MaxSize];
	int Top1; //堆栈1栈顶的数组下标位置 
	int Top2;//堆栈2栈顶的数组下标位置 
}S;
S.Top1=-1;
S.Top2=MaxSize;

int main(int argc, char** argv) {
	return 0;
}
//入栈 
void Push(Stack PtrS,ElementType item,int Tag)
{
	if(PtrS->Top2-PtrS->Top1==1)
	{
		printf("堆栈满");return ;		
	}
	if(Tag==1)
	{
		PtrS->Data[++(PtrS->Top1)]=item;
	}
	else 
	{
		PtrS->Data[--(PtrS->Top2)]=item;
	}
}
//出栈
ElementType Pop(Stack PtrS,int Tag)
{   //Tag用于区分两个堆栈的标志,取值为1、2 
	if(Tag==1) //对第一个堆栈操作 
	{
		if(PtrS->Top1==-1)//堆栈1空 
		{
			printf("堆栈1空");return NULL; 
		}
		else return PtrS->Data[(PtrS->Top1)--];//返回栈顶1元素 
	}
	else if(Tag==2)//对第二个堆栈操作 
	{
		if(PtrS->Top2==MaxSize)//堆栈2空 
		{
			printf("堆栈2空");return NULL: 
		}
		else return PtrS->Data[(PtrS->Top2)++];//返回栈顶2元素 
	}
	else 
	{
		printf("堆栈序号选择错误");return NULL; 
	}
 } 

 六、堆栈的链式存储实现

        栈的链式存储结构实际上是一个单链表,叫做链栈。插入和删除操作只能在链栈的栈顶进行。栈顶指针一定得是链表的表头,在表头位置插入或者删除结点。

1、定义结构体

typedef struct SNode *Stack;
struct SNode
{
	ElementType Data;
	struct SNode *Next;
};

2、创建堆栈头结点

Stack CreateStack()
{
	Stack S;
	S=(Stack)malloc(sizeof(struct SNode));//创建一个堆栈头结点,返回指针 
	S->Next=NULL:
	return S;
}

3、判断是否为空栈

int IsEmpty(Stack S)
{
	return (S->Next==NULL);//判断堆栈S是否为空,若为空,函数返回整数1,否则返回0 
}

4、入栈

void Push(ElementType item,Stack S)
{
	//将元素item压入堆栈S 
	Stack Tmpcell;
	Tmpcell=(Stack)malloc(sizeof(struct SNode));
	Tmpcell->Data=item;
	Tmpcell->Next=S->Next
	s->Next=Tmpcell;
} 

5、出栈

ElementType Pop(Stack S)
{
	struct SNode *FirstCell;
	ElementType TopElem;
	if(IsEmpty(s))//判断是否为空栈
	{
		printf("堆栈空");
		return NULL; 
	}
	else
	{
		FirstCell=S->Next;
		S->Next=FirstCell->Next;
		TopElem=FirstCell->Data;
		free(FirstCell);
		return TopElem;
	}
 } 

6、堆栈的应用

        ① 应用堆栈实现后缀表达式求值的基本过程

        ②将中缀表达式转换为后缀表达式

        ③函数调用以及递归实现

        ④深度优先搜索

        ⑤回溯算法


数据结构的奇妙冒险持续更新中~

要是文章有帮助的话

就点赞收藏关注一下啦!

感谢大家的观看

欢迎大家提出问题并指正~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IC 1396

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值