实验三_栈的操作

引言

  1. 文章结构:每题是由题目解析与注意事项代码三部分组成。在文章的结尾,记录了我的一些做题心得
  2. 建议第一次写这些题目的同学可以自己先敲一下代码,然后再参考文章中的代码。

第一题

题目

题目描述
栈是计算机中经典的数据结构,简单的说,栈就是限制在一端进行插入删除操作的线性表。栈有两种最重要的操作,即pop(从栈顶弹出一个元素)和push(将一个元素进栈)。

输入
构造一个顺序栈,输入数据只有3行,第1行是一个整数n,表示顺序栈元素个数;第2行是n个整数,将这n个整数依次入栈构造顺序栈;第3行表示出栈元素个数m(m

输出
共2行,第一行为出栈前所有栈中元素,元素之间用空格分割,第二行为出栈后栈顶元素和栈的长度,以空格分割。

样例输入
5
10 20 30 40 50
2

样例输出
10 20 30 40 50
30 3

解析与注意事项

  1. 使用 exit() 要包含头文件
  2. 初始化栈的思路:1)栈底指针指向所分配空间的首地址(注意判断是否分配成功);2)置空栈(栈顶等于栈底);3)确定站的大小(staksize)。
  3. 清空栈操作:「 S.top = S.base; 」
  4. 判断栈是否为空直接:「 return S.top == S.base; 」即可。
  5. 求栈中元素个数:「 return S.top - S.base; 」
  6. 获取栈顶元素操作与出栈操作要先判断是否为空栈;入栈操作要先判断是否栈满(栈满要再分配存储空间,调整指针关系与栈的size)。
  7. 注意 :S.top 指向的是栈顶元素的下一个位置,不是栈顶元素。

代码

#define _CRT_SECURE_NO_WARNINGS

#include	//若用printf,scanf,getchar,putchar,gets,puts函数需包含该头文件
#include	//用malloc,free,realloc函数需包含该头文件

#define MAXSIZE 100
#define STACKINCREMENT 10

typedef int ElemType;

typedef struct STACK//与大话数据结构中栈的结构不同
{
	ElemType *base;
	ElemType *top;
	int stacksize;
}SqStack;//请填写完整栈的数据结构

//函数声明
int InitStack(SqStack& s);
void ClearStack(SqStack& S);
int StackEmpty(SqStack S);
int StackLength(SqStack S);
int GetTop(SqStack s, ElemType& e);
int Push(SqStack& s, ElemType e);
int Pop(SqStack& s, ElemType& e);

//初始化,创建空栈
int InitStack(SqStack& s)
{
	//请完善代码......
	s.base = (ElemType*)malloc(STACKINCREMENT * sizeof(ElemType));//注意是栈底指针
	if (!s.base)
	{
		printf("存储分配失败!\n");
		return 0;
	}
	s.top = s.base;
	s.stacksize = STACKINCREMENT;
	return 1;
}

//清空栈
void ClearStack(SqStack& S)
{
	//请完善代码......
	S.top = S.base;
}

//判栈空
int StackEmpty(SqStack S)
{
	//请完善代码......
	return S.top == S.base;
}

//求栈中元素个数
int StackLength(SqStack S)
{
	//请完善代码......
	return S.top - S.base;
}

//获取栈顶元素值
int GetTop(SqStack s, ElemType& e)
{
	//请完善代码......
	if (s.top == s.base)//先判断是否为空栈
		return 0;
	e = *(s.top - 1);//S.top 指向的是栈顶元素的下一个位置
	return 1;
}

//入栈
int Push(SqStack& s, ElemType e)
{
	//请完善代码......
	if (s.top - s.base >= s.stacksize)//判断是否栈满
	{
		s.base = (ElemType*)realloc(s.base,(s.stacksize+STACKINCREMENT) * sizeof(ElemType));
		if (!s.base)
		{
			printf("存储分配失败!\n");
			return 0;
		}
		s.top = s.base+s.stacksize;
		s.stacksize += STACKINCREMENT;
	}
	*s.top = e;
	s.top++;
	return 1;
}

//出栈
int Pop(SqStack& s, ElemType& e)
{
	//请完善代码......
	if (s.top == s.base)//先判断是否为空栈
		return 0;
	s.top--;
	e = *s.top;
	return  1;
}

//打印栈中元素
void PrintElem(SqStack S)
{
	//请完善代码......
	int i, L = S.top - S.base;
	for (i = 0; i < L;i++)
	{
		printf("%d ", *(S.base++));
	}

}

//主函数
int main() {
	ElemType e;
	SqStack S;//定义一个顺序栈 
	int n, m;
	InitStack(S);//初始化顺序栈 
	scanf("%d", &n);//请输入要入栈的元素个数 
	for (int i = 0; i < n; i++)
	{
		scanf("%d", &e);
		Push(S, e);//入栈 
	}
	PrintElem(S);//输出栈中元素 
	printf("\n");
	scanf("%d", &m);//请输入要出栈的元素个数 
	for (int i = 0; i < m; i++)
	{
		Pop(S, e);//出栈 
	}
	GetTop(S, e);//输出栈顶元素 
	printf("%d %d", e, StackLength(S));
	return 0;
}

第二题

题目

题目描述
利用栈实现十进制与二进制、八进制、十六进制之间的转换,其中十六进制数码09,AF。

输入
输入两个数n和R,分别表示十进制数和要转换的进制(2、8或16)。

输出
转换的R进制结果。

样例输入
56 2

样例输出
111000

解析与注意事项

  1. 数制转换算法原理:

1)十进制数 N 和其他 D 进制数的转换遵循以下原理:
N = ( N d i v D ) × D + N m o d D \boxed{N=(N div D)×D+N mod D} N=(NdivD)×D+NmodD
(其中div为整除运算,mod为求余运算)
例如: ( 1348 ) 10 = ( 2504 ) 8 (1348)_{10}=(2504)_8 (1348)10=(2504)8,其运算过程如下:

N N / 8 N % 8
1348 168 4
168 21 0
21 2 5
2 0 2

2)假设现要编制一个满足下列要求的程序:对于输入的任意一个非负十进制整数,输出与其等值的八进制数。由于上述计算过程是从低位到高位顺序产生八进制数的各数位,而打印输出,一般来说应从高位到低位进行,恰好和计算过程相反。因此,若将计过程中得到的八进制数的各位顺序进栈,则按出栈序列打印输出的即为与输入对应的进制数。

  1. 注意:十六进制中第 10 - 15 要用字母 A - F 表示。
  2. 用该方法转换出来的数,其实不是一个数,而是几个数的有序排列(用几个按一定顺序排列的数,来表示转换进制后所要的那个数)

代码

#define _CRT_SECURE_NO_WARNINGS

#include	//若用printf,scanf,getchar,putchar,gets,puts函数需包含该头文件
#include	//用malloc,free,realloc函数需包含该头文件

#define MAXSIZE 100
#define STACKINCREMENT 10

typedef int ElemType;

typedef struct STACK
{
	ElemType* base;
	ElemType* top;
	int stacksize;
}SqStack;//请填写完整栈的数据结构

//函数声明
int InitStack(SqStack& s);
void ClearStack(SqStack& S);
int StackEmpty(SqStack S);
int StackLength(SqStack S);
int GetTop(SqStack s, ElemType& e);
int Push(SqStack& s, ElemType e);
int Pop(SqStack& s, ElemType& e);

//初始化,创建空栈
int InitStack(SqStack& s)
{
	//请完善代码......
	s.base = (ElemType*)malloc(STACKINCREMENT * sizeof(ElemType));
	if (!s.base)
	{
		printf("存储分配失败!\n");
		return 0;
	}
	s.top = s.base;
	s.stacksize = STACKINCREMENT;
	return 1;
}
//判栈空
int StackEmpty(SqStack S)
{
	//请完善代码......
		return S.top == S.base;
}

//求栈中元素个数
int StackLength(SqStack S)
{
	//请完善代码......
	return S.top - S.base;
}

//入栈
int Push(SqStack& s, ElemType e)
{
	//请完善代码......
	if (s.top - s.base >= s.stacksize)
	{
		s.base = (ElemType*)realloc(s.base, (s.stacksize + STACKINCREMENT) * sizeof(ElemType));
		if (!s.base)
		{
			printf("存储分配失败!\n");
			return 0;
		}
		s.top = s.base + s.stacksize;
		s.stacksize += STACKINCREMENT;
	}
	*s.top = e;
	s.top++;
	return 1;
}

//出栈
int Pop(SqStack& s, ElemType& e)
{
	//请完善代码......
	if (s.top == s.base)
		return 0;
	s.top--;
	e = *s.top;
	return  1;
}

//数制转换函数
void conversion()
{
	ElemType e;
	SqStack S;
	InitStack(S);
	//请完善代码......
	int n, R;
	scanf("%d%d", &n, &R);

	//将算好的数入栈
	while (n) {
		Push(S, n % R);//key1
		n = n / R;//key2
	}

	//将入栈后的数出栈(先入后出)
	while (!StackEmpty(S)) {
		Pop(S, e);
		if (e > 9)
		{
			printf("%c", 'A' + e - 10);//十六进制中第 10 - 15 要用字母 A - F 表示
		}
		else
			printf("%d", e);
	}

	printf("\n");
}

//主函数
int main() {
	conversion();
	return 0;
}

做题心得

  1. 第一题其实不需要用到清空栈函数与判栈空函数。
  2. 《大话数据结构》中的栈的结构不同于题目中栈的结构(大话的是用数组实现的)。其中,数组实现的栈,由于事先固定了栈的大小,故不能扩展内存。(如果试图通过修改MAXSIZE值来改变数组长度,那么原先存在数组中的数据就会丢失。因为这不同于动态分配内存的在堆上分配内存,修改长度后原先的数据还在;若数组的长度被修改了,内存就给整个数组重新分配内存了,原先的数据就不在了。)

你可能感兴趣的:(#,数据结构错题本,数据结构,数据结构,c++,算法)