顺序栈实现:空栈构造、销毁栈、清空栈、检测栈是否为空、返回栈元素个数、访问栈顶元素、插入栈顶元素、删除栈顶元素并返回其值、从栈底到栈顶依此访问栈元素九大功能的解决方案

   为了清楚的为读者展示每个功能模块如何实现,分得很细,以致有一些功能模块的运行结果要组合起来展示:比如说栈先初始化后才能插入元素(直接插也可以),但删除元素,和返回栈顶元素等需要先插入栈元素运行效果才能展现得更具体,当然,选择不同的功能选项,不插入栈元素也会有相应的输出;

  作此说明是想告诉读者后面的运行结果展示可能会有点乱,当然每次结果输出上都会有文字标识

文末有完整代码

一、面板功能初始化

<1>.c文件对操作界面的初始化代码展示:

printf("选择你想实现的功能:\n");
printf("*-----------------------------------------------------------------------------------------*\n");
printf("**1:构造空栈        **\t\t"); printf("2:销毁栈                  **\t"); printf("3:清空栈                **\t\n");
printf("**4:检测栈是否为空栈**\t\t"); printf("5:返回栈元素个数          **\t"); printf("6:返回栈顶元素          **\t\n");
printf("**7:插入栈顶元素    **\t\t"); printf("8:删除栈顶元素,并返回其值**\t"); printf("9:从底到顶依此访问栈元素**\t\n");
printf("**10:退出           **                                                                   **\n");
printf("*-----------------------------------------------------------------------------------------*\n");

<2>运行结果展示:

二、.c文件对变量的定义以及对函数的引用

int Choice = 0, Ele = 0;
SqStack s = { NULL };
while (1)
{
	printf("输入功能序号:\n");
	scanf_s("%d", &Choice);
	if ((Choice > 10) || (Choice <= 0))
		printf("输入非法,请重新选择!!\n");
	switch (Choice)
	{
	case 1:
		InitStack(&s);
		break;
	case 2:
		DestroyStack(&s);
		break;
	case 3:
		ClearStack(&s);
		break;
	case 4:
		StackEmpty(&s);
		break;
	case 5:
		StackLength(&s);
		break;
	case 6:
		GetTop(&s);
		break;
	case 7:
		Push(&s);
		StackTraverse(&s);//遍历栈元素
		break;
	case 8:
		Ele = Pop(&s);
		printf("删除的栈顶元素为:%d\n", Ele);
		break;
	case 9:
		StackTraverse(&s);
		break;
	case 10:
		exit(0);
		break;
	}

三、.h文件对标准库的引用以及对顺序栈的表示 

#pragma once
#include<stdio.h>
#include<stdlib.h> 
#define Maxsize 25//顺序栈存储空间的初始分配量
typedef int SElemType;
//顺序栈的表示
typedef struct
{
	SElemType* base;//栈底指针
	SElemType* top;//栈顶指针
	int stacksize;//栈可用的最大容量
}SqStack;

四、构造空栈InitStack函数的定义

<1>代码展示

//顺序栈的初始化
int InitStack(SqStack *S)
{
	S->base = (SElemType*)malloc(sizeof(SElemType));//为顺序表分配一个最大容量为Maxsize的数组
	if (!S->base)//存储分配失败
		exit(0);
	else
		printf("成功初始化\n");
	S->top = S->base;//top初始为base
	S->stacksize = Maxsize;

	return true;
}

<2>运行结果展示

前三次选择超范围,提示非法输入;第四次合法输入,成功初始化;

 五、销毁栈DestroyStack函数的定义

<1>代码展示

//销毁栈
int DestroyStack(SqStack* S)
{
	free(S->base);//释放栈底元素的空间
	S->base = NULL;//并将栈底和栈顶的指针同时指向NULL
	S->top = NULL;
	S->stacksize = 0;//栈可用的最大容量赋值为0
	if (S->base == NULL)
	{
		printf("栈销毁成功!\n");
		return true;
	}
	else
	{
		printf("栈销毁失败!!\n");
		return false;
	}
}

<2>运行结果展示

第一次输入:1构造空栈    第二次输入:2销毁栈,成功销毁  第三、四次输入:7插入两个栈元素33 22  第五次输入:9从栈底到栈顶访问栈元素

六、 清空栈ClearStack函数的定义

<1>代码展示

//清空栈
int ClearStack(SqStack* S)
{
	if (S->top == S->base)//两者地址相同
		return true;
	else
	{
		while (S->base < S->top)//因为顺序栈是地址连续的存储单元所以可以比较地址的大小
		{
			S->top--;//地址减减直到S->top的地址等于S->base的地址
		}
		if(S->top==S->base)
		{
			printf("成功清除\n");
			return true;
		}
		else 
		{
			printf("清除失败!!");
			return false;
		}
	}

}

<2>运行结果展示

  第一次输入:1构造栈  第二、三次输入:7插入栈元素33 22  第四次输入:3请空栈  第五次输入:4检测栈是否为空  因为清空了栈所以为空

 七、检测StackEmpty函数的定义

<1>代码展示

//检测栈是否为空
int StackEmpty(SqStack* S)
{
	if (S->top == S->base)
	{
		printf("空栈!!\n");
		return false;
	}
	else
	{
		printf("非空栈!!\n");
		return true;
	}
}

<2>运行结果展示

第一次输入:构造空栈  第二次输入:检测栈是否为空  第三次:插入栈元素 第四次:检测栈元素是否为空

八、 检测StackLength函数的定义

<1>代码展示

//返回栈元素个数
int StackLength(SqStack* S)
{
	printf("元素个数为:%d\n", S->top-S->base);//S->top在元素的上一个地址,S->top-S->base正好会等于栈元素个数
	return true;
}

<2>运行结果

第一次输入:构造空栈  第二次输入:返回栈元素个数  第三四次:插入栈元素  第五次:返回元素个数

九、 检测GetTop函数的定义

<1>代码展示

//返回栈顶元素
int GetTop(SqStack *S)
{
	if (S->top == S->base)
	{
		printf("为空栈,不存在元素\n");
		return false;
	}
	else
	{
		printf("栈顶元素为:%d\n", *(S->top - 1));//通过指针读取地址的数据
		return true;
	}
}

<2>运行结果

第一次:构造链表  第二次:6返回栈顶元素  第三四次:7插入栈元素  第五次:6返回栈顶元素

十、 检测Push函数的定义

<1>代码展示

//插入栈顶元素
int Push(SqStack* S)
{
	int Element=0;
	if ((S->top - S->base) >= S->stacksize)//此时栈最大可用容量已满
	{
		S->base = (SElemType*)realloc(S->base, S->stacksize + 20 * sizeof(int));
		if(S->base==NULL)
		return false;
			S->top = S->base + S->stacksize;
			S->stacksize += 20 * sizeof(int);
	}
		printf("输入你想添加的元素:\n");
		scanf_s("%d", &Element, sizeof(Element));
		*S->top++ = Element;//等效于下面的语句
		//*S->top=e;
		//S->top++;
		return true;
	
}

<2>运行结果展示

前面用到很多次,也为了避免篇幅过长,就不展示了

十一、 检测Pop函数的定义

<1>代码展示

//删除栈顶元素并返回值
int Pop(SqStack* S)
{
	int e = 0;
	if (S->top == S->base)
	{
		printf("空栈!!没有可以删除的元素\n");
	}
	else
	{
		e = *--S->top;
	}
	return e;
}

 <2>输出结果展示

第一次:初始化  第二次:8删除空栈栈顶元素 第四五六:插入 33 22 61  第七次:8删除栈顶元素  第八次:9遍历栈元素

十二、 检测StackTraverse函数的定义

<1>代码展示

//从底到顶依此访问栈元素
int StackTraverse(SqStack* S)
{
	int* p = S->base;//定义一个指针变量指向栈底
	if (S->top == S->base)//如果栈底和栈顶存储地址相同即为空栈
	{
		printf("空栈!!\n");
		return false;
	}
	else
	{
		printf("栈元素为:");
		while (p <= S->top-1)//p地址从S->base一直向上移动直到移动到S->top-1
		{//S->top总是指向栈顶元素的上一个
			printf("%d\t", *p);//p为指针类型
			p++;//地址上移
		}
		printf("\n");
		return true;
	}
}

<2>结果展示

第一次:构造空栈  第二次:遍历空栈  第三四次:7插入栈顶元素  第五次:遍历打印栈元素;

其实我们在每次插入完成的时候都使用了访问栈的StackTraverse函数

十二、完整代码展示 

<1>.c

#include"Module.h"
int main()
{
	printf("选择你想实现的功能:\n");
	printf("*-----------------------------------------------------------------------------------------*\n");
	printf("**1:构造空栈        **\t\t"); printf("2:销毁栈                  **\t"); printf("3:清空栈                **\t\n");
	printf("**4:检测栈是否为空栈**\t\t"); printf("5:返回栈元素个数          **\t"); printf("6:返回栈顶元素          **\t\n");
	printf("**7:插入栈顶元素    **\t\t"); printf("8:删除栈顶元素,并返回其值**\t"); printf("9:从底到顶依此访问栈元素**\t\n");
	printf("**10:退出           **                                                                   **\n");
	printf("*-----------------------------------------------------------------------------------------*\n");
	int Choice = 0, Ele = 0;
	SqStack s = { NULL };
	while (1)
	{
		printf("输入功能序号:\n");
		scanf_s("%d", &Choice);
		if ((Choice > 10) || (Choice <= 0))
			printf("输入非法,请重新选择!!\n");
		switch (Choice)
		{
		case 1:
			InitStack(&s);
			break;
		case 2:
			DestroyStack(&s);
			break;
		case 3:
			ClearStack(&s);
			break;
		case 4:
			StackEmpty(&s);
			break;
		case 5:
			StackLength(&s);
			break;
		case 6:
			GetTop(&s);
			break;
		case 7:
			Push(&s);
			StackTraverse(&s);//遍历栈元素
			break;
		case 8:
			Ele = Pop(&s);
			printf("删除的栈顶元素为:%d\n", Ele);
			break;
		case 9:
			StackTraverse(&s);
			break;
		case 10:
			exit(0);
			break;
		}
	}
}

<2>.h

#pragma once
#include<stdio.h>
#include<stdlib.h> 
#define Maxsize 25//顺序栈存储空间的初始分配量
typedef int SElemType;
//顺序栈的表示
typedef struct
{
	SElemType* base;//栈底指针
	SElemType* top;//栈顶指针
	int stacksize;//栈可用的最大容量
}SqStack;
//顺序栈的初始化
int InitStack(SqStack *S)
{
	S->base = (SElemType*)malloc(sizeof(SElemType));//为顺序表分配一个最大容量为Maxsize的数组
	if (!S->base)//存储分配失败
		exit(0);
	else
		printf("成功初始化\n");
	S->top = S->base;//top初始为base
	S->stacksize = Maxsize;

	return true;
}
//销毁栈
int DestroyStack(SqStack* S)
{
	free(S->base);//释放栈底元素的空间
	S->base = NULL;//并将栈底和栈顶的指针同时指向NULL
	S->top = NULL;
	S->stacksize = 0;//栈可用的最大容量赋值为0
	if (S->base == NULL)
	{
		printf("栈销毁成功!\n");
		return true;
	}
	else
	{
		printf("栈销毁失败!!\n");
		return false;
	}
}
//清空栈
int ClearStack(SqStack* S)
{
	if (S->top == S->base)//两者地址相同
		return true;
	else
	{
		while (S->base < S->top)//因为顺序栈是地址连续的存储单元所以可以比较地址的大小
		{
			S->top--;//地址减减直到S->top的地址等于S->base的地址
		}
		if(S->top==S->base)
		{
			printf("成功清除\n");
			return true;
		}
		else 
		{
			printf("清除失败!!");
			return false;
		}
	}

}
//检测栈是否为空
int StackEmpty(SqStack* S)
{
	if (S->top == S->base)
	{
		printf("空栈!!\n");
		return false;
	}
	else
	{
		printf("非空栈!!\n");
		return true;
	}
}
//返回栈元素个数
int StackLength(SqStack* S)
{
	printf("元素个数为:%d\n", S->top-S->base);//S->top在元素的上一个地址,S->top-S->base正好会等于栈元素个数
	return true;
}
//返回栈顶元素
int GetTop(SqStack *S)
{
	if (S->top == S->base)
	{
		printf("为空栈,不存在元素\n");
		return false;
	}
	else
	{
		printf("栈顶元素为:%d\n", *(S->top - 1));//通过指针读取地址的数据
		return true;
	}
}
//插入栈顶元素
int Push(SqStack* S)
{
	int Element=0;
	if ((S->top - S->base) >= S->stacksize)//此时栈最大可用容量已满
	{
		S->base = (SElemType*)realloc(S->base, S->stacksize + 20 * sizeof(int));
		if(S->base==NULL)
		return false;
			S->top = S->base + S->stacksize;
			S->stacksize += 20 * sizeof(int);
	}
		printf("输入你想添加的元素:\n");
		scanf_s("%d", &Element, sizeof(Element));
		*S->top++ = Element;//等效于下面的语句
		//*S->top=e;
		//S->top++;
		return true;
	
}
//删除栈顶元素并返回值
int Pop(SqStack* S)
{
	int e = 0;
	if (S->top == S->base)
	{
		printf("空栈!!没有可以删除的元素\n");
	}
	else
	{
		e = *--S->top;
	}
	return e;
}
//从底到顶依此访问栈元素
int StackTraverse(SqStack* S)
{
	int* p = S->base;//定义一个指针变量指向栈底
	if (S->top == S->base)//如果栈底和栈顶存储地址相同即为空栈
	{
		printf("空栈!!\n");
		return false;
	}
	else
	{
		printf("栈元素为:");
		while (p <= S->top-1)//p地址从S->base一直向上移动直到移动到S->top-1
		{//S->top总是指向栈顶元素的上一个
			printf("%d\t", *p);//p为指针类型
			p++;//地址上移
		}
		printf("\n");
		return true;
	}
}

如果真有能看到最后的小伙伴,点个赞叭!!!

​​​​​​​

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值