数据结构_实验三_栈和队列的操作_部分一

顺序栈的基本操作

实验目的

通过该实验,让学生掌握栈的相关基本概念,认识栈是插入和删除集中在一端进行的线性结构,掌握栈的“先进后出”操作特点。栈在进行各类操作时,栈底指针固定不动,掌握栈空、栈满的判断条件。

实验内容

(1)用顺序存储结构,实现教材定义的栈的基本操作。

(2)提供数制转换功能,将输入的十进制整数转换成二进制。

 参考界面

参考界面

 验收/测试用例


通过菜单调用各个操作,测试点:

  1. 没有初始化前进行其他操作,程序是否能控制住。
  2. 初始化一个栈。
  3. 判栈空,屏幕显示栈为空。
  4. 3个数入栈, 1、2、3。
  5. 栈长度,屏幕输出3。
  6. 取栈顶元素,再判栈空,然后再判栈长度。
  7. 出栈,再判栈长度。
  8. 销毁栈,再做其他操作,判断程序是否能控制。
  9. 数制转换,输入:8,输出:1000。

 参考代码

//From:TengMMVP
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define MAXSIZE 100  // 定义栈的最大容量

typedef int SElemType; // 假设栈元素类型为int

typedef struct {
	SElemType *base;  // 栈底指针
	SElemType *top;   // 栈顶指针
	int stacksize;    // 当前已分配的存储空间
} SqStack;

// 初始化顺序栈
void InitStack(SqStack *s) {
	// 动态分配栈的存储空间,大小为MAXSIZE个SElemType元素
	s->base = (SElemType *)malloc(MAXSIZE * sizeof(SElemType));
	// 如果内存分配失败,则程序退出
	if (!s->base) exit(0);

	// 初始化栈顶指针,指向栈底(即空栈状态)
	s->top = s->base;
	// 设置栈的最大容量为MAXSIZE
	s->stacksize = MAXSIZE;
	// 输出栈成功创建的信息
	printf("顺序栈已成功创建。\n");
}

// 判断顺序栈是否为空
int StackEmpty(SqStack *s) {
	// 若栈顶指针等于栈底指针,则说明栈为空
	return s->top == s->base;
}

// 清空顺序栈
void ClearStack(SqStack *s) {
	// 将栈顶指针重置为栈底,实现栈的清空
	s->top = s->base;
	// 打印提示信息,告知用户顺序栈已经被清空
	printf("顺序栈已清空。\n");
}

// 销毁顺序栈
void DestroyStack(SqStack *s) {
	// 释放栈的存储空间
	free(s->base);
	// 将栈底指针设置为NULL,表示该栈已经不再指向任何有效的内存空间
	s->base = NULL;
	// 将栈顶指针设置为NULL,表示栈顶无元素
	s->top = NULL;
	// 将栈的大小设置为0,表示栈为空
	s->stacksize = 0;
	// 输出提示信息,告知用户顺序栈已经被销毁
	printf("顺序栈已销毁。\n");
}

// 返回顺序栈长度
int StackLength(SqStack *s) {
	return s->top - s->base;
}

// 返回栈顶元素
int GetTop(SqStack *s, SElemType *item) {
	// 首先检查栈是否为空
	if (StackEmpty(s)) {
		// 如果栈为空,则打印错误信息,并返回0表示失败
		printf("顺序栈为空,无法取得栈顶元素!\n");
		return 0;
	}

	// 栈不为空,则将栈顶元素赋值给item指针指向的内存
	*item = *(s->top - 1);
	// 返回1表示成功取得栈顶元素
	return 1;
}

// 入栈操作
int Push(SqStack *s, SElemType item) {
	// 检查栈是否已满
	if (s->top - s->base >= s->stacksize) {
		// 如果栈满,则尝试扩展栈空间
		SElemType *newBase = (SElemType *)realloc(s->base, (s->stacksize + MAXSIZE) * sizeof(SElemType));
		// 如果内存重新分配失败,则退出程序
		if (!newBase) exit(0);
		// 更新栈底指针
		s->base = newBase;
		// 更新栈顶指针到新的栈空间末尾
		s->top = s->base + s->stacksize;
		// 更新栈的大小
		s->stacksize += MAXSIZE;
	}
	// 将新元素压入栈,并移动栈顶指针
	*(s->top++) = item;
	// 返回成功标志
	return 1;
}

// 出栈操作
int Pop(SqStack *s, SElemType *item) {
	// 判断栈是否为空
	if (StackEmpty(s)) {
		// 如果栈为空,则打印错误信息,并返回0表示出栈失败
		printf("顺序栈为空,无法出栈!\n");
		return 0;
	}

	// 将栈顶元素通过指针item返回,并将栈顶指针下移,实现出栈操作
	*item = *(--s->top);
	// 出栈成功,返回1
	return 1;
}

// 打印栈内所有元素
void PrintStack(SqStack *s) {
	// 如果栈为空,则打印提示信息并返回
	if (StackEmpty(s)) {
		printf("顺序栈为空。\n");
		return;
	}

	// 打印栈内元素
	printf("顺序栈中的元素为:");
	// 遍历栈,从栈底到栈顶前一个元素
	for (SElemType *i = s->base; i < s->top; i++) {
		// 打印每个元素的值
		printf("%d ", *i);
	}
	printf("\n");
}

// 创建并输入顺序栈元素
void CreateStack(SqStack *s) {
	// 检查s->base是否已经分配内存,如果是则释放
	if (s->base != NULL) {
		free(s->base);
	}

	s->base = (SElemType *)malloc(MAXSIZE * sizeof(SElemType));
	if (!s->base) {
		printf("顺序栈内存分配失败!\n");
		exit(EXIT_FAILURE);
	}
	s->top = s->base;
	s->stacksize = MAXSIZE;

	printf("请输入顺序栈的元素个数(最大%d):", MAXSIZE);
	int n, item;
	if (scanf("%d", &n) != 1 || n <= 0 || n > MAXSIZE) {
		printf("无效的顺序栈元素个数。\n");
		return;
	}

	printf("请依次输入顺序栈的元素:");
	for (int i = 0; i < n; i++) {
		if (scanf("%d", &item) != 1) {
			printf("读取元素失败!\n");
			return;
		}
		Push(s, item);
	}
	printf("创建并输入顺序栈元素操作成功。\n");
}

// 十进制转二进制并使用栈存储
void DecToBin(SqStack *s, int num) {
	SElemType temp,item;
	temp=num;

	s->top = s->base; // 清空栈,准备存储二进制数字

	while (num > 0) {
		Push(s, num % 2);
		num /= 2;
	}

	printf("%d的二进制形式为:",temp);
	while (!StackEmpty(s)) {
		Pop(s, &item);
		printf("%d", item);
	}
	printf("\n");
}
//From:TengMMVP
// 主函数
int main() {
	SqStack s; // 预定义顺序栈
	int quit = 0, item, num;
	bool isInitialized = false, isDestroyed;

	while (!quit) {
		printf("\n********************栈的操作********************\n");
		printf("1. 初始化顺序栈       2. 销毁顺序栈\n");
		printf("3. 清空顺序栈         4. 判断顺序栈是否为空\n");
		printf("5. 返回顺序栈长度     6. 返回栈顶元素\n");
		printf("7. 插入新栈顶元素     8. 删除栈顶元素并返回其值\n");
		printf("9. 输出栈内元素       10.创建并输入顺序栈元素\n");
		printf("11.十进制转二进制     12.退出程序\n");
		printf("************************************************\n");
		printf("请输入操作码:");

		int choice, operationResult;
		scanf("%d", &choice); // 读取操作码

		switch (choice) {
			case 1: // 初始化顺序栈
				InitStack(&s); //调用初始化函数进行顺序栈的初始化
				isInitialized = true; // 初始化标志设置为true
				isDestroyed = false; // 销毁标志设置为false
				break;
			case 2: // 销毁顺序栈
				if(isInitialized&&!isDestroyed) {
					DestroyStack(&s); //调用销毁函数进行顺序栈的销毁
					isDestroyed = true; // 销毁标志设置为true
				} else {
					printf("顺序栈未初始化或已经被销毁,无法进行销毁操作!\n");
				}
				break;
			case 3: // 清空顺序栈
				if(isInitialized&&!isDestroyed) {
					ClearStack(&s); //调用清空函数进行顺序栈的清空
				} else {
					printf("顺序栈未初始化或已经被销毁,无法进行清空操作!\n");
				}
				break;
			case 4: // 判断顺序栈是否为空
				if(isInitialized&&!isDestroyed) {
					// 调用判空函数,返回判断结果
					operationResult = StackEmpty(&s);
					printf("顺序栈%s为空。\n", operationResult ? "" : "不");
				} else {
					printf("顺序栈未初始化或已经被销毁,无法进行判空操作!\n");
				}
				break;
			case 5: // 返回顺序栈长度
				if(isInitialized&&!isDestroyed) {
					// 调用求顺序栈长度的函数,返回顺序栈长度
					operationResult = StackLength(&s);
					printf("顺序栈的长度为:%d。\n", operationResult);
				} else {
					printf("顺序栈未初始化或已经被销毁,无法进行求长度操作!\n");
				}
				break;
			case 6: // 返回栈顶元素
				if(isInitialized&&!isDestroyed) {
					operationResult = GetTop(&s, &item);
					if (operationResult) {
						printf("顺序栈的栈顶元素为:%d。\n", item);
					}
				} else {
					printf("顺序栈未初始化或已经被销毁,无法进行求栈顶操作!\n");
				}
				break;
			case 7: // 插入新栈顶元素
				if(isInitialized&&!isDestroyed) {
					printf("请输入要入栈的元素:");
					scanf("%d", &item);
					operationResult = Push(&s, item);
					if (operationResult) {
						printf("元素%d成功入栈。\n", item);
					}
				} else {
					printf("顺序栈未初始化或已经被销毁,无法进行入栈操作!\n");
				}
				break;
			case 8: // 删除栈顶元素并返回其值
				if(isInitialized&&!isDestroyed) {
					operationResult = Pop(&s, &item);
					if (operationResult) {
						printf("删除的栈顶元素为:%d。\n", item);
					}
				} else {
					printf("顺序栈未初始化或已经被销毁,无法进行删除操作!\n");
				}
				break;
			case 9: // 输出栈内元素
				if(isInitialized&&!isDestroyed) {
					PrintStack(&s);
				} else {
					printf("顺序栈未初始化或已经被销毁,无法进行输出操作!\n");
				}
				break;
			case 10: // 创建并输入顺序栈元素
				CreateStack(&s);
				isInitialized = true; // 初始化标志设置为true
				isDestroyed = false; // 销毁标志设置为false
				break;
			case 11: // 十进制转二进制
				if(isInitialized&&!isDestroyed) {
					printf("请输入要转换的十进制数:");
					scanf("%d", &num);
					DecToBin(&s, num);
				} else {
					printf("顺序栈未初始化或已经被销毁,无法进行转换操作!\n");
				}
				break;
			case 12: // 退出程序
				quit = 1;
				DestroyStack(&s); // 程序结束前销毁栈
				printf("程序已结束。\n");
				break;
			default:
				printf("操作码无效,请重新输入!\n");
		}
	}

	return 0;
}
//From:TengMMVP

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值