数据结构-栈和队列应用之八皇后与表达式求值

八皇后问题

/* 
八皇后问题是在8x8的国际象棋棋盘上,安放8个皇后,要求没有一个皇后能够"吃掉"任何其他一个皇后, 
即没有两上或两个以上的皇后占据棋盘上的同一行、同一列或同一条对角线。 
 
算法描述: 
    1.置当前行当前列均为1; 
    2.while(当前行号<=8) 
    3.{检查当前行,从当前列起逐列试探,寻找安全列号; 
    4.    if(找到安全列号) 
    5.        放置皇后,将列号记入栈中,并将下一行置成当前行,第1列置为当前列; 
    6.    esle 
    7.        退栈回溯到上一行,移去该行放置的皇后,以该皇后所在列的下一列作为当前列; 
    8.}结束程序。 
 
     
1.当前行和列用i和j表示。若皇后放在位置(i,j)上,则将j压入栈中,即s[i]=j. 
2.添加三个布尔数组(初始值为真),用于保存与检查有关的信息。 
    enum boolean {false,true}; 
    enum boolean a[9],a[17],a[17]; 
    int s[9]; 
     
    1.其中 a[j]为真时,表示第j列上无皇后。 
    2.b[k]:表示 "/"方向的第 k 条对角线上无皇后。 
    3.c[k]:表赤 "\"方向的第 k 条对角线上无皇后。  
     
    位于同一条 "/"方向的对角线上的诸方格,其行、列坐标之和 i+j 是相等的,这种方向的对角线有15条, 
    其行列坐标之和分别为2至16,因此用b[2...16]标记该方向的诸对角线上有无皇后,b[k]为真时表 
    示该方向的第 k 条对角线上无皇后。  
     
    行列坐标之差 i-j 相等的诸方格在同一条 "\"方向以对角线上,该类对角线有15条,其行列坐标之差分 
    别是 -7到7 ,因为C语言数组下标是从0开始,所以用 c[2...16]标记这种方向的诸对角线上有无皇后, 
    c[k](k=i-j+9,使其取值范围为2到16),为真时表示该方向的第 k 条对角线上无皇后。 
     
    所以 b[i+j]和c[i-j+9]真假就分别表示了通过位置(i,j)的两条对角线上有无皇后。因此,位置 (i,j) 的 
    "安全" 性可用逻辑表达示: 
            a[j] && b[i+j] && c[i-j+9]      
    来表示。在位置 (i,j) 上放置皇后后,相当于将 a[j],b[i+j]和 c[i-j+9]置为假;移去 (i,j)上的皇后相当 
    于将 a[j],b[i+j]和 c[i-j+9]置为真。   
*/ 
 
enum boolean {false,true}; 
enum boolean a[9],b[17],c[17]; 
int s[9]; 
#include<stdio.h> 
void main() 
{ 
    void print(),movequeen(),eightqueen();    //函数声明 
    eightqueen();                             //求解八皇后  
}  
 
/*******************************************/ 
/**           求解八皇后           **/ 
/*******************************************/ 
void eightqueen() 
{ 
    int i,j; 
    for(i=2;i<=16;i++)             //将棋盘上的所有格子都置为真  
    { 
        if(i>=2 && i<=9) 
            a[i-1]=true;        //将第j列置为真 , 设置成无皇后     
        b[i]=true;                //将"/"方向的第 i 条对角线置为真 , 设置成无皇后 
        c[i]=true;                //将"\"方向的第 i 条对角线置为真 , 设置成无皇后 
    } 
    i=1;j=1;                     //置当前行当前列均为1 
    while(i>=1)                    //当i等于0时终止循环  
    { 
        while(j<=8)                //在当前行i上寻找安全位置 
        { 
            if(a[j] && b[i+j] && c[i-j+9]) 
                break; 
            j++;     
        } 
        if(j<=8)                //找到安全位置(i,j) 
        { 
            a[j]=false; 
            b[i+j]=false; 
            c[i-j+9]=false; 
            s[i]=j;                //皇后位置入栈 
            if(i==8)            //找到一个解,输出解  
            { 
                print();        //打印输出一个解 
                movequeen(i,j);    //移去位置(i,j)上的皇后 
                i=i-1; 
                j=s[i];            //退栈,回溯到上一个皇后 
                movequeen(i,j);    //移去位置(i,j)上的皇后 
                j++;  
            } 
            else 
            { 
                i++;            //准备放置下一个皇后  
                j=1; 
            } 
        } 
        else 
        { 
            i--;                //退栈 
            if(i>=1)            //栈不为空,移去皇后  
            { 
                j=s[i]; 
                movequeen(i,j);    //移去皇后 
                j++;     
            } 
        }  
    } 
} 
 
/*******************************************/ 
/**         打印输出一具解的函数          **/ 
/*******************************************/ 
void print() 
{ 
    int k; 
    printf("\n行号:    1   2   3   4   5   6   7   8\n"); 
    printf("列号:"); 
    for(k=1;k<=8;k++) 
        printf("%4d",s[k]); 
    printf("\n\n");  
}  
 
/*******************************************/ 
/**         移去位置(i,j)上的皇后的函数          **/ 
/*******************************************/ 
 
void movequeen(int i,int j) 
{ 
    a[j]=true; 
    b[i+j]=true; 
    c[i-j+9]=true; 
} 
 

表达式求值

#include<stdio.h> 
#define    StackSize    100 
#define QueueSize    100 
 
/*队列的相关操作*/ 
typedef char DataType; 
typedef struct 
{ 
    char data[100]; 
    int front,rear; 
}SeqQueue;                    //定义队列类型 
 
void InitQueue(SeqQueue *Q)    //初始化队列  
{ 
    Q->front=0; 
    Q->rear=0; 
} 
 
int QueueEmpty(SeqQueue *Q)    //判断空队列 
{ 
    return Q->rear==Q->front;  
} 
 
void EnQueue(SeqQueue *Q,DataType x)    //入队列 
{ 
    if((Q->rear+1)%QueueSize==Q->front) 
        printf("Queue overflow\n"); 
    else 
    { 
        Q->data[Q->rear]=x; 
        Q->rear=(Q->rear+1)%QueueSize;         
    }  
}  
 
DataType DeQueue(SeqQueue *Q)            //出队列  
{ 
    DataType x; 
    if(QueueEmpty(Q)) 
    { 
        printf("Queue Empty\n");  
        return 0; 
    } 
    else 
    { 
        x=Q->data[Q->front]; 
//        free(Q->data[Q->front]); 
        Q->front=(Q->front+1); 
        return x; 
    } 
} 
 
/*栈的相关操作*/ 
typedef struct 
{ 
    DataType data[100]; 
    int top; 
}SeqStack;                                //栈类型的定义 
 
void InitStack(SeqStack *s)                //初始化栈  
{ 
    s->top=-1; 
}  
 
void Push(SeqStack *s,DataType x)        //入栈 
{ 
    if(s->top==StackSize-1) 
    { 
        printf("stack overflow"); 
        return; 
    } 
    else 
    { 
        s->top=s->top+1; 
        s->data[s->top]=x; 
    } 
}  
 
DataType Pop(SeqStack *s)                //退栈 
{ 
    if(s->top==-1) 
    { 
        printf("stack underflow"); 
        return 0; 
    } 
    else 
        return s->data[s->top--];  
}  
 
DataType GetTop(SeqStack *s)                        //取栈顶元素 
{ 
    if(s->top==-1) 
    { 
        printf("stack empty"); 
        return 0; 
    } 
    else 
        return s->data[s->top];  
}  
 
/*求运算符优先级函数*/ 
int Priority(DataType op) 
{ 
    switch(op) 
    { 
        case '(': 
        case '#':return(0); 
        case '-': 
        case '+':return(1); 
        case '*': 
        case '/':return(2); 
    } 
}  
 
void CTPostExp(SeqQueue *Q) 
{ 
    SeqStack OS; 
    char c,t; 
    SeqStack *S; 
    S=&OS; 
    InitStack(S);                        //初始化栈 
    Push(S,'#');                        //压入栈底元素 '#'  
    do                                    //扫描中缀表达式 
    { 
        c=getchar(); 
        switch(c) 
        { 
            case ' ':break;                //去除空格 
            case '1': 
             case '2': 
             case '3': 
             case '4': 
             case '5': 
             case '6': 
             case '7': 
             case '8': 
             case '9': 
                 EnQueue(Q,c); 
                 break; 
             case '(': 
                 Push(S,c); 
                 break; 
             case ')': 
             case '#': 
                 do 
                 { 
                     t=Pop(S); 
                     if(t!='('&&t!='#') 
                         EnQueue(Q,t); 
                 }while(t!='('&&S->top!=-1); 
                 break; 
            case '+': 
            case '-': 
            case '*': 
            case '/': 
                while(Priority(c)<=Priority(GetTop(S))) 
                { 
                    t=Pop(S); 
                    EnQueue(Q,t); 
                } 
                Push(S,c); 
                break; 
        } 
    }while(c!='#');                        //以'#'号结束表达式扫描  
} 
 
int CPostExp(SeqQueue *Q) 
{ 
    SeqStack VS,*S; 
    char ch; 
    int x,y; 
    S=&VS; 
    InitStack(S); 
    while(!QueueEmpty(Q)) 
    { 
        ch=DeQueue(Q); 
        if(ch>='0'&&ch<='9') 
            Push(S,ch-'0'); 
        else 
        { 
            y=Pop(S); 
            x=Pop(S); 
            switch(ch) 
            { 
                case '+': 
                    Push(S,x+y); 
                    break; 
                case '-': 
                    Push(S,x-y); 
                    break; 
                case '*': 
                    Push(S,x*y); 
                    break; 
                case '/': 
                    Push(S,x/y); 
                    break; 
            } 
        }  
    } 
    return GetTop(S); 
}  
 
void main() 
{ 
    SeqQueue *Q; 
    SeqQueue PostQ,PostQ2;                        //定义队列,存放后缀表达式  
    Q=&PostQ; 
    printf("请输入中缀表达式(以#号结束):"); 
    InitQueue(Q);                        //初始化队列 
    CTPostExp(Q);                        //调用转换函数将中缀表式转换成后缀表达式 
    PostQ2=PostQ; 
    printf("后缀表达式为:"); 
    while(!QueueEmpty(Q))                //输出后缀表达式 
        printf("%2c",DeQueue(Q));  
    printf("\n"); 
    printf("计算结果为%4d\n",CPostExp(&PostQ2)); 
} 

版权所有,转载请注明出处 luowei.github.io.