第三章-栈(一)


------------------------------------------------------------------------------------------------

1、定义 :         限定只能在表的一端进行插入和删除运算的线性表(只能在栈顶操作)表尾端。
2、逻辑结构:   与线性表相同,仍为一对一关系
3、存储结构:   只能在栈顶运算,且访问结点时依照后进先出(LIFO)或先进后出(FILO)的原则
4、运算规则:  只能在栈顶运算
5、实现方法:  关键是编写入栈和出栈函数,具体实现依顺序栈或链栈的不同而不同
                        基本操作有入栈、出栈、读栈顶元素值、建栈、或判断栈满、栈空等。


6、栈的物理结构
                     

注意:在每次入栈的时候, top 指针会在存储的位置的上一个位置:



7、栈的抽象数据类型定义:
     ADT{
               数据对象:D={ ai | ai 属于 ElemSet,i=1,2 ,.... , n,   n>=0 }
               数据关系:R1={ < ai-1 , ai > | ai-1 , ai 属于 D , i=2, ... , n}
                             约定 an 端为栈顶, a1 端为栈底。
               基本操作:
                        InitStack(&S)
                           操作结果:构造一个空栈S。

                        DestroyStack(&S)
                           初始条件:栈S已存在。
                           操作结果:栈S被销毁。

                        ClaerStack(&S)
                           初始条件:栈S已存在。
                           操作结果:将栈S清空为空栈

                        StackEmpty(&S)
                           初始条件:栈S已存在。
                           操作结果:若栈为空栈,则返回TRUE,否则FLASE。

                        StackLength(&S)
                           初始条件:栈S已存在。
                           操作结果:返回S的元素个数,即栈的长度

                        GetTop(S,&e)
                           初始条件:栈S已存在且非为空。
                           操作结果:用e返回S的栈顶元素

                        Push(&S,e)
                           初始条件:栈S已存在。
                           操作结果:插入元素 e 为新的栈顶元素

                        Pop(&S)
                           初始条件:栈S已存在且非为空。
                           操作结果:删除S的栈顶元素,并用e返回其值

                        StackTraverse( S, visit() )
                           初始条件:栈S已存在且非为空。
                           操作结果:从栈底到栈顶依次对S的每个元素调用 Visit() 。一旦Visit()失败,则操作失                                                  败。

     }ADT Stack


8、栈的条件:
             栈不存在的条件 : base =NULL;
             栈为空的条件:      base=top;
              栈满的条件:        top- base=stacksize;
             
                          

9、栈的实现:(和线性表类似,栈也有两种存储方式)
     顺序栈的操作系统:
完整代码:

注:需要以  .cpp 为后缀名


//头文件
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<malloc.h>

//宏定义
#define STACK_INIT_SIZE 100     //存储空间初始分配量
#define STACKINCREMENT 10         //存储空间分配增量
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2

typedef int SElemType;
typedef int Status;

//栈的顺序结构体
typedef struct{
	SElemType *base;              //在栈构造之前和销毁之后,base 的值为NULL;
	SElemType *top;               //栈顶指针
	int stacksize;                //当前已分配的存储空间,以元素为单位
}SqStack;

//------------基本操作的函数原型说明--------------
//Status InitStack(SqStack &S);      //构造一个空栈S

//Status DestroyStack(SqStack &S);   //销毁栈S,S不再存在

//Status ClearStack(SqStack &s);     //把栈S置位空

//Status StackEmpty(SqStack S);    //若栈S为空栈,则返回TRUE,否则返回FALSE

//int StackLength(SqStack S);      //返回S的元素个数,即栈的长度

//Status GetTop(SqStack S,SElemType &e);     //若栈不为空,则用e返回S的栈顶元素,并返回OK,否则返回ERROR

//Status Push(SqStack &S,SElemType e);        //插入元素e为新的栈顶元素

//Status Pop(SqStack &S,SElemType &e);        //若栈不为空,则删除S的栈顶元素,用e返回其值,并返回OK,否则返回ERROR

//Status StackTraverse(SqStack S,Status (*visit) () );      
        //从栈底到栈顶依次对栈中每个元素调用函数 visit() , 一旦 visit() 失败,则操作失败

//1.构建栈
Status InitStack(SqStack &S){
	//构造一个空栈S
	S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
	if(! S.base) exit(OVERFLOW);  //存储分配失败
	S.top=S.base;    //当栈为空时,栈底等于栈顶
	S.stacksize=STACK_INIT_SIZE;    //栈可存储的个数
	return OK;
}

//2.销毁栈
Status DestroyStack(SqStack &S){
	S.top=NULL;
	S.stacksize=0;
	free(S.base);
	return OK;
}

//3.清空栈
Status ClearStack(SqStack &S){
	S.top=S.base;   //栈顶和栈底指向同一个位置,即为空
	return OK;
}

//4.判断栈是否为空
Status StackEmpty( SqStack S)
{
	if(S.top==S.base)
		return ERROR;
	else
		return TRUE;
}

//5.求栈的长度
Status StackLength(SqStack S)
{
	int n;
	if(S.top==S.base)
		return FALSE;
	else{
		n=S.top-S.base;
		return n;
	}
}

//6.求栈顶元素
Status GetTop(SqStack S,SElemType &e)
{
	if(S.top==S.base)
		return FALSE;
	else
		return ( e=*(S.top-1) );
}

//7.栈顶插入元素
Status Push(SqStack &S,SElemType &e)
{       //插入元素 e 为新的栈顶元素
	if(S.top-S.base >= STACK_INIT_SIZE)  //栈满的时候就需要追加存储空间
	{
		S.base=(SElemType *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));	
		if(!S.base)  exit(OVERFLOW);    //存储空间分配失败

		S.top=S.base+S.stacksize;   //栈底的位置可能改变,需要重新定位栈顶元素
		//S.top 还是之前的那个没有存储的位置   

		S.stacksize = S.stacksize+STACKINCREMENT;
	}
	*S.top=e;
	S.top++;
	return OK;
}


//8.栈顶出栈元素
Status Pop(SqStack &S,SElemType &e){
	//若栈不为空,则删除 S 的栈顶元素,用 e 返回其值,并返回 OK ,否则返回ERROR
	if(S.top == S.base)  return ERROR;
	e=*(--S.top);     //可以不加括号,但需要记住的是,需要让 top 指针减 1 ,再取出元素
	return OK;
}

//9.遍历栈 
Status StackTraverse(SqStack S){
	if(S.base==NULL)  return ERROR;
	if(S.top==S.base){
		printf("栈为空,没有元素-------!");
		return FALSE;
	}
	SElemType *p=S.top;   //先找出 top 的地址
	while(p > S.base)
	{
		p--;
		printf("%d\n",*p);
	}
	return OK;
}
/*
Status StackTraverse(SqStack S,Status (*visit) () )
{
	whlie(S.top != S.base)
		visit(--S.top); //先把指针减 1 ,再输出其元素 
}
*/

//主函数
void main(){
	SqStack S;
	int whilenum=1;
	int stack_length;
	int word;
	char anykey;
	int IS_Result;
	do{
			printf("------------------------------Use Stack----------------------------\n");
        	printf("1.Buliding an empty Stack. \n");
        	printf("2.Destruction of the Stack. \n");
    		printf("3.Clear the Stack. \n");
    		printf("4.Determines whether the Stack is empty. \n");
    		printf("5.Caculate the Stack length.  \n");
    		printf("6.Obtain the top element Stack. \n");
    		printf("7.Insert elements into the top of the Stack. \n");
    		printf("8.The output Stack top element. \n");
    		printf("9.Ergodic output stack. \n");
    		printf("10.The end of the Stack. \n");
    		printf("11.\n");
    		printf("12.\n");
    		printf("13.\n");
			printf("--------------------------------------------------------------------\n");

		whilenum=1;
		int choice;
		printf("Please enter your choice.\n");
		scanf("%d",&choice);

		switch(choice){
			//初始化栈
		case 1:
			printf("Buliding an empty Stack.\n");
        	IS_Result=InitStack(S);
        	if(IS_Result=1)
     	    	printf("Construct an empty Stack.\n");
        	else
	        	printf("Rrror\n");
        	printf("\n\n");
			printf("anykey to continue!");
			scanf("%c",&anykey);
			scanf("%c",&anykey);
			break;

			//销毁栈
		case 2:
			printf("Destruction of the Stack.\n");
			if(DestroyStack(S)==1)
				printf("Destruction of the Stack succeed. \n");
			else
				printf("Destruction of the Stack succeed error. \n");
			printf("anykey to continue!");
			break;

			//清空栈
		case 3:
			printf("Clear the Stack.\n");
			if(ClearStack(S)==1)
				printf("Clear the Stack succeed.\n");
			else
				printf("Clear the Stack error.\n");
			printf("anykey to continue!");
			break;

			//判断栈是否为空
		case 4:
			printf("The Stack is empty?  \n");
			if( StackEmpty(S) == 1)
				printf("NO!\n");
			else
				printf("YES!\n");
			printf("anykey to continue!");
			scanf("%c",&anykey);
			scanf("%c",&anykey);
			break;

			//Calculate the stack length.
		case 5:
			printf("Calculate the stack length,the length of Atack is:");
			stack_length=StackLength(S);
			printf("%d",stack_length);
			printf("anykey to continue!");
			scanf("%c",&anykey);
			scanf("%c",&anykey);
			break;

			//获得栈顶元素
		case 6:
			printf("Get the top element of the stack.\n");
			GetTop(S,word);
			printf("the word is : %d",word);
			printf("anykey to continue!");
			scanf("%c",&anykey);
			scanf("%c",&anykey);
			break;

			//入栈
		case 7:
			printf("Please enter the char you want to enter.");
			scanf("%d",&word);
			Push(S,word);
			printf("anykey to continue!");
			scanf("%c",&anykey);
			scanf("%c",&anykey);
			break;

			//出栈
		case 8:
			printf("The output Stack top element.\n");
			Pop(S,word);
			printf("the word is : %d",word);
			printf("anykey to continue!");
			scanf("%c",&anykey);
			scanf("%c",&anykey);
			break;

			//遍历栈
		case 9:
			printf("Traverse the Stack:");
			StackTraverse(S); 
			printf("anykey to continue!");
			scanf("%c",&anykey);
			scanf("%c",&anykey);
			break;

			//结束
		case 10:
			printf("Succeding end. \n");
			whilenum=0;
			break;
		}

		system("cls");
	}while(whilenum);
}








                                                                                     如有错误,敬请指出!
       
























             
             
             
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值