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;
}

 

posted @ 2020-11-30 23:02  张同光  阅读(135)  评论(0编辑  收藏  举报