栈和队列应用实例
1.迷宫问题
迷宫问题的存储,二维数组,用0表示通路,1表示阻断,对于m*n的迷宫,最多有m*n的栈容量即可。
算法思想:从点p(i,j)向8个方向搜索路径,如果相邻的下一个点q(x,y)是0,表示p可以到达q点,设q为已访问过点并入栈,如果8个方向都找不到,这该p点是死点,出栈。重新对栈顶元素继续搜索。直到到达(m.n)出口节点。时间复杂度是O(n*m)
1 const static int n=12; 2 const static int p=15; 3 4 struct node{ 5 short int row; 6 short int col; 7 }; 8 9 int mark[n][p]; //用于记录迷宫的点是否已经走过 10 int maze[n][p]={0,1,0,0,0,1,1,0,0,0,1,1,1,1,1, 11 1,0,0,0,1,1,0,1,1,1,0,0,1,1,1, 12 0,1,1,0,0,0,0,1,1,1,1,0,0,1,1, 13 1,1,0,1,1,1,1,0,1,1,0,1,1,0,0, 14 1,1,0,1,0,0,1,0,1,1,1,1,1,1,1, 15 0,0,1,1,0,1,1,1,0,1,0,0,1,0,1, 16 0,1,1,1,1,0,0,1,1,1,1,1,1,1,1, 17 0,0,1,1,0,1,1,0,1,1,1,1,1,0,1, 18 1,1,0,0,0,1,1,0,1,1,0,0,0,0,0, 19 0,0,1,1,1,1,1,0,0,0,1,1,1,1,0, 20 0,1,0,0,1,1,1,1,1,0,1,1,1,1,0, 21 }; 22 23 struct node dir[8]={{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}}; 24 25 void search_path() 26 { 27 struct node start={0,0}; 28 struct node end={n-1,p-1}; 29 struct node next; //下一个节点 30 stack<struct node> stack; 31 stack.push(start); 32 bool found=0; 33 mark[start.row][start.col]=1; 34 while (!stack.isEmpty()&&!found) 35 { 36 next=stack.Top(); 37 for (int i=0;i<8;i++) 38 { 39 int row=next.row+dir[i].row; 40 int col=next.col+dir[i].col; 41 if(row<0 ||row>n-1 ||col<0 ||col>p-1) 42 { 43 continue; //不满足便捷条件 44 } 45 else if(next.row==end.row&&next.col==end.col) 46 { 47 //出口点 48 stack.push(next); 49 found=true; 50 break; 51 } 52 else if (!maze[row][col]&&!mark[row][col]) 53 { 54 //下一个点没有走过并且的可以通路德 55 mark[row][col]=1; 56 next.row=row; 57 next.col=col; 58 stack.push(next); 59 i=-1; 60 } 61 else 62 continue; 63 } 64 stack.pop(); 65 66 } 67 68 if (found) 69 { 70 cout<<"the path is:"<<endl; 71 stack_list<struct node> stack_new; 72 while(!stack.isEmpty()) 73 { 74 stack_new.push(stack.Top()); 75 stack.pop(); 76 } 77 int i=1; 78 while (!stack_new.isEmpty()) 79 { 80 cout<<"("<<stack_new.Top().row<<","<<stack_new.Top().col<<")->"; 81 if(i++%5==0) 82 cout<<endl; 83 stack_new.pop(); 84 } 85 } 86 else 87 cout<<"the maze does not have a path"<<endl; 88 }
2.判断括号匹配 () [] {}
基本栈运用
1 bool isMatch(const char * str) 2 { 3 const char *p=str; 4 stack_list<char> stack; 5 char temp; 6 bool match=true; 7 while (*p) 8 { 9 if (!match) 10 break; 11 switch (*p) 12 { 13 case '(': 14 case '[': 15 case '{': 16 stack.push(*p); 17 break; 18 case ')': 19 case ']': 20 case '}': 21 if(stack.isEmpty()) 22 { 23 match=false; 24 }else 25 { 26 temp=stack.Top(); 27 stack.pop(); 28 switch(temp) 29 { 30 case '(': 31 if (*p!=')') 32 match=false; 33 break; 34 case '[': 35 if (*p!=']') 36 match=false; 37 break; 38 case '{': 39 if (*p!='}') 40 match=false; 41 break; 42 default: 43 match=false; 44 } 45 } 46 break; 47 default: 48 break; 49 } 50 p++; 51 } 52 if(match&&stack.isEmpty()) 53 { 54 cout<<"match"<<endl; 55 return true; 56 57 }else 58 { 59 cout<<"not match"<<endl; 60 return false; 61 } 62 63 }
3.表达式求值
中缀表达式 -> 后缀表达式 ->求值
如:2+3*4 ->234*+ ;a*b+5 ->ab*5+;((a/(b-c+d)))*(e-a)*c -> abc-d+/*ea-c*
3.1 中缀转后缀
维持一个操作符栈,新的输入操作符op
1 op优先级大于栈顶元素优先级,则op入栈,
2 如果栈顶元素是“(”,这op直接入栈,
3 如果priority(op)小于栈顶元素的优先级,这出栈输出到后缀表达式,op入栈
如果输入数据不是操作符,直接输出到后缀表示中,如果输入结束,出栈直到栈空
3.2 后缀求值
维持一个操作数栈,如果输入是操作数,进栈,如果是运算符,这如果是双目,依次弹出两个元素并对数据求值,在压入栈中。
//运算符定义优先级 int priority(const char token) { int pri=0; switch(token) { case '(': pri=0; break; case '*': case '/': case '%': pri=1; break; case '+': case '-': pri=2; break; default: pri=-1; break; } return pri; } //判断是否操作符 bool isoperator(const int token) { switch(token) { case '(': case ')': case '*': case '/': case '%': case '+': case '-': return true; default: return false; } } static stack_list<int> op_stack; //操作符栈 //中缀表达式到后缀表达式转化 char * infix2suffix(const char *str,char *result) { const char *ps=str; char *pr=result; char *p=NULL; char token; int pri=0; char name[16]=""; while (*ps) { token=*ps; if (isspace(token)) //空白符 { ps++; }else if (isdigit(token)|| token=='.') //数字 { while (!isoperator(*ps)&&*ps) { *pr++=*ps; ps++; } }else if (isoperator(token)) //操作符 { *pr++=' '; char top=0; if (op_stack.isEmpty()) { op_stack.push(token); ps++; continue; } else { top=op_stack.Top(); } if(token=='(') { op_stack.push(token); }else if(token==')') { top=op_stack.Top(); while (top!='('&&!op_stack.isEmpty()) { *pr++=' '; *pr++=top; op_stack.pop(); top=op_stack.Top(); } if (op_stack.isEmpty()) { cout<<"() not match"<<endl; } else op_stack.pop(); } else if(priority(token)<priority(top)) { op_stack.push(token); }else { op_stack.pop(); *pr++=top; *pr++=' '; } ps++; } else if(isalpha(token)) //函数字母 { int i=0; while (*ps!='(') { name[i++]=*ps; ps++; } name[i++]=' '; cout<<name<<endl; } else { cout<<"error unkown symbol"<<endl; } } if(!op_stack.isEmpty()) { *pr++=' '; *pr++=op_stack.Top(); op_stack.pop(); if(!op_stack.isEmpty()) cout<<"expression error 1"<<endl; } *pr=0; return result; }