堆和栈的使用


栈和队列应用实例

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;
    
}
复制代码



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值