【3 栈和队列】

栈和队列的定义和特点

  • 栈和队列是限定插入和删除只能在表的“端点”进行的线性表
  • 栈:插入和删除只能在表尾进行,特点:先进后出
  • 队列:插入在表尾插入,删除在表头删除。特点:先进先出
  • 栈是一个特殊的线性表,是限定尽在一端(通常是表尾)进行插入和删除操作的线性表。
  • 又称后进先出的线性表,简称LIFO(Last In First Out)结构。
  • 表尾称为栈顶top,表头称为栈底base。
  • 在栈中插入元素的操作,插入到栈顶(表尾),叫入栈(压栈)。从栈顶删除一个元素叫出栈(弹栈 )。

栈的抽象数据类型的定义

ADT Stack{
   	数据对象:D={ai|ai∈Elemset,i=1,2,...n,n≥0}
   	数据关系:{<ai-1,ai>|ai-1,ai∈D,i=2,...n,n≥0}
   	数据操作:入栈、出栈、求栈顶元素等

//———————————————————这是一条分割线———————————————————————//	
 InitStack(&S)//操作结果,构造一个空栈S。
 DestoryStack(&S)	//销毁栈操作
	 初始条件:栈S已经存在
	 操作结果:栈S被销毁
StackEmpty(S) //判断栈S是否为空
	 初始条件:栈S已经存在
	 操作结果:如果为空,返回true;反之返回False。
StackLength(S)//求解栈的长度
	初始条件:栈已经存在
	操作结果:返回S的元素个数,即栈的长度
	GetTop(S,&e)//获取栈顶元素
	初始条件:S已经存在
	操作结构:用e返回S的栈顶元素
ClearStack (&S) //清空一个栈S
	初始条件:S已经存在
	操作结果:获得一个空栈
Push(&S,e)
	初始条件:栈S已经存在。
	操作结果:插入元素e为新的栈顶元素
Pop(S,&e)
	初始条件:栈S已经存在。
	操作结果:获取栈顶元素并用e返回。
}ADT Stack

顺序栈的表示和实现

在这里插入图片描述

  • 设置top指针指向栈顶元素,另设base指针指向栈底元素。
  • 通常情况下,为了方便操作,让top指针指向栈顶元素之上下表地址,如图所示。
  • 使用stacksize表示栈可使用的最大容量。
  • 栈空标志,base==top
  • 栈满标志:top-base=stacksize,栈满可以出栈;栈满不可以入栈,会导致溢栈;
  • 溢栈分文两种:
    上溢:栈满还要压入元素;(是一种错误类型,使问题的处理无法进行)
    下溢:栈空还要弹出元素(是一种结束条件,即问题处理结束)

顺序栈的定义

#define Maxsize 100
typedef struct SqStack
{
	SElemtype *base;//栈底指针
	SElemType *top; //栈顶指针
	int Stacksize;//栈的最大可使用容量
}

顺序栈上的操作

  • 顺序栈的初始化

     Status InitStack(Sqstack &S){
     	S.base=new SElemType[MAXSIZE];//或者S.base=(SElemType*)malloc(MAXSIZE*sizeof(SElemtype));
     	if(!S.base)
     		exit(OVERFLOW);
     		S.top=S.base;
     		Stacksize=MAXSIZE;
     		return OK;
     }
    
  • 判断顺序栈是否为空

     Status StackEmpty(Sqstack S)
     {
     	if(S.base==S.top)
     		return TRUE;
     	else
     		return FALSE;
     }
    
  • 求顺序栈的长度

     int StackLength(S,int &e)
     	{
      		e=S.top-S.base;
      		return e;
     	}
    
  • 清空顺序栈

     Status ClearStack (SqStack &S) 
     {
     	if(S.base)
     		else S.top=S.base;
     	return OK;
     }
    
  • 销毁顺序栈

     Status DestoryStack (SqStack S) 
     {
     	if(S.base)
     	{
     		delete S.base;
     		S.stackSize=0;
     		S.base=S.top=NULL;
     	}
     	return OK;
     }
    
  • 顺序栈的入栈

     	Status Push (SqStack &S,SElemType e) 
     {
     	if(S.top-S.bazs==Stacksize)	//栈满
     		return ERROR;
     	else 
     	     *S.top=e;
     		S.top++;
     	return OK;
     }			
    
  • 顺序栈的出栈

     Status Push (SqStack &S,SElemType &e) 
     {
     	if(!S.base==S.top)
     	{	
     	    --S.top;	  
     		e=*S.top;
     	 }
     	 else return ERROR;
     	return OK;
     }	
    

链栈的表示和实现

链栈的定义

  • 链栈是运算受限的单链表,只能在链表的头部进行操作。

     #define Maxsize 100
     typedef struct StackNode		
     {
     	SElemType data;//数据域
     	struct StackNode *next;
     }StackNode,*LinkStack;
     LinkStack S;
    

注意:

  • 链栈当中指针方向和单链表的指针方向相反
  • 头指针指向栈顶
  • 链栈中没有头结点。
  • 基本不存在栈满的情况。
  • 空栈相当于头指针指向空。
  • 插入和删除只在栈顶进行。

链栈上的操作

  • 链栈的初始化

     Void InitStack(Linkstack &S)
     {
     S=null;
     return OK;
     }
    
  • 判断链栈是否为空

       Void LinkStackEmpty(Linkstack &S)
      {
      if(S=null)return true;
      else  return False;
      }
    
  • 链栈的入栈

      Status Push(Linkstack &S,LinkNode e)
      {
      p=new StackNode;
      p->data=e;
      P->next=S;
      S=p
      return ok ;
      }
    
  • 链栈的出栈

      Status Pop(Linkstack &S,LinkNode &e)
      {
      	p=new StackNode;
      	if(S=NULL)return ERROR;
      	e=S->data;		//出栈的元素值保存在e中
      	p=S:
      	S=S->next;
      	delete p;
      	return OK;
      }
    
  • 取链栈栈顶元素

      SElemType GetTop(Linkstack S)
      {
      	if(S!=NULL) 
      	return S->data;
      }
    

队列

  • 队列是一个特殊的线性表,是限定在表尾进行插入,在表头进行删除。
  • 又称先进先出的线性表,简称FIFO(First In First Out)结构。
  • 插入元素称为入队,删除元素称为出队。
  • 队列的存储结构称为链队或顺序队。(常用循环顺序队)

队列的抽象数据类型定义

ADT Queue{
   	数据对象:D={ai|ai∈Elemset,i=1,2,...n,n≥0}
   	数据关系:{<ai-1,ai>|ai-1,ai∈D,i=2,...n,n≥0}
   	数据操作:入栈、出栈、求栈顶元素等

//———————————————————这是一条分割线———————————————————————//	
 InitQueue(&Q)//操作结果,构造一个空队列Q。
 DestoryQueue(&Q)	//销毁队列Q操作
	 初始条件:队列Q已经存在
	 操作结果:队列Q被销毁
QueueEmpty(Q) //判断队列Q是否为空
	 初始条件:队列Q已经存在
	 操作结果:如果为空,返回true;反之返回False。
QueueLength(Q)//求解队列Q的长度
	初始条件:队列Q已经存在
	操作结果:返回队列Q的元素个数,即队列Q的长度
GetHead(Q,&e)//获取栈顶元素
	初始条件:队列Q已经存在
	操作结构:用e返回队列Q的队头元素
ClearQueue (&Q) //清空一个队列Q
	初始条件:队列Q已经存在
	操作结果:获得一个空栈
EnQueue(&Q,e)
	初始条件:队列Q已经存在。
	操作结果:插入元素e为新的队尾元素
DeQueue(Q,&e)
	初始条件:队列Q已经存在。
	操作结果:删除对头元素并用e返回。
}ADT Queue

顺序队列的表示和实现

顺序队列的定义

#define MAXSIZE 100
Typedef struct{
	QElemType *base;
	int front ;//头指针
	int rear;//尾指针,表示下表,并非真的指针
}SqQueue;

顺序队列上的操作

  • 顺序循环栈的初始化

      Status InitQueue(SqQueue &Q){
      	Q.base=new QElemType[MAXQSIZE];//或者Q.base=(QElemType*)malloc(MAXQSIZE*sizeof(QElemtype));
      	if(!Q.base)
      		exit(OVERFLOW);
      	Q.front=Q.near=0;
      	return OK;
      }
    
  • 求循环顺序队列的长度

     int QueueLength(Q,int &e)
     	{
      		e=(Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
      		return e;
     	}
    
  • 顺序队列的出队

     	Status DeQueue (SqQueue &Q,QElemType &e) 
     {
     	if(Q.rear=Q.front)//队空
     		return ERROR;	
     	e=Q.base[Q.front];//队头删除元素值
     	Q.front=(Q.front+1)%MAXQSIZE;//头指针加1
     	return OK;
     }			
    
  • 顺序队列的入队

     Status EnQueue (SqQueue &Q,QElemType e) 
     {
     if((Q.rear+1)%MAXQSIZE==Q.front)//队满
     	 return ERROR; 
     Q.base[Q.rear]=e;  //队尾插入
     Q.rear=(Q.rear+1)%MAXQSIZE;	//队尾指针加1
     return OK;
     }	
    
  • 取队头元素

      QElemType GetHead(SqQueue Q,QElemType e)
       {
      	 if(Q.front=Q.rear)		//队空
      	 	return ERROR;
      	 return Q.base[Q.front]		//返回指针元素,队头指针不变
       }
    

链式队列的表示和实现

链式队列的定义

在这里插入图片描述

	//----------定义结点-------------//
	#define MAXSIZE 100
	Typedef QNode{
		QElemType data;
		Struct Qnode *next;
	} QNode,*QueuePtr;
	//----------定义队列-------------//
	Typedef struct{
		QueuePtr front;
		QueuePtr rear;
	}LinkQueue;

链式队列上的操作

  • 链队列的初始化

      Status InitQueue(LinkQueue &Q)
      {
      	Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
      	Q.front->next=NULL;
      	return OK;
      }
    
  • 链队列的销毁

      Status DestoryQueue(LinkQueue &Q)
      {
      	while(!Q.front)
      	{
      		p=Q.front->next;		//指向下一结点
      		free (Q.front);
      		Q.front=p;
      	} 
      	return OK;
      } 
    
  • 链队列的入队

在这里插入图片描述

	Status EnQueue(LinkQueue &Q,QElemtype e)
	{
		p=(QueuePtr)malloc(sizeof(Qnode));
		if(!p)		exit(OVERFLLLOW);
		p->data=e;
		p->next=NULL;
		Q.rear->next =p;
		Q.rear=p;
		return OK;
	} 
  • 链队列的出队

      Status DeQueue(LinkQueue &Q,QElemtype &e)
      		{
      			if(Q.front=Q.rear)//队空
      				return error;
      			p=Q.front->next;
      			e=p->data;
      			Q.front->next=p->next;
      			if(Q.rear==p) //删除为尾结点,需要修改尾指针
      					Q.rear=Q.front;
      			delete p;
      			return OK;
      		} 
    
  • 链队列的队头

  •   Status GetHead(LinkQueue Q,QElemtype &e)
      	{
      		if(Q.front=Q.rear)//队空
      			return error;
      		e=Q.front->next->data;
      		return e;
      	} 
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值