栈的操作实现(详细)

实际上是线性表的特例,限定在表尾进行插入或删除操作,表尾端称为栈顶,表头端称为栈顶,栈拥有后进先出的特点。

请添加图片描述

栈分为顺序栈链栈两种,的主要操作有:创建空栈、栈的判空、进栈、出栈、取栈顶元素等,下面逐一分析:

先介绍顺序栈:

**

顺序栈

栈的结构类型的定义

因为栈是线性表的特例,所有顺序栈有最大容量,以及栈顶指针,还有存放元素的起始指针(用于指向存放元素的位置)

typedef  int DataType;//类型声明
struct Stack
{
	DataType *elem;//存放元素起始指针
	int Max;//最大容量
	int top;//栈顶指针
};
typedef Struct Stack* SeqStack;//定义顺序栈的类型
  • **

创建空栈

类似于数组的声明,创建空栈就是为顺序栈分配预先定义的数组空间,并将栈顶指针top变量设置为-1。

SeqStack SetNullStack_Seq(int m)
{
	SeqStack stack=(SeqStack)malloc(sizeof(struct Stack));//申请空间
	if(stack!=NULL)
	{
		stack->elem=(int *)malloc(sizeof(int)*m);//申请m个节点空点
		if(stack->elem!=NULL)
		{
			stack->Max=m;
			stack->top=-1;
			return stack;
		}
		else
		{
			free(stack);
			return NULL;
		}
	}
	else
	{
		printf("Alloc failure");
		return NULL;
	}
}
  • **

栈的判空

顺序栈的判空即检查栈顶指定是否等于初始化的-1即可,如果是则为空栈,返回1,否则返回0。

int IsNullStack_seq(SeqStack stack)
{
	return (stack->top==-1);//检查栈顶指针
}
  • **

顺序栈入栈

顺序栈的入栈需要检查栈是否已经满,即栈顶指针是否已经达到最大值,进栈时要先修改栈顶指针,再将元素压入栈中。

void Push_seq(SeqStack stack,int x)
{
	if(stack->top==stack->Max-1)//检查栈顶指针
		printf("Overflow!\n");
	else
	{
		stack->top++;//修改栈顶指针
		stack->elem[stack->top]=x;//压入元素
	}
}
  • **

顺序栈出栈

出栈操作要检查栈是否为空,若不为空则修改栈顶指针。

void Pop_seq(SeqStack stack)
{
	if(IsNullStack_seq(stack))
		printf("Undelflow!\n")
	else
	{
		stop->top=stack->top-1;
	}
}
  • **

顺序栈取栈顶元素

需要先检查栈是否为空,若不为空则返回栈顶元素。

DataType Top_seq(SeqStack stack)
{
	if(IsNullStack_seq(stack))
		printf("Underflow!\n")
	else
		return stack->elem[stack->top];
}

有时候面对动态的存储问题,顺序栈往往不能满足我们的要求(因为顺序栈创建时指定了栈的最大存储空间),这时使用链栈就解决了顺序栈的不足,下面介绍链栈操作的实现方法:

链栈

链栈结构体类型

定义:链栈的节点包括数据域和指针域

请添加图片描述

typedef int DataType;
struct Node
{
	DataType data;//数据域
	struct Node *next;//指针域
};

typedef struct Node * PNode;//结点类型
typedef steuct Node *top;//栈顶类型
typedef struct Node *LinkStack;//链栈类型
  • **

链栈创建空栈

创建带有头结点的空链栈,需要申请结构空间并使top->next为空

ListStack SetNullStack_Link()
{
	LinkStack top=(LinkStack)malloc(sizeof(struct Node));//申请空间
	if(top!=NULL)
		top->next=NULL;
	else
		printf("Alloc failure");
	return top;//返回栈顶指针
}
  • **

链栈的判空

判空:链栈的判空只需要判断栈顶结点后继是否为空,为空则返回1,否则返回0。

int IsNullStack_Link(LinkStack top)
{
	if(top->next==NULL)
		return 1;
	else
		return 0;
}

链栈进栈

进栈:链栈的进栈操作首先要申请结点空间,然后进行数据域和指针域赋值,并修改top指针指向

void Push_Link(LinkStack top,DataType x)
{
	PNode p=(PNode)malloc(sizeof(struct Node));//申请结点空间
	if(p==NULL)
		printf("Alloc faliure");
	else
	{
		p->data=x;//数据域赋值
		p->next=top->next;//指针域赋值
		top->next=p;//修改栈顶
	}
}

链栈出栈

出栈:出栈首先要判断栈是否为空,不为空则修改栈顶指针,并释放结点空间

void Pop_Link(LinkStack top)
{
	PNode p;
	if(IsNullStack_Link(top))
		printf("It is empty stack");
	else
	{
		p=top->next;//p指向待删除的结点
		top->next=p->next;//修改栈顶指针
		free(p);//释放删除结点
	}
}

链栈取栈顶元素

取栈顶元素:首先判断栈是否为空,不为空则返回栈顶元素

DataType Pop_seq_return(LinkStack top)
{
	if(IsNullStack_Link(top))
		printf("It is empty stack!");
	else
		return top->next->data;
}

总结

总结:
栈的应用很广泛,通常被用作一种工具取解决数据结构的各类问题,常见的有:进制转换、括号匹配、迷宫、表达式求值、树的创建与遍历等等,感兴趣的可以看看一下几篇文章。

用栈实现进制转换

用栈实现迷宫问题的深度优先法

在这里插入图片描述

创作不易,支持一下呗q(≧▽≦q)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值