数据结构----栈

1.定义:限定仅在表尾进行插入或删除操作的线性表。

   表尾:栈顶

   表头:栈底

   不含元素的空表称空栈。

2.特点:先进后出(FILO)或后进先出(LIFO)


3.栈的基本操作

InitStack(S)                 Push(S,x)

ClearStack(S)              Pop(S,x)

IsEmpty(S)                  GetTop(S,x)

IsFull(S)

4.栈的表示和实现

栈在计算机中主要有两种基本的存储结构:

顺序存储结构--------顺序栈

链式存储结构--------链栈

5.顺序栈:利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素,同时附设指针top指示栈顶元素在顺序栈中的位置。

   顺序栈的类型说明:

   typedef struct{

         ElemType  elem[Stack_Size];

         int top;

     }SeqStack;

吐舌头说明:top == -1,表示栈空;

                       top ==stacksize-1,表示栈满;

                       每插入一元素时,top加1;

                        每删除一元素时,top减1;


6.顺序栈的基本操作

//顺序栈的初始化

void  InitStack ( SeqStack  * s ) 
 {
      S->top= -1;
} 

//顺序栈的判空

int   IsEmpty ( SeqStack  * s )  
{
     if ( S->top= =-1 )  
           return 1;
     else  
           return 0;
} 

//顺序栈的判满

int  IsFull ( SeqStack  * s )  
{
     if ( S->top = = Stack_Size-1 )  
           return 1;
     else  
          return 0;
} 

//顺序栈的入栈

int  Push ( SeqStack *S, ElemType e ) 
{
     if(S->top==Stack_Size-1)    return FALSE; 
     S->top++; 
     S->elem[S->top]=e;
     return TRUE;
}

//顺序栈的出栈

int  Pop ( SeqStack *S, ElemType *e ) 
{
      if ( S->top== -1 )    return FALSE;
      *e=S->elem[S->top];
      S->top--; 
      return TRUE;
} 

//顺序栈读取栈顶元素

int  GetTop ( SeqStack *s, ElemType *e ) 
{
     if ( S->top== -1 )   return FALSE;
     *e=S->elem[S->top];
     return TRUE;
} 

两栈共享技术

原因:若在一个程序中要同时使用多个栈,如果采用顺序存储结构,会因为栈空间大小难以准确估计,产生有的栈溢出,有的栈还很空闲的情况,故产生了两栈共享技术。

特点:栈底位置不变,而栈顶位置动态变化。

首先为两个栈申请一个共享的一段存储空间S[M],然后将两个栈的栈底分别放在存储空间的两段,分别是0,M-1。

//两栈共享的数据结构定义

#define  M  100
typedef struct
{
    ElemType Stack[M];
    int top[2];
} DqStack;

//两栈共享的初始化

void InitStack ( DqStack *S )
{
      S->top[0]=-1;
      S->top[1]=M;
}

//两栈共享的入栈操作

int Push(DqStack *S, ElemType x, int i)
{  if(S->top[0]+1==S->top[1])  return(FALSE);  
    switch(i)
    { case 0: S->top[0]++; S->Stack[S->top[0]]=x;  break;
      case 1: S->top[1]--; S->Stack[S->top[1]]=x;  break;
      default:  return(FALSE);
    }
    return(TRUE);
}

//两栈共享的出栈操作

int Pop(DqStack *S, ElemType *x, int i)
{  switch(i)
   { case 0:  if(S->top[0]==-1)  return(FALSE); 
              *x=S->Stack[S->top[0]]; S->top[0]--;  break;
     case 1: if(S->top[1]==M)  return(FALSE);  
	       *x=S->Stack[S->top[1]]; S->top[1]++;  break;
     default: return(FALSE);
   }
   return(TRUE);
}


链栈

1.定义

2.链栈的结点类型

typedef struct node
{
   ElemType  data;
   struct node *next;
}LinkStackNode, *LinkStack;

3.链栈的入栈操作

int Push(LinkStack top, ElemType x) {
   temp=( )malloc(sizeof(LinkStackNode));
   if(!temp)  return FALSE;
   temp->data=x; 
   temp->next=top->next;
   top->next=temp;   /* 修改当前栈顶指针 */ 
   return TRUE;
}

4.链栈的出栈操作

int Pop(LinkStack top, ElemType *x) {
    temp=top->next;
    if(temp==NULL) return FALSE; /*栈为空*/
    top->next=temp->next; 
    *x=temp->data;
    free(temp);   /* 释放存储空间 */
    return TRUE;
}

栈的应用

1.数制转换
//十进制数转换成二进制数
void Conversion(int N) 
{  Stack S; int x;      /*S为顺序栈或链栈*/
    InitStack(&S);
	while(N)
	{ x=N%2; Push(&S, x); N=N/2; }
	 while(!IsEmpty(S))
	{ Pop(&S,&x); printf(“%d”,x); }
}

//十进制数转换成K进制数

void Conversion(int N,int base) 
{  Stack S; int x;      /*S为顺序栈或链栈*/
    InitStack(&S);
	while(N)
	{ x=N%base; Push(&S, x); N=N/base; }
	 while(!IsEmpty(S))
	{ Pop(&S,&x); 
     if(x<10) printf(“%d”,x);
     else printf(“%c”,x+55); }
}

2.括号匹配问题

算法思想:

在检验算法中设置一个栈,依次读入表达式中的括号。

若读入的是左括号,则直接入栈,等待相匹配的同类右括号;

若读入的是右括号,且与当前栈顶的左括号同类型,则二者匹配,将栈顶的左括号出栈,否则属于不合法的情况。

如此反复,直到:

输入序列和栈同时变为空,说明所有括号完全匹配;

输入序列已读尽,而栈中仍有等待匹配的左括号,说明括号不匹配,表达式不合法;

或者读入了一个右括号,而栈中已无等待匹配的左括号,同样属于不合法的情况。

3.回文游戏

4.表达式求值

5.函数的调用

6.Tower of Hanoi问题

问题描述:有A,B,C三个塔座,A上套有n个直径不同的圆盘,按直径从小到达叠放,形如宝塔,编号1,2,3......n。

要求:将n个原盘从A移动到C,叠放顺序不变,移动过程中遵循下列原则:

每次只能移一个圆盘,

圆盘可在三个塔座上任意移动,

任何时刻,每个塔座上不能将大盘压到小盘上。

解决方法:

n=1时,直接把圆盘从A移到C

n>1时,先把上面n-1个圆盘从A移到B

              然后将n号盘从A移到C

              再将n-1个盘从B移到C

即把求解n个圆盘的Hanoi问题转化为求解n-1个圆盘的Hanoi问题,依次类推,直至转化成只有一个圆盘的Hanoi问题

//Hanoi算法

void hanoi(int n,char x,char y,char z) {
  if(n==1)  move(1,x,z);
  else{
     hanoi(n-1,x,z,y);
     move(n,x,z);
     hanoi(n-1,y,x,z);
  }
}

void move( int n,char x,char y )
{ printf(“%d:%c%c\n”,n,x,y); }

7.迷宫问题




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值