栈:是插入和删除只能在一端进行的线性表

例:线性表(a1...a5)进栈出栈示意图


栈的特点:有序性,先进后出,后进先出。栈指针永远指向栈顶。


向栈顶压如一个元素item,

if(top==MaxStackSize - 1){

 //判断是否栈满

}

top++;//先修改指针,再插入元素

StackList[top] = item; // StackList是一个数组


从栈顶删除一个元素

if(top= -1 ){//如果栈顶指针为-1,则为空栈

// 判断是否为空

}

temp = StackList[top];//先将元素赋值给临时变量以便使用

top--;//然后栈顶指针向下移动

return temp;


读栈顶元素(只读不删不改)

先判断栈是否为空,然后 return StackList[top];


判断栈是否为空


return top == -1;//栈空


判断栈是否为满


return top == MaxStackSize - 1 ;//栈满


栈的应用--迷宫探索


Status Pass(MazeType MyMaze, PosType CurPos);
void FootPrint(MazeType &MyMaze, PosType CurPos);
void MarkPrint(MazeType &MyMaze, PosType CurPos);
PosType NextPos(PosType CurPos, int Dir);


Status MazePath(MazeType &maze, PosType start, PosType end) {  
  // 若迷宫maze中从入口 start到出口 end的通道,则求得一条存放在栈中
  // (从栈底到栈顶),并返回TRUE;否则返回FALSE
  Stack S;
  PosType curpos;
  int curstep;
  SElemType e;


  InitStack(S);
  curpos = start;  // 设定"当前位置"为"入口位置"
  curstep = 1;     // 探索第一步
  do {
    if (Pass(maze,curpos)) {  // 当前位置可通过,即是未曾走到过的通道块
      FootPrint(maze,curpos); // 留下足迹
      e.di =1;
      e.ord = curstep;
      e.seat= curpos;
      Push(S,e);              // 加入路径
      if (curpos.r == end.r && curpos.c==end.c)  
        return (TRUE);        // 到达终点(出口)
      curpos = NextPos(curpos, 1);        // 下一位置是当前位置的东邻
      curstep++;                          // 探索下一步
    } else {  // 当前位置不能通过
      if (!StackEmpty(S)) {
        Pop(S,e);
        while (e.di==4 && !StackEmpty(S)) {
          MarkPrint(maze,e.seat);  
          Pop(S,e);    // 留下不能通过的标记,并退回一步
        } // while
        if (e.di<4) {
          e.di++;
          Push(S, e);  // 换下一个方向探索
          curpos = NextPos(e.seat, e.di); // 当前位置设为新方向的相邻块
        } // if
      } // if
    } // else
  } while (!StackEmpty(S) );
  return FALSE;
} // MazePath


Status Pass( MazeType MyMaze,PosType CurPos) {
  if (MyMaze.arr[CurPos.r][CurPos.c]==' ')
    return 1;     // 如果当前位置是可以通过,返回1
  else return 0;  // 其它情况返回0
}


void FootPrint(MazeType &MyMaze,PosType CurPos) {
  MyMaze.arr[CurPos.r][CurPos.c]='*';
}


void MarkPrint(MazeType &MyMaze,PosType CurPos) {
  MyMaze.arr[CurPos.r][CurPos.c]='!';
}


PosType NextPos(PosType CurPos, int Dir) {
  PosType ReturnPos; 
  switch (Dir) {
    case 1:
        ReturnPos.r=CurPos.r;
        ReturnPos.c=CurPos.c+1;
        break;
    case 2:
        ReturnPos.r=CurPos.r+1;
        ReturnPos.c=CurPos.c;
        break;
    case 3:
        ReturnPos.r=CurPos.r;
        ReturnPos.c=CurPos.c-1;
        break;
    case 4:
        ReturnPos.r=CurPos.r-1;
        ReturnPos.c=CurPos.c;
        break;
  }
  return ReturnPos;
}


栈的应用--算符间的优先关系

#define OPSETSIZE 7
unsigned char Prior[7][7] = {     
  	  '>','>','<','<','<','>','>',
	  '>','>','<','<','<','>','>',
	  '>','>','>','>','<','>','>',
	  '>','>','>','>','<','>','>',	
	  '<','<','<','<','<','=',' ',
	  '>','>','>','>',' ','>','>',
	  '<','<','<','<','<',' ','='
};		
float Operate(float a, unsigned char theta, float b);
char OPSET[OPSETSIZE]={'+' , '-' , '*' , '/' ,'(' , ')' , '#'};
Status In(char Test,char* TestOp);
char precede(char Aop, char Bop);
		
float EvaluateExpression(char* MyExpression) {  // 算法3.4
   // 算术表达式求值的算符优先算法。
   // 设OPTR和OPND分别为运算符栈和运算数栈,OP为运算符集合。
   StackChar  OPTR;    // 运算符栈,字符元素
   StackFloat OPND;    // 运算数栈,实数元素
   char TempData[20];
   float Data,a,b;
   char theta,*c,x,Dr[2];
   
   InitStack (OPTR);
   Push (OPTR, '#');
   InitStack (OPND);
   c = MyExpression;
   strcpy(TempData,"\0");
   while (*c!= '#' || GetTop(OPTR)!= '#') {
      if (!In(*c, OPSET)) {
      	 Dr[0]=*c;
      	 Dr[1]='\0';
         strcat(TempData,Dr);
         c++;
         if(In(*c,OPSET)) {
            Data=(float)atof(TempData);
            Push(OPND, Data);
            strcpy(TempData,"\0");
         }
      } else {   // 不是运算符则进栈
         switch (precede(GetTop(OPTR), *c)) { 
            case '<':   // 栈顶元素优先权低
                 Push(OPTR, *c);  
                 c++;
                 break;
            case '=':   // 脱括号并接收下一字符
                 Pop(OPTR, x);   
                 c++;
                 break;
            case '>':   // 退栈并将运算结果入栈
                 Pop(OPTR, theta);
                 Pop(OPND, b);  
                 Pop(OPND, a);                      
                 Push(OPND, Operate(a, theta, b)); 
                 break;
         } // switch
      }
   } // while
   return GetTop(OPND);
} // EvaluateExpression

float Operate(float a,unsigned char theta, float b) {
   switch(theta) {
      case '+': return a+b;
      case '-': return a-b;
      case '*': return a*b;
      case '/': return a/b;
      default : return 0;
   } 
}	

Status In(char Test,char* TestOp) {
   bool Find=false;
   for (int i=0; i< OPSETSIZE; i++) {
      if (Test == TestOp[i]) Find= true;
   }
   return Find;
}


int ReturnOpOrd(char op,char* TestOp) {
   int i;
   for(i=0; i< OPSETSIZE; i++) {
      if (op == TestOp[i]) return i;
   }
   return 0;
}

char precede(char Aop, char Bop) {
   return Prior[ReturnOpOrd(Aop,OPSET)][ReturnOpOrd(Bop,OPSET)];
}




当程序需要多个栈的时候--链式栈


将链表和栈联合使用,将top用数组进行使用。







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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值