✨一、实验要点
- 在进行进制转换时,要特别注意十六进制,此时可以打表,也可以按照ASCII码输出对应数 值:注意,ASCII码中需要特别记住 '0' = 48, 'a' = 97, 'A' = 65即可
2. 在实验过程中如果销毁栈之后,再次输入如查看栈的长度等应该输出专门的提示:如栈已销毁。所以,要在销毁栈的时候将 A == NULL (设为Stack *A), 但有意思的地方来了, free(p); // p 所指的内存被释放,但是p 所指的地址仍然不变,所以如果要在函数块中使得主函数中的A == NULL, 则应该传入A的指针,详情可见代码实现部分
二、实验目标
(1)实验目的
通过该实验,让学生掌握栈的相关基本概念,认识栈是插入和删除集中在一端进行的线性结构,掌握栈的“先入后出”操作特点。栈在进行各类操作时,栈底指针固定不动,掌握栈空、栈满的判断条件。
(2)实验内容
用顺序存储结构,实现教材定义的栈的基本操作,提供数制转换功能,将输入的十进制整数转换成二进制、八进制或十六进制。
三、代码实现 (可以重点看一下实验要点中的提示)
//
// main.c
// 数据结构---顺序栈
//
// Created by *** on 17/10/2023.
//
// 用顺序存储结构,实现教材定义的栈的基本操作,提供数制转换功能,
// 将输入的十进制整数转换成二进制、八进制或十六进制。
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
// 顺序栈的创建
typedef struct Stack
{
int elems[STACK_INIT_SIZE];
int top;
int capacity;
} Stack;
// 顺序栈的初始化
Stack* StackInit(void)
{
Stack *A = (Stack*)malloc(sizeof(int) * STACK_INIT_SIZE);
A->top = 0;
A->capacity = STACK_INIT_SIZE;
return A;
}
// 入栈操作
bool push_back(Stack *A, int e)
{
if (A->top >= A->capacity)
return false;
A->elems[A->top ++ ] = e;
return true;
}
// 出栈操作
bool pop_back(Stack *A, int *e)
{
if (A->top == 0)
return false;
A->top --;
*e = A->elems[A->top];
return true;
}
// 清空栈
bool StackFree(Stack *A, int *e)
{
while (A->top > 0)
pop_back(A, e);
return A;
}
// 销毁栈
bool StackDestroy(Stack **A) // 要点一
{
free(*A);
*A = NULL;
return true;
}
// 进制转化,将char dnum中的十进制数,转换成x进制数, 并将每一位都存储在栈Stack A中
bool Dconversion(int dnum, int x, Stack *A)
{
int r = 0;
while (dnum)
{
r = dnum % x;
push_back(A, r);
dnum /= x;
}
return true;
}
int dnum, x, e, order;
Stack *A = NULL;
int main(int argc, const char * argv[]) {
printf("Please enter the corresponding letter to order : \n"
"1 --- Initialize the stack\n"
"2 --- Destroy the stack\n"
"3 --- Free the stack\n"
"4 --- Is Stack Empty?\n"
"5 --- Calculate the length of the lovely stack\n"
"6 --- Get the top element of the stack\n"
"7 --- Insert an element\n"
"8 --- Delete an element\n"
"9 --- Print all the elements\n"
"10 --- Convert the number scale\n"
"Attention --- enter 0 to quit\n");
printf("Please give me an order : ");
scanf("%d", &order);
while (order > 0)
{
switch(order)
{
case 1:
// Stack *A = StackInit();
A = StackInit();
printf("Your stack A has been created.\n");
break;
case 2:
if(A == NULL)
printf("Please initialize stack A first\n");
else if (StackDestroy(&A))
printf("Your stack A has been destroyed.\n");
break;
case 3:
if(A == NULL)
printf("Please initialize stack A first\n");
else if (StackFree(A, &e))
printf("Your stack A has been freed\n");
break;
case 4:
if(A == NULL)
printf("Please initialize stack A first\n");
else if (A->top > 0)
printf("Your stack A is not empty\n");
else
printf("Your stack A is empty\n");
break;
case 5:
if(A == NULL)
printf("Please initialize stack A first\n");
else
printf("The length of stack A is %d\n", A->top);
break;
case 6:
if(A == NULL)
printf("Please initialize stack A first\n");
else if(A->top == 0)
printf("Your stack is empty. Please insert the elements first\n");
else
printf("The top element of stack A is %d\n", A->elems[A->top - 1]);
break;
case 7:
if(A == NULL)
printf("Please initialize stack A first\n");
else {
printf("Please enter the number your want to insert : ");
scanf("%d", &e);
push_back(A, e);
printf("The stack A is : \n");
for (int i = 0; i < A->top; i ++ ) printf("%d ", A->elems[i]);
}
break;
case 8:
if(A == NULL)
printf("Please initialize stack A first\n");
else if(A->top == 0)
printf("Your stack is empty. Please insert the elements first\n");
else
{
printf("Attention : only the toppest element could be deleted"
"The stack A now is : ");
pop_back(A, &e);
for (int i = 0; i < A->top; i ++ ) printf("%d ", A->elems[i]);
}
break;
case 9:
if(A == NULL)
printf("Please initialize stack A first\n");
else if(A->top == 0)
printf("Your stack is empty. Please insert the elements first\n");
else{
printf("The stack now is : ");
for (int i = 0; i <= A->top; i ++ ) printf("%d ", A->elems[i]);
}
break;
case 10:
printf("Please enter the decimal number : ");
scanf("%d", &dnum);
printf("\nPlease enter which scale you want to convert to : ");
scanf("%d", &x);
Stack *A = StackInit();
Dconversion(dnum, x, A);
while (A->top > 0)
{
pop_back(A, &e);
if (x == 16 && e >= 10)
printf("%c", e + 55); // 要点二 :输出ASCII码对应的字符, '0' = 48, 'a' = 97, 'A' = 65
else
printf("%d", e);
}
printf("\n");
break;
default:
printf("Sorry, please enter the right number to order\n");
break;
}
printf("Please give me an order : ");
scanf("%d", &order);
}
return 0;
}
四、总结
总的来说,顺序栈的实现并不是很困难,如果想要提高熟练度,可以删了再打一遍,一共3~5遍左右基本就差不多了。
具体栈的应用如:表达式求值、迷宫等等会在“严蔚敏《数据结构》代码实现”中给出具体的实 现,感兴趣的uu们可以期待一下~~