02---顺序栈---20195106023---王亚威.c
/* 栈的概念: 栈(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; }