栈和队列应用实例
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;
}

浙公网安备 33010602011771号