【数据结构】其六:栈之链栈——2022/01/13
可怕……距离上次发文居然已经过去一星期了。真是容易怠惰,不知道月底最后一天之前,能不能把数据结构全部整完呢😢,焦虑起来了。
#include <stdio.h>
#include <stdlib.h>
/**
* 注释:
* 项目建立时间:2022/01/12
* 项目名称:链栈(与不带头结点的单链表相似)
* “后进先出”原则,简称LIFO表。
* 实现:通过预设足够长的一维数组和一个记录栈顶元素位置的变量来实现
* 操作集:
* 1、初始化栈
* 2、判断栈空
* 3、进栈
* 4、出栈
* 5、取栈顶元素
* 6、十进制转二进制
*
* q:有两个问题:
* 一个是s需要在头部声明,不然后面的程序调用s的时候会显示s可能为初始化;
* 另一个是num需要初始化值为1,不然程序会自动退出;
*/
#define MAXSIZE 100
typedef struct stacknode
{
int data;
struct stacknode *next;
} LinkStack;
typedef struct stacknode *StackNode; //给链栈指针结构体设置别名:StackNode;
StackNode s;
/* 初始化栈,置为空 */
StackNode InitStack()
{
StackNode s;
s = NULL;
return s;
}
/* 判断栈空 */
int EmptyStack(StackNode s)
{
if (s == NULL)
{
printf("栈空!\n");
return 1;
}
else
{
return 0;
}
}
/* 入栈 */
StackNode Push(StackNode s, int x)
{
StackNode p;
p = (StackNode)malloc(sizeof(LinkStack));
p->data = x;
p->next = s;
s = p;
return s;
}
/* 出栈 */
StackNode Pop(StackNode s, int *x)
{
StackNode p;
if (EmptyStack(s))
{
return NULL;
}
else
{
*x = s->data;
p = s;
s = s->next;
free(p);
return s;
}
}
/* 获取栈顶元素 */
int GetTop(StackNode s, int *x)
{
if (EmptyStack(s))
{
return 0;
}
else
{
*x = s->data;
return 1;
}
}
/* 依序输出栈中元素 */
void ShowStack(StackNode s)
{
StackNode p = s;
if (p == NULL)
{
printf("栈空!\n");
}
else
{
printf("自栈顶起各元素为:\n");
while (p != NULL)
{
printf("\t%d", p->data);
p = p->next;
}
printf("\n");
}
}
/* 十进制转二进制 */
void D_B(StackNode s, int x)
{
while (x)
{
s = Push(s, x % 2);
x /= 2;
}
printf("转换后的二进制为:\n");
while (s != NULL)
{
s = Pop(s, &x);
printf("%d\t", x);
}
printf("\n");
}
void menu()
{
printf("\t链栈的各种操作:\n");
printf("==============================\n");
printf("\t1----建立链栈\n");
printf("\t2----入栈操作\n");
printf("\t3----出栈操作\n");
printf("\t4----求栈顶元素\n");
printf("\t5----显示栈中元素\n");
printf("\t6----十、二进制转换\n");
printf("==============================\n");
}
int main()
{
int n, z, x;
int num = 1;
while (num)
{
menu();
printf("请输入菜单号:\n");
scanf("%d", &num);
if (num == 0)
{
break;
}
switch (num)
{
case 1:
printf("初始化链栈完毕。\n");
s = InitStack();
break;
case 2:
printf("请输入进栈元素的个数:\t");
scanf("%d", &n);
printf("请输入%d个整数进行入栈:\n", n);
for (int i = 0; i < n; i++)
{
scanf("%d", &x);
s = Push(s, x);
}
printf("\t入栈完毕!\n");
break;
case 3:
printf("请输入出栈元素的个数:\t");
scanf("%d", &n);
printf("出栈元素数量为:%d\n",n);
for (int i = 0; i < n; i++)
{
s = Pop(s, &x);
if (s!=NULL)
{
printf("%5d", x);
}
}
printf("\n\t出栈完毕!\n");
break;
case 4:
GetTop(s, &x);
printf("栈顶元素为:%d\n", x);
break;
case 5:
ShowStack(s);
break;
case 6:
s = InitStack();
printf("请输入十进制正整数:\n");
scanf("%d", &z);
D_B(s, z);
break;
default:
printf("请输入0-6的数!\n");
break;
}
}
}
这个链栈结构不复杂,但是比起前一个顺序栈,感觉自己花了额外的时间来改bug。自己的动手写代码能力还是非常亟待提高……
明天再见😋.