/*
栈的概念:
栈(Stack)的定义:是限制在表的一端进行插入和删除操作的线性表。
又称为后进先出LIFO (Last In First Out)或先进后出FILO (First In Last Out)线性表。
栈顶(Top):允许进行插入、删除操作的一端,又称为表尾。用栈顶指针(top)来指示栈顶元素。
栈底(Bottom):是固定端,又称为表头。
空栈:当表中没有元素时称为空栈。
*/
# include <stdio.h>
# include <malloc.h>
# include <stdlib.h>
# define true 1
# define false 0
typedef struct Node
{
int data;
struct Node * pNext;
}NODE, * PNODE;
typedef struct Stack
{
PNODE pTop; //栈顶指针(top)
PNODE pBottom; //栈底指针(pBottom)
}STACK, * PSTACK; //PSTACK 等价于 struct STACK *
//栈的初始化
void init(PSTACK pS)
{
pS->pTop = (PNODE)malloc(sizeof(NODE));
if (NULL == pS->pTop)
{
printf("动态内存分配失败!\n");
exit(-1);
}
else
{
pS->pBottom = pS->pTop;
pS->pTop->pNext = NULL; //pS->Bottom->pNext = NULL;
}
}
//压栈
void push(PSTACK pS, int val)
{
PNODE pNew = (PNODE)malloc(sizeof(NODE));
pNew->data = val;
pNew->pNext = pS->pTop; //pS->Top不能改成pS->Bottom
pS->pTop = pNew;
return;
}
//遍历
void traverse(PSTACK pS)
{
PNODE p = pS->pTop;
while (p != pS->pBottom)
{
printf("%d ", p->data);
p = p->pNext;
}
printf("\n");
return;
}
//判断栈空
_Bool empty(PSTACK pS)
{
if (pS->pTop == pS->pBottom)
return true;
else
return false;
}
//弹栈(把pS所指向的栈出栈一次,并把出栈的元素存入pVal形参所指向的变量中,如果出栈失败,返回false,否则返回true)
_Bool pop(PSTACK pS, int * pVal)
{
if ( empty(pS) ) //pS本身存放的就是S的地址
{
return false;
}
else
{
PNODE r = pS->pTop;
*pVal = r->data;
pS->pTop = r->pNext;
free(r);
r = NULL;
return true;
}
}
//clear清空
void clear(PSTACK pS)
{
if (empty(pS))
{
return;
}
else
{
PNODE p = pS->pTop;
PNODE q = NULL;
while (p != pS->pBottom)
{
q = p->pNext;
free(p);
p = q;
}
pS->pTop = pS->pBottom;
}
}
//显示菜单
void ShowMenu()
{
int i;
int WIDESIZE = 65;
printf("\n\n\n");
printf("------------------------");
printf("\t欢迎使用动态栈的压栈和弹栈\t");
printf("------------------------\n\n");
printf("\t\t");
for(i=0;i<WIDESIZE;i++)
{
printf("*");
}
printf("\n\n");
printf("\t\t*\t1.系统帮助及说明\t**");
printf("\t2.提示\t\t\t*\n");
printf("\t\t*\t3.初始化\t\t");
printf("**\t4.遍历\t\t\t*\n");
printf("\t\t*\t5.压栈\t\t\t**");
printf("\t6.弹栈\t\t\t*\n");
printf("\t\t*\t7.清空\t\t\t**");
printf("\t8.退出\t\t\t*\n");
for(i=0;i<4;i++)
{
printf("\t");
}
printf("\n\t\t");
for(i=0;i<WIDESIZE;i++)
{
printf("*");
}
printf("\n");
printf("--------------------------------");
printf(" 2019级电科一班王亚威作品 ");
printf("----------------------------------\n");
printf("\n\n请按所需输入菜单编号:");
}
//显示帮助信息
void ShowHelp()
{
printf("1、此系统可以简单完成动态栈的压栈和弹栈\n");
printf("2、输入对应功能项的编号即可进行不同功能的操作。\n");
}
int main(void)
{
STACK S;
int val;
int flag = -1;
int choice;
while(flag!=8)
{
ShowMenu();
scanf("%d",&choice);
switch (choice)
{
case 1:
ShowHelp();break;
case 2:
printf("提示:压栈和出栈前请先完成初始化。\n");break;
case 3:
init(&S);break;
case 4:
traverse(&S);break;
case 5:
printf("请输入要压栈的元素\n");
scanf("%d",&val);
push(&S, val);
traverse(&S);;break;
case 6:
if ( pop(&S, &val) )
{
printf("出栈成功,出栈的元素是%d\n", val);
}
else
{
printf("出栈失败!\n");
}
traverse(&S);break;
case 7:
clear(&S);break;
case 8:
flag=8;break;
}
}
return 0;
}