数据结构(5)栈的介绍与代码实现(c语言)

栈与队列是两种重要的线性结构,也是两种特殊的线性结构。
从逻辑结构角度看,栈和队列是线性表;
从运算看,栈和队列的基本运算是线性表运算的子集,
所以栈与队列可以说是操作受限的线性表。

栈:一种特殊的线性表,它的插入和删除操作只允许在固定的同一端进行。其中允许进行数据操作的一端称为栈顶,另一个不被允许进行数据操作的端称为栈底;处于栈顶位置的元素成为栈顶元素;由于只允许在一端进行操作,所以先放入栈中的元素反而得最后才可以取出来,所以栈又称为先进后出的线性表。我们将不含任何元素的栈称为空栈。

在这里插入图片描述
和线性表一样,栈也有两种存储结构:顺序存储结构和链式存储结构。

顺序栈

顺序栈通常由一个一维静态数组和一个记录栈顶元素位置的变量组成。习惯上将栈底放在数组下标小的那端,顺序栈所有操作的时间复杂度为O(1)

顺序栈的代码实现
#define _CRT_SECURE_NO_WARNINGS 1

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

#define StackSize 5
typedef int DataType;

typedef struct SqStack
{
	DataType data[StackSize];  //保存栈中元素,元素的类型为DataType
	int top;   //栈指针,top的取值范围0~StackSize-1;top=-1表示栈空;top=StackSize-1表示栈满;top++表示进栈;top--表示出栈

}SqStack;

//初始化
void InitStack(SqStack &pst)//pst为引用型参数(C++)
{
	pst.top = -1;
}

//进栈:栈指针加1,将栈顶元素放进栈顶处
void Push(SqStack &pst, DataType x)
{
	if (StackSize-1 == pst.top)
	{
		printf("栈已满\n");
		return;
	}
	else {
		pst.top++;
		pst.data[pst.top] = x;
	}

}

//出栈:先将栈顶元素取出,然后将栈指针减一
DataType Pop(SqStack &pst)
{
	if (- 1 == pst.top)
	{
		printf("栈为空\n");
		return -1;
	}
	else {
		int x = pst.data[pst.top];
		pst.top--;
		return x;
	}
}

//查看栈顶元素:将栈指针top出的元素返回
DataType GetTop(SqStack st)
{
	if (-1 == st.top)
	{
		printf("栈为空\n");
		return -1;
	}
	else
		return st.data[st.top];
}

//判断栈是否为空
void StackEmpty(SqStack st)
{
	if (-1 == st.top)
	{
		printf("栈为空\n");
	}
	else
		printf("栈不为空\n");
}

//打印
void SeqListPrint(const SqStack st)
{
	int i = 0;
	for (i = 0; i < StackSize; i++)
	{
		printf("%d ", st.data[i]);
	}
	printf("\n");
}

void Test()
{
	SqStack s;
	SqStack& ps = s;
	InitStack(s);

	Push(ps, 1);
	Push(ps, 2);
	Push(ps, 3);
	Push(ps, 4);
	Push(ps, 5);
	SeqListPrint(s);

	printf("此时栈顶元素为:%2d\n", GetTop(s));

	printf("出栈元素为:%2d", Pop(ps));
	printf(",此时栈顶元素为:%2d\n", GetTop(s));
	printf("出栈元素为:%2d", Pop(ps));
	printf(",此时栈顶元素为:%2d\n", GetTop(s));
	
	StackEmpty(s);
}

int main()
{
	Test();
	system("pause");
	return 0;
}

结果展示:
在这里插入图片描述

链栈

采用链式存储结构的栈简称为链栈,结构与单链表类似。其中,单链表的第一个结点就是栈顶结点;栈底结点的next指向NULL;栈由栈顶指针唯一指定。因为链栈本身没有容量限制,故不存在栈满的情况。

链栈的代码实现

代码:

#define _CRT_SECURE_NO_WARNINGS 1

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

typedef int DataType;

typedef struct SListStack
{
	struct SListStack* next;  //指针域
	DataType data;  //存储节点数据

}SListStack;


//初始化
void InitStack(SListStack *&pst)//pst为引用型参数(C++),
{
	pst = NULL;//pst为栈顶指针
}

//进栈
void Push(SListStack *&pst, DataType x)//SListStack **pst
{
	SListStack *p = (SListStack*)malloc(sizeof(SListStack));//创建一个节点
	p->data = x;
	p->next = pst;//p->next = *pst;
	pst = p;//*p = p;
	
}

//出栈
DataType Pop(SListStack *&pst)
{
	if (pst == NULL)
	{
		printf("栈为空\n");
		return -1;
	}
	else {
		SListStack *cur = pst;
		int x = cur->data;
		pst = cur->next;
		free(cur);
		return x;
	}
}

//查看栈顶元素
DataType GetTop(SListStack *st)
{
	if (NULL == st)
	{
		printf("栈为空\n");
		return -1;
	}
	else
		return st->data;
}

//判断栈是否为空
void StackEmpty(SListStack *st)
{
	if (NULL == st)
	{
		printf("栈为空\n");
	}
	else
		printf("栈不为空\n");
}

//打印
void StackPrint(SListStack *st)
{
	SListStack *cur = st;
	for (; cur != NULL; cur = cur->next)
	{
		printf("%2d->", cur->data);
	}
	printf("NULL\n");
}



void Test()
{
	SListStack *s;
	SListStack*& ps = s;
	InitStack(ps);

	Push(ps, 1);
	Push(ps, 2);
	Push(ps, 3);
	Push(ps, 4);
	Push(ps, 5);
	StackPrint(s);

	printf("此时栈顶元素为:%2d\n", GetTop(s));

	printf("出栈元素为:%2d", Pop(ps));
	printf(",此时栈顶元素为:%2d\n", GetTop(s));
	printf("出栈元素为:%2d", Pop(ps));
	printf(",此时栈顶元素为:%2d\n", GetTop(s));

	StackEmpty(s);
}

int main()
{
	Test();
	system("pause");
	return 0;
}

结果展示:
在这里插入图片描述

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值