顺序栈的讲解

堆栈(简称栈)是插入和删除操作都在表的同一端进行的线性表。运行插入和删除元素的一端称为栈顶(top),另一端称为栈底(bottom)。如果堆栈中没有元素,则为空栈。栈是一个后进后出的结构(Last In First Out),简称为LIFO结构。

有几点需要注意:
1.栈本质上还是线性表,只是这个线性表增加了新的限定规则,只能在一端进行插入和删除。
2.栈和线性表一样,也有顺序存储(顺序栈)和链式存储(链式栈)两种结构。
3.栈的插入叫进栈,栈的删除叫出栈

顺序栈

顺序栈是栈的顺序实现。顺序栈是指利用顺序存储结构实现的栈。采用地址连续的存储空间(数组)依次存储栈中数据元素。下面是顺序栈的示意图:
在这里插入图片描述

顺序栈有八个操作,分别是初始化,出栈,入栈,是否为空,是否为满,取栈顶元素,取有效元素个数,遍历。

先对堆栈结构体定义:

typedef struct//堆栈结构体定义
{
	int top;//栈顶指针
	int data[MaxSize];//静态数组存放栈中元素
}SqStack;

初始化

根据上面的示意图,初始化只需把栈顶指针指向-1就可以了。

void InitStack(SqStack &S)//初始化栈
{
	S.top = -1;//初始化栈顶指针
}

出栈

1.判断是否为空栈,空栈无法进行出栈操作。
2.先赋值给x再移动栈顶指针,并且是向下移动。

bool Printf(SqStack &S,int &x)//出栈(删除栈顶元素)
{
		if (S.top == -1)//判断是否为空栈
			return false;
		x = S.data[S.top];//让x等于此时栈顶指针所指的元素
		S.top = S.top - 1;//栈顶指针往下移动一位
	return true;
}

入栈

1.判断是否为栈满,栈满无法进行入栈操作。
2.栈顶指针先向上移动,再把输入的数据放进去。

bool Push(SqStack &S)//入栈(在栈顶位置插入元素)
{
	printf("请输入%d个数:", MaxSize);
	for (int i = 0; i < MaxSize; i++)
	{
		if (S.top == MaxSize - 1)//判断栈满了没有
			return false;
		S.top = S.top + 1;//栈顶指针往上移动一位
		scanf("%d", &S.data[S.top]);//把这次输入的元素放入此时栈顶指针指向的位置
	}
		return true;
}

判断栈空

只需要判断栈顶指针指向的是不是-1,因为一开始空栈的时候栈顶指针指向的是-1。

int testStack(SqStack &S)//判断栈空
{
	return (S.top == -1);//空栈返回1,反之返回0。
}

判断栈满

由于栈顶指针指向的是-1,所以一开始放入的位置是0,栈满的时候就会是MaxSize-1,只需判断栈顶指针指向的是不是MaxSize-1就好了。

int IsFull(SqStack &S)//判断栈满
{
	return (S.top == MaxSize-1);//满栈返回1,反之返回0。
}

取栈顶元素

取栈顶元素的操作和一次出栈类似,但是不需要进行栈顶指针的移动。

bool GetTop(SqStack &S)//读取栈顶元素,操作和出栈类似,top不需要减1。
{
	if (S.top == -1)//判断空栈
		return false;
	int x = S.data[S.top];
	printf("栈顶元素是:%d\n", x);
	return true;
}

取有效元素个数

由上面的效果图可知,栈顶指针+1就可以了。

int lenth(SqStack &S)//求有效元素的个数
{
	return S.top + 1;
}

遍历

遍历是进行多次的出栈操作,并把每次出栈的数据打印出来。给出栈操作加上循环和输出即可。

全部代码:

#define _CRT_SECURE_NO_WARNINGS 
#define MaxSize 5
#include<stdio.h>

typedef struct//堆栈结构体定义
{
	int top;//栈顶指针
	int data[MaxSize];//静态数组存放栈中元素
}SqStack;

void InitStack(SqStack &S)//初始化栈
{
	S.top = -1;//初始化栈顶指针
}

int testStack(SqStack &S)//判断栈空
{//只需要判断栈顶指针指向的是不是-1,因为一开始空栈的时候栈顶指针指向的是-1。
	return (S.top == -1);//空栈返回1,反之返回0。
}

int IsFull(SqStack &S)//判断栈满
{
	return (S.top == MaxSize-1);//满栈返回1,反之返回0。
}

bool Push(SqStack &S)//入栈(在栈顶位置插入元素)
{
	printf("请输入%d个数:", MaxSize);
	for (int i = 0; i < MaxSize; i++)
	{
		if (S.top == MaxSize - 1)//判断栈满了没有
			return false;
		S.top = S.top + 1;//栈顶指针往上一位
		scanf("%d", &S.data[S.top]);//把这次输入的元素放入此时栈顶指针指向的位置
	}
		return true;
}

bool GetTop(SqStack &S)//读取栈顶元素,操作和出栈类似,top不需要减1。
{
	if (S.top == -1)
		return false;
	int x = S.data[S.top];
	printf("栈顶元素是:%d\n", x);
	return true;
}

int lenth(SqStack &S)//求有效元素的个数
{
	return S.top + 1;
}

bool Printf(SqStack &S,int &x)//出栈(删除栈顶元素)
{
		if (S.top == -1)//判断是否为空栈
			return false;
		x = S.data[S.top];//让x等于此时栈顶指针所指的元素
		S.top = S.top - 1;//栈顶指针往下移动一位
	return true;
}

void DestroyStack(SqStack &S)//销毁栈
{
	char a;
	getchar();
	printf("是否销毁顺序栈(Y/N):");
	scanf("%c", &a);
	if (a == 'Y')
	{
		printf("销毁成功\n");
		S.top = -1;
	}
	else
		printf("未销毁\n");
}

int main()
{
	int x;
	SqStack S;//声明栈
	InitStack(S);//初始化栈
	Push(S);//入栈
	int a=testStack(S);//判断栈空
	a == 1 ? printf("栈空\n") : printf("栈不是空的\n");
	a = IsFull(S);
	a == 1 ? printf("栈满\n") : printf("栈不满\n");
	GetTop(S);//读取栈顶元素
	int len = lenth(S);
	printf("栈内元素个数:%d\n", len);
	Printf(S,x);//出栈
	DestroyStack(S);//销毁栈
	return 0;
}



输出结果:
在这里插入图片描述

如果有什么不懂的,文中有错误的可以私信联系我,非常感谢。

觉得这篇博客对你有帮助的话可以点个赞呀。

  • 18
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
您好,我可以为您解答关于使用C语言顺序栈实现十进制转换为二进制、八进制和十六进制的问题。 首先,您需要一些基本的知识。十进制是我们平常使用的数字系统,有 0~9 一共 10 个数字。二进制是计算机使用的数字系统,只有 0 和 1 两个数字。八进制是由 0~7 八个数字组成的数字系统,十六进制是由 0~9 和 A~F 共 16 个数字组成的数字系统。 现在,我们开始讲解如何实现十进制转换为其他进制: 1. 二进制转换 首先,我们可以使用除 2 取余法来实现十进制转换为二进制。具体步骤如下: 1) 初始化一个顺序栈,将十进制数依次入栈; 2) 然后反转栈中的元素,依次出栈,并将该元素除以二的余数压入新的栈中; 3) 直到取完最后一个元素,将栈中所有元素出栈并输出即可。 下面是示例代码: void DecToBin(int dec) { int rem; SeqStack S; InitStack(&S); while (dec) { Push(&S, dec % 2); dec /= 2; } while (!StackIsEmpty(S)) { Pop(&S, &rem); printf("%d", rem); } } 2. 八进制转换 我们可以使用除 8 取余法来实现十进制转换为八进制。具体步骤如下: 1) 初始化一个顺序栈,将十进制数依次入栈; 2) 然后反转栈中的元素,依次出栈,并将该元素除以八的余数压入新的栈中; 3) 直到取完最后一个元素,将栈中所有元素出栈并输出即可。 示例代码如下: void DecToOct(int dec) { int rem; SeqStack S; InitStack(&S); while (dec) { Push(&S, dec % 8); dec /= 8; } while (!StackIsEmpty(S)) { Pop(&S, &rem); printf("%d", rem); } } 3. 十六进制转换 我们可以将十进制数转换为二进制数,然后将二进制数每 4 位一组转换为对应的十六进制数字。具体步骤如下: 1) 先调用上面的十进制转二进制的函数 DecToBin(int dec) 来得到该十进制数对应的二进制数; 2) 然后将得到的二进制数每 4 位一组,将每组的二进制数转换为对应的十六进制数字; 3) 最后将多个十六进制数字拼接起来即可。 示例代码如下: void DecToHex(int dec) { int bin[100], hex[100], i = 0, j, n; char hex_char[16] = "0123456789ABCDEF"; SeqStack S; InitStack(&S); while (dec) { Push(&S, dec % 2); dec /= 2; } while (!StackIsEmpty(S)) { Pop(&S, &bin[i++]); } n = ceil((double)i / 4); for (j = 0; j < n * 4; ++j) { if (j < i) { hex[j / 4] <<= 1; hex[j / 4] |= bin[i - j - 1]; } else { hex[j / 4] <<= 1; } } for (j = n - 1; j >= 0; --j) { printf("%c", hex_char[hex[j]]); } } 希望可以帮到您,如有疑问请随时问我。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值