栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

数据结构 栈的结构特点及基本操作

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

数据结构 栈的结构特点及基本操作

栈的结构特点和操作

栈是限定只能在表的一端进行插入和删除的线性表,在表中,允许插入和删除的一端称为“栈顶”,不允许插入和删除的一端称为“栈底”。栈的元素进出是按照“先进后出,后进先出”的顺序进行。和线性表类似,栈也有两种存储方法顺序栈和链栈。

顺序栈

顺序栈是指利用顺序存储分配实现的栈。同时附设top指针指示栈顶元素在顺序栈中的位置。用一维数组来描述顺序栈中数据元素的存储区域,并预设一个最大的存储空间。对于top指针,由于数组的第一个元素的下标为0,所以初始化top=-1;表示是个空栈。输出栈内数据元素时,可以利用循环变量 i <= S.top;来输出。由于顺序栈的插入和删除只能在栈顶进行,所以顺序栈的一些相关操作比顺序表要简单的多。具体C语言实现代码如下:

#include

#define TRUE 1
#define FALSE 0

const int STACK_INIT_SIZE = 100;   //顺序栈默认的初始分配最大空间量
const int STACKINCREMENT = 10;     //默认的增补空间量
typedef struct {
	int *elem;             //存储数据的数组
	int top;              //栈顶指针
	int stacksize;         //当前分配的最大容量
	int incrementsize;     //约定的增补空间量
}SqStack;


void InitStack_Sq(SqStack &S, int maxsize = STACK_INIT_SIZE, int incresize = STACKINCREMENT)
{
	//构造一个空栈S,初始化分配的最大空间为maxsize,预设的增补空间量为incresize
	S.elem = new int[maxsize];        //为顺序栈分配最大容量为maxsize的数组空间
	S.top = -1;                       //顺序栈中当前所含元素个数为零
	S.stacksize = maxsize;            //该顺序栈可容纳maxsize个数据元素
	S.incrementsize = incresize;      //需要时每次扩容incresize个元素的空间
}


bool GetTop_Sq(SqStack S, int &e)
{
	//若栈不空,用e返回栈顶元素并返回TRUE,否则返回FALSE
	if (S.top == -1)
		return FALSE;
	e = S.elem[S.top];
	return TRUE;
}


void incrementStacksize(SqStack &S)
{
	int *a;
	a = new int[S.stacksize + S.incrementsize];
	for (int i = 0; i <=S.top; i++)
		a[i] = S.elem[i];
	delete[]S.elem;
	S.elem = a;
	S.stacksize = S.stacksize + S.incrementsize;
}

void Push_Sq(SqStack &S, int e)
{
	//插入元素e为新的栈顶元素
	if (S.top == S.stacksize - 1)
		incrementStacksize(S);       //若空间不够则扩容重新分配空间,类似于顺序表
	S.elem[++S.top] = e;
}


bool Pop_Sq(SqStack &S, int &e)
{
	//若栈不空,则删除S的栈顶元素,并用e返回其值,并返回TRUE,否则饭返回FALSE
	if (S.top == -1)
		return FALSE;
	e = S.elem[S.top--];
	return TRUE;
}


void main()
{
	int i;
	int e1;       //用于接收栈顶元素
	int e2 = 11;  //用于插入新的栈顶元素
	int e3;       //用于接收删除的栈顶元素
	SqStack S;
	InitStack_Sq(S);
	for (i = 0; i < 10; i++)
	{
		S.elem[i] = i + 1;
		S.top++;
	}
	printf("顺序栈中数据元素为:");
	for (i = 0; i <= S.top; i++)
		printf("%d ", S.elem[i]);
	printf("n");
	if (GetTop_Sq(S, e1))
		printf("返回此时栈顶元素为:%dn", e1);
	else
		printf("这是一个空栈。n");
	Push_Sq(S, e2);
	printf("插入新的栈顶元素后新栈的数据元素为:");
	for (i = 0; i <= S.top; i++)
		printf("%d ", S.elem[i]);
	printf("n");
	if (Pop_Sq(S, e3))
	{
		printf("删除的栈顶元素为%d,删除后的栈内数据元素为:",e3);
		for (i = 0; i <= S.top; i++)
			printf("%d ", S.elem[i]);
	}
	else
		printf("这是一个空栈。");
}
链栈

链栈是利用链式分配实现的栈。对于顺序栈,虽然在满员状态下可以重新分配空间扩容,但是也是不得已而为之,所以当无法预先估计栈可能达到的最大容量时,应该采用链栈更合适。链栈的结点结构和链表的结点结构相同,值得注意的是,链栈中指针的方向是从栈顶指向栈底。

同顺序栈一样,链栈相比于单链表来说操作也简单了不少。值得注意的是,对于需要用 e 返回数值的函数来说,定义函数时形参部分需要用 int &e;来表示。原因是函数是布尔类型的函数,若要让e的值改变,需要传地址进入函数,所以用&e。同时,对于链栈的赋值,可以用提前赋好值的数组,也可以用scanf函数进行赋值,本质上是不断调用 void Push_L(linkStack &S, int e) 插入函数。

#include
#define TRUE 1
#define FALSE 0


typedef struct LNode {
	int data;
	struct LNode *next;
}LNode, *linkStack;


void InitStack_L(linkStack &S)
{
	//创建一个空的链栈,即设栈顶指针为空
	S = NULL;
}

void Push_L(linkStack &S, int e)
{
	//在链栈的栈顶插入新的栈顶元素e
	LNode *p = new LNode;     //为新的栈顶元素分配结点
	p->data = e;
	p->next = S;              //插入新的栈顶元素
	S = p;                    //修改栈顶指针
}

bool Pop_L(linkStack &S, int &e)
{
	//若栈不空则删除栈顶元素,并用e返回其值,并返回TRUE,否则返回FALSE
	if (S)
	{
		LNode *p;
		p = S;
		S = S->next;    //修改栈顶指针
		e = p->data;    //返回栈顶元素
		delete p;       //释放结点空间
		return TRUE;
	}
	else
		return FALSE;
}

void main()
{
	int i;
	int e1;      //用来接收新插入的数据元素
	int e2;      //用来返回删除的栈顶元素
	int a[10] = { 1,2,3,4,5,6,7,8,9,10 };
	linkStack S;
	LNode *p;
	InitStack_L(S);
	for (i = 0; i < 10; i++)
	{
		e1 = a[i];
		Push_L(S, e1);
	}
	printf("此链栈的数据元素为:");
	for (p = S; p != NULL; p = p->next)
		printf("%d ", p->data);
	printf("n");
	if (Pop_L(S, e2))
	{
		printf("删除的栈顶元素为%d,删除后的栈内数据元素为:", e2);
		for (p = S; p != NULL; p = p->next)
			printf("%d ", p->data);
	}
	else
		printf("这是一个空栈。");

}

本笔记所依据的教材为严薇敏版的《数据结构及应用算法教程》

所引用的图片来源于华中师范大学云课堂

所有代码在Visual Studio 2017上均可正常运行

如有错误欢迎指出

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/291127.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号