顺序栈

3.1 顺序栈的建立

1.建立一个字符栈,从键盘输入若干个字符,以回车键结束,实现元素入栈操作;然后依次输出栈中的字符元素,实现元素出栈操作

2.实验要求和说明
参考程序中,由InitStack_Seq函数分配一个指定大小的字符数组空间,在分配成功地情况下,从键盘输入若干个字符,实现进栈操作。然后依次输出栈中元素的值,其输出顺序恰与输出顺序相反。注意入栈,出栈时栈顶指针TOP的不同变化及栈空的判断条件。建立一个头文件SeqStack.h,包含顺序栈的定义、初始化等。
3.参考程序

// 头文件SeqStack.h
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
//#include <string.h>
#define  STACK_INIT_SIZE 50          // 存储空间初绐分配量
#define  STACKINCREMENT 50   // 存储空间分配增量
#define  OK 1
#define  ERROR -1
#define  OVERFLOW 0

typedef struct SeqStack
{ // 顺序栈类型定义
    int   MAXSIZE;       // 栈中最大元素的个数(即栈空间的大小)
    int   top;           // 栈顶指针
	char *selem;         
}SeqStack,*PSeqStack;

//typedef struct SeqStack *PSeqStack;

int InitStack_Seq(PSeqStack S)    // 初始化顺序栈,见图3-11
{
	S->selem = (char*)malloc(STACK_INIT_SIZE*sizeof(char));
	if(!(S->selem))
		exit(OVERFLOW);
	S->top=-1;
	S->MAXSIZE=STACK_INIT_SIZE;
	return OK;
}
 

int IsEmptyStack_Seq(PSeqStack S)
{// 判栈是否为空
	return( S->top == -1 ? OK : ERROR);
}

int IsFullStack_Seq(PSeqStack S)
{// 判栈是否满
	return(S->top >= S->MAXSIZE-1 ? OK : ERROR);
}

int Push_Seq(PSeqStack S, char x)
{// 元素进栈
	if(S->top >= S->MAXSIZE-1)
	{ 
		printf("Overflow!\n");
        return ERROR;
	}
        S->top++;
        S->selem[S->top] = x;
        return OK;
}

int Pop_Seq(PSeqStack S, char *e)
{// 元素出栈
	if(S->top == -1)
	{
		printf("Underflow!\n");
        return ERROR;
	}
	*e = S->selem[S->top]; 
    S->top--;
    return OK;
}

int GetTop_Seq(PSeqStack S, char *e)
{// 取栈顶元素
	if(S->top == -1)
	{ 
		printf("Underflow!\n");
		return ERROR;
	}
    *e = S->selem[S->top];
	return OK;
}
// 头文件SeqStack.h 结束

void main( )
{
	SeqStack S_seq;
	PSeqStack S;
	char ch;
	S = &S_seq;
	
	InitStack_Seq(S);
	printf("Input the datas to the stack, end Input \\n: ");
    ch = getchar();
    while( ch != '\n' && Push_Seq(S, ch)) 
	{
        ch = getchar();    
	} 
	printf("Output the datas in the stack: ");
	for(;S->top != -1; S->top--)    // 栈中元素出栈
		printf("%c", S->selem[S->top]);
	printf("\n");

3.思考题
(1)如果栈中的元素为结构类型,如何建立一个顺序栈?

typedef struct SeqStack
{
	int MAXSIZE;		//栈中最大元素的个数(即栈空间的大小) 
	int top;			//栈顶指针 
	struct Student *selem;		 //结构体类型的元素指针
}SeqStack,*PSeqStack;

//定义一个Student结构体,只需要把结构体地址传给栈的selem就可以了,为了方便,用结构体数组来存储。
typedef struct Student
{
	int id;		//学号 
	char sex;	//性别 F/M 
	char name[11];	//名字 
}Student,*Stu;


int Push_Seq(PSeqStack S,Student x) { ......}    //函数里边内容不变

int Pop_Seq(PSeqStack S,Student *e){......}

int GetTop_Seq(PSeqStack S,Student *e){......}

int main()
{
	SeqStack S_seq;
	PSeqStack S;
	S = &S_seq;	int i=-1,n;
	InitStack_Seq(S);
	
	struct Student stu[50];
	
	do{
		i++;
		printf("请输入第%d个学生的信息 id sex name(0 0 0 结束):", i);
        scanf ("%d %c %s",&stu[i].id, &stu[i].sex, stu[i].name);
	}
	while(stu[i].id != 0 && Push_Seq(S,stu[i]));
	
	
	printf("Output the datas in the satck:");
	for(;S->top != -1; S->top--)
	{
		*stu = S->selem[S->top];
		printf("id: %d ,sex: %c ,name: %s \n",stu->id,stu->sex,stu->name);
	}
		
	printf("\n");
	
	return 0;
}

(2)设计一个算法,利用栈的基本运算,返回指定顺序栈中的栈底元素。

int GetSelem_Seq(PSeqStack S,char *e)
{
	//取栈底元素、若栈i非空,用变量*e返回栈顶元素
	int i;
	printf("top = %d\n",S->top);
	if(S->top <= -1)	
	{
		printf("The Stack is NULL!\n");
		return ERROR;
	}
	else
		*e = S->selem[0];

	return OK;
}

3.2 顺序栈的共享共用

1.建立两个迎面增长的共享栈Stack0,Stack1,栈元素为char类型。分别完成建栈、取栈顶元素及求栈的长度(栈元素的个数)操作。建栈时,支持字符元素连续输入。
2.实验要求及说明
顺序栈共用,即使多个顺序栈共用一个足够大的数组空间,并利用栈的动态特性使其存储空间互补。下面实现的两个顺序栈共用算法可以推广到多个共用栈。
参考程序中设置了一个结构类型:DseqStack,用于描述两个迎面增长的共享栈的状态。程序中利用整型变量i控制对不同栈的操作。注意两个共享栈Stack0,Stack1的栈底位置的不同和栈顶指针变化的差异。两个顺序栈共用结构示意图如图所示。

3.参考代码

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#define   STACK_INIT_SIZE 10
#define   OK 1
#define   ERROR -1
#define   OVERFLOW 0

typedef struct DSeqStack
{ // 共用栈的结构定义
	char  *selem[2];      // 两个栈的栈底指针
	int    top[2];         // 两个栈的栈顶指针
    int   MAXSIZE;         // 共用栈的大小
}DSeqStack, *PDSeqStack;/

int InitStack_DSeq(PDSeqStack S) 
{ // 初始化共享栈DSeq
  // 分别设置 Stack0、Stack1 的栈底指针selem[0]、selem[1]
	S->selem[0]=(char *)malloc(STACK_INIT_SIZE*sizeof(char));  
	if(!S->selem[0])
		exit(OVERFLOW);
    S->MAXSIZE = STACK_INIT_SIZE;
	S->selem[1]= S->selem[0]+S->MAXSIZE-1;     // 设置 Stack1 的栈底指针selem[1]//
	S->top[0] = -1;                 		  // 栈 Stack0 的初始状态
	S->top[1] = S->MAXSIZE;                   // 栈 Stack1 的初始状态///
	return OK;
}

int CreateStack_DSeq(PDSeqStack S, int i)
{ // 建立顺序字符栈i
	char ch;
	if(i==0)
	{ // 建立栈Stack0
		while((ch = getchar())!='\n')
		{
			S->top[0]++;
			if(S->top[0] >= S->top[1])
			{
				printf("The stack is full!\n");
				exit(OVERFLOW);
			}
           else 
                S->selem[0][S->top[0]] = ch;//
		}
	}
	if(i==1)                                 			
	{ // 建立栈Stack1
		while((ch = getchar())!='\n')
		{
			S->top[1]--;
			if(S->top[1] <= S->top[0])
			{
				printf("The stack is full!\n");
				exit(OVERFLOW);
			}
            else 
				S->selem[1][S->top[1]] = ch;//
		}
	}
	return OK;
}

int GetTop_DSeq(PDSeqStack S, int i, char *e)     
{ // 取栈顶元素。若栈 i 非空,用变量 *e 返回栈顶元素
    if(i==0)
	{
        if(S->top[0] <= -1)//
		{
            printf("The stack%d is NULL!\n",i);
            return ERROR;
        }
        else 
            *e = S->selem[0][S->top[0]];///
	}
    if(i==1)
	{
	    if(S->top[1] >= S->MAXSIZE)///
		{
            printf("The stack%d is NULL!\n",i);
            return ERROR;
        }
        else 
            *e = S->selem[1][S->top[1]];///
	}
	return OK;
}// end GetTop_DSeq


int GetDepth_DSeq(PDSeqStack S, int i)    
{  // 求栈i中元素的个数。
	int t,p1,p2;
	p1 = S->top[0];//
	p2 = S->top[1];//
	if(i==0)
	{
		for(t=0; p1 >-1; t++,p1--);
	}
	if(i==1)
	{
		for(t=0; p2<S->MAXSIZE; t++,p2++);
		
	}
	return t;
}

void main( )
{
	DSeqStack s;
    PDSeqStack S;
	int i,t,k;
	char e;
	S = &s;
	InitStack_DSeq(S);
	printf("Enter 0 for the left stack0 operation\n");
	printf("Enter 1 for the right stack1 operation:");
	for(;;)
	{
		printf("\n1: createstack, 2: gettop, 3: getlength. please enter k=");
		scanf("%d",&k);
		//fflush(stdin);         // 清除回车键
		switch(k)
		{
		   case 1: printf("\n now begin CreateStack_DSeq: please Enter i=");
			       scanf("%d",&i);
                   fflush(stdin); 
		           if(i==0)
				   {
			           printf("Input the datas of char to the stack 0: ");
			           CreateStack_DSeq(S,0);
				   }
				   if(i==1)
				   {
                       printf("Input the datas of char to the stack 1: ");
			           CreateStack_DSeq(S,1);
				   }
				   break;
		   case 2: printf("\n now begin GetTop of stack. please Enter i=");
			       scanf("%d",&i);
				   //fflush(stdin); 
                   if(i==0)
				   {
			           if(GetTop_DSeq(S,0,&e))
					       printf("\nThe data on the top  of the left stack0 is %c",e);
					   else
						    printf("The left stack0 is empty!\n");
				   }
				   if(i==1)
				   {
                       if(GetTop_DSeq(S,1,&e))
						   printf("\nThe data on the top  of the left stack1 is %c",e);
					   else
                           printf("The left stack1 is empty!\n");
				   }
				   break;
		   case 3: printf("\n now begin GetDepth of stack. please Enter i=");
			       scanf("%d",&i);
                   //fflush(stdin); 
				   if(i==0)
				   {
			           t=GetDepth_DSeq(S,0);
					   printf("the depth of the left stack0 is %d\n",t);
				   }
				   if(i==1)
				   {
                       t=GetDepth_DSeq(S,1);
			           printf("the depth of the right stack1 is %d\n",t);
				   }
				   break;
		   default: exit(0);
		}//endswitch
	}//endfor
}//endmain

4.思考题
(1)如何用函数实现栈中元素的出栈操作?试修改上述程序,对于一个非空栈,实现删除栈顶元素,并由变量e返回其值的算法

int DeleteTop_DSeq(PDSeqStack S,int i,char *e)
{
	//取栈顶元素、若栈i非空,用变量*e返回栈顶元素
	if(i==0)
	{
		if(S->top[0] <= -1)
		{
			printf("The stack%d is NULL!\n",i);
			return ERROR;
		 }
		else
			*e = S->selem[0][S->top[0]];
			S->top[0]--;
	}
	if(i==1)
	{
		if(S->top[i] >= S->MAXSIZE)
		{
			printf("The stack%d is NULL!\n");
			return ERROR;
		}
		else
			*e = S->selem[1][S->top[1]];
			S->top[0]++;
	}
	return OK;
}//end DeleteTop_DSeq


Int main()
{
  ......
     While ....
            .......
            case 4:printf("\n now begin DeleteTop of stack.please Enter i= ");
				scanf("%d",&i);
				//fflush(stdin);
				if(i==0)
				{
					if(DeleteTop_DSeq(S,0,&e))
						printf("\nThe data on the top of the left stack0 is %c",e);
					else
						printf("The left stack0 is empty!\n");
				}
				if(i==1)
				{
					if(DeleteTop_DSeq(S,1,&e))
						printf("\nThe data on the top  of the left stack1 is %c",e);
					else
						printf("The left stack1 is empty!\n");
				}
				break;
}

(2)在栈的操作中,栈满时仍进行入栈操作称为“上溢”,栈空时仍进行出栈操作称为“下溢”,试分析这两种溢出中的哪一种是正常现象?哪一种是错误状态。

栈溢出属于系统重大漏洞,这种漏洞将会产生相当严重网络安全事件。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值