zoukankan      html  css  js  c++  java
  • 数据结构上机实验(6个)

    关于文件的输入输出,只要在主函数中添加:

    freopen("E:\read9.txt","r",stdin);
    freopen("E:\write9.txt","w",stdout);

    即可。

    其余地方的输入输出不变,但是必须用scanf和printf进行输入输出。

    实验一  迷宫问题(bfs)

    #include"iostream"
    #include"stdio.h"
    #include"algorithm"
    #include"queue"
    #include"string.h"
    #include"cmath"
    #include"stack"
    #include"fstream"
    #define mx 105
    #define inf 1000
    using namespace std;
    int n,m;
    int sx,sy,ex,ey;
    int  maze[mx][mx],vis[mx][mx];
    int dir[8][2]= {{0,1},{0,-1},{1,0},{-1,0},{-1,-1},{-1,1},{1,-1},{1,1}};
    bool judge(int x,int y)
    {
        if(maze[x][y]==0&&x>=0&&x<n&&y>=0&&y<m)
        {
            return true;
        }
        return false;
    }
    void output(int step)
    {        
        int i;
        stack<int>path;
        path.push(ex*m+ey);
        printf("%s%d
    ","最少步骤是:",step);
        int x=ex,y=ey,dx,dy;
        while(vis[x][y]!=0)
        {
            for(i=0;i<8;i++)
            {
                dx=x+dir[i][0];
                dy=y+dir[i][1];
                if(dx>=0&&dx<n&&dy>=0&&dy<m)
                if(vis[dx][dy]==vis[x][y]-1)
                {
                    path.push(dx*m+dy);
                    break;
                }
            }
            x=dx;y=dy;
        }
        printf("%s","最短路径为:");
        while(!path.empty())
         {
             int u=path.top();
             path.pop();
             x=u/m;y=u%m;
             if(x!=ex||y!=ey)
            printf("%s%d%s%d%s%s","(",x,",",y,")","->");
             else printf("%s%d%s%d%s
    
    ","(",x,",",y,")");
         }
    
    }
    void bfs(int step)
    {
        queue<int>q;
        int i,x,y,dx,dy,u;
        x=sx;y=sy;
        u=x*m+y;
        q.push(u);
        while(!q.empty())
        {
            u=q.front();
            q.pop();
            x=u/m;y=u%m;
            if(x==ex&&y==ey)
            {
                output(step);
                return;
            }
            int flag=1;
            step=vis[x][y];
            for(i=0;i<8;i++)
            {
                dx=x+dir[i][0];
                dy=y+dir[i][1];
                if(judge(dx,dy))
                {
                       if(flag){step++;flag=0;}
                        maze[dx][dy]=1;
                        if(step<vis[dx][dy])
                        vis[dx][dy]=step;
                        u=dx*m+dy;
                        q.push(u);
    
                }
            }
        }
        printf("%s","没有满足条件的通路!
    ");
    }
    int main()
    {
        int i,j;
        freopen("C://read.txt","r",stdin);
        freopen("C://write.txt","w",stdout);
        while(scanf("%d%d",&n,&m),n||m)
        {
            for(i=0;i<n;i++)
            {
                for(j=0;j<m;j++)
                    {scanf("%d",&maze[i][j]);vis[i][j]=inf;}
            }
            scanf("%d%d%d%d",&sx,&sy,&ex,&ey);
            maze[sx][sy]=1;
            vis[sx][sy]=0;
            bfs(0);
        }
        return 0;
    }
    View Code

    实验二  锦标赛问题(简单的分治思想)

    #include"iostream"
    #include"stdio.h"
    #include"cmath"
    #include"string.h"
    #include"algorithm"
    #include"queue"
    using namespace std;
    const int mx=1005;
    int calendar[mx][mx];//日程表
    FILE*  rfile=fopen("E:\read2.txt","r");
    FILE*  wfile=fopen("E:\write2.txt","w");//文件读写
    void championship(int k)
    {
        int i,j,t;
        calendar[1][1]=1;//只有两个人比赛的情况
        calendar[1][2]=2;
        calendar[2][1]=2;
        calendar[2][2]=1;
        int temp=1;
        for(t=1;t<k;t++)
        {
            temp*=2;
            for(i=1;i<=temp;i++)
            {
                for(j=1;j<=temp;j++)
                {
                    calendar[i+temp][j+temp]=calendar[i][j];
                }
            }
          for(i=1;i<=temp;i++)//用分治的方式打表
                {
                    for(j=1;j<=temp;j++)
                    {
                        calendar[i+temp][j]=calendar[i][j]+temp;
                    }
                }
    
           for(i=temp+1;i<=temp*2;i++)
                {
                    for(j=1;j<=temp;j++)
                    {
                        calendar[i-temp][j+temp]=calendar[i][j];
                    }
                }
        }
    
        int n=pow(2,k);
        for(i=1;i<=n;i++)//日程表的输出
        {
            for(j=1;j<=n;j++)
                fprintf(wfile,"%d ",calendar[i][j]);
            fprintf(wfile,"%s
    ","");
        }
        fprintf(wfile,"%s
    ","");//文件输出
    }
    int main()
    {
        int k,icase=0;
        while((fscanf(rfile,"%d",&k),k!=-1))
        {
            fprintf(wfile,"%s%d%s
    ","Case ",++icase," :");
            fprintf(wfile,"%s%d
    ","input k :",k);
            championship(k);
        }
        fclose(wfile);
        fclose(rfile);
        return 0;
    }
    View Code

    实验三 kruskal算法(最小生成树)

    #include"iostream"
    #include"stdio.h"
    #include"algorithm"
    #include"cmath"
    #include"string.h"
    #include"string"
    using namespace std;
    
    const int mx=105;
    const int inf=32767;
    FILE*  rfile=fopen("E:\read3.txt","r");
    FILE*  wfile=fopen("E:\write3.txt","w");//文件读写
    struct Edge//记录边的两个端点和权值
    {
        int u;
        int v;
        int w;
    };
    
    struct Mgraph
    {
        int edges[mx][mx];//存储边
        int n;//顶点数
    };
    
    struct UFStree//并查集的数据结构
    {
        int data;//节点对应的编号
        int  parent;//节点对应双亲下标
        int rank;//节点对应秩
    };
    
    bool cmp(const Edge a,const Edge b)
    {
        return a.w<b.w;
    }
    void Make_set(UFStree t[],int n)//初始化
    {
        for(int i=0;i<n;i++)
        {
            t[i].rank=0;
            t[i].parent=i;
        }
    }
    
    int Find_set(UFStree t[],int  x)//查找集合的代表元素
    {
        while(x!=t[x].parent)
            x=t[x].parent;
        return x;
    }
    
    void Union(UFStree t[],int x,int y)//将两个集合并为一个
    {
        x=Find_set(t,x);
        y=Find_set(t,y);
        if(t[x].rank>t[y].rank)//将秩小的作为秩大的子集
            t[y].parent=x;
        else
        {
            t[x].parent=y;
            if(t[x].rank==t[y].rank) t[y].rank++;
        }
    }
    
    void  Kruskal(Mgraph g)//求最小生成树的算法
    {
    
        int i,j,k,u1,v1,sn1,sn2;
        UFStree t[mx];
        Edge E[mx];
        k=1;                //E数组的下标从1开始
        for(i=0;i<g.n;i++)   //由g产生的边集E
            for(j=0;j<g.n;j++)
        {
            if(g.edges[i][j]!=0&&g.edges[i][j]!=inf)//取出图的邻接矩阵中所有的边
            {
                E[k].u=i;E[k].v=j;E[k++].w=g.edges[i][j];
            }
        }
        sort(E,E+k,cmp);//按边的权值从小到大排序
        Make_set(t,g.n);
        k=1;//k表示当前构造生成树的第几条边,初值为1
        j=1;//E中边的下标,初值为1
        while(k<g.n)
        {
            u1=E[j].u;
            v1=E[j].v;
            sn1=Find_set(t,u1);
            sn2=Find_set(t,v1);
            if(sn1!=sn2)//两定顶点属于不同的集合,该边是最小生成树的一条边
            {
                fprintf(wfile,"%s%d%s%d%s%d
    ","(",u1,",",v1,"):",E[j].w);
                k++;//生成边数增1
                Union(t,u1,v1);//将 u1和v1两个顶点合并
            }
            j++;
        }
    }
    
    int main()
    {
        Mgraph g;
        int i,j,n;
        fprintf(wfile,"%s
    
    ","输入顶点数为0时结束!");
        while(fscanf(rfile,"%d",&n),n)
        {
            fprintf(wfile,"%s%d
    ","输入图的顶点数目:",n);
            g.n=n;
            fprintf(wfile,"%s
    ","输入每个顶点与n个顶点边的权值:");
            for(i=0;i<n;i++)
            {
                for(j=0;j<n;j++)
                  {fscanf(rfile,"%d",&g.edges[i][j]);//取地址符很关键
                   fprintf(wfile,"%d ",g.edges[i][j]);
                  }
                  fprintf(wfile,"%s
    ","");
            }
            fprintf(wfile,"%s
    ","输出构成最小生成树的边和顶点集:");
            Kruskal(g);
            fprintf(wfile,"%s
    ","");
        }
        fclose(wfile);//关闭文件
        fclose(rfile);
        return 0;
    }
    View Code

    实验四  哈夫曼编码

    #include"iostream"
    #include"stdio.h"
    #include"algorithm"
    #include"string"
    #include"string.h"
    #include"cmath"
    #include"fstream"
    using namespace std;
    const int mx=105;
    const int inf=32767;//表示无穷
    FILE* rfile=fopen("E:\read4.txt","r");
    FILE* wfile=fopen("E:\write4.txt","w");
    struct htnode
    {
        char data;//节点值
        double weight;//权重
        int parent;//双亲节点
        int lchild;//左孩子节点
        int rchild;//右孩子节点
    };
    
    struct hcode
    {
        char cd[mx];//存放当前结点的哈夫曼码
        int start;//cd[start]~cd[n]存放哈夫曼码
    };
    void CreatHuffman(htnode ht[],int n)
    {
        int i,j,k,lnode,rnode;
        double min1,min2;
        for(i=0;i<2*n-1;i++)//所有节点的相关域置初值-1
        {
            ht[i].parent=ht[i].lchild=ht[i].rchild=-1;
        }
        for(i=n;i<2*n-1;i++)//构造哈弗曼树
        {
            min1=min2=inf;
            lnode=rnode=-1;//lnode和rnode为最小权重的两个结点位置
            for(k=0;k<=i-1;k++)//在ht[]中找权值最小的两个结点
            {
                if(ht[k].parent==-1)//只在尚未构造二叉树的结点中查找
                {
                    if(ht[k].weight<min1)
                {
                    min2=min1;rnode=lnode;
                    min1=ht[k].weight;lnode=k;
                }
                else if(ht[k].weight<min2)
                {
                    min2=ht[k].weight;rnode=k;
                }
                }
            }
            ht[i].weight=ht[lnode].weight+ht[rnode].weight;
            ht[i].lchild=lnode;ht[i].rchild=rnode;//ht[i]作为双亲结点
            ht[lnode].parent=i;ht[rnode].parent=i;
        }
    }
    
    void CreatHuffmanCode(htnode ht[],hcode hcd[],int n)
    {
        int i,f,c;
        hcode hc;
        for(i=0;i<n;i++)//根据哈夫曼树求哈夫曼编码
        {
            hc.start=n;c=i;
            f=ht[i].parent;
            while(f!=-1)
            {
                if(ht[f].lchild==c)
                    hc.cd[hc.start--]='0';
                else
                    hc.cd[hc.start--]='1';
                c=f;f=ht[f].parent;
            }
            hc.start++;hcd[i]=hc;
        }
    }
    void display(htnode ht[],hcode hcd[],int n)
    {
        for(int i=0;i<n;i++)
        {
            fprintf(wfile,"%c%s",ht[i].data,": ");
            for(int j=hcd[i].start;j<=n;j++)
                fprintf(wfile,"%c",hcd[i].cd[j]);
            fprintf(wfile,"%s
    ","");
        }
         fprintf(wfile,"%s
    ","");
    }
    int main()
    {
        htnode ht[mx];
        hcode hcd[mx];
        char enter;//用于清除换行
        int n,i,j;
        while(fscanf(rfile,"%d",&n),n)
        {
            for(i=0;i<n;i++)
            {
                fscanf(rfile,"%c%c%lf",&enter,&ht[i].data,&ht[i].weight);
            }
            CreatHuffman(ht,n);
            CreatHuffmanCode(ht,hcd,n);
            display(ht,hcd,n);
        }
        fclose(wfile);
        fclose(rfile);
        return 0;
    }
    View Code

    实验五  树和二叉树

     任务(1)和(2):

    #include"iostream"
    #include"stdio.h"
    #include"algorithm"
    #include"string"
    #include"string.h"
    #include"Stack"
    #include"queue"
    #include"vector"
    //顺序表ADT的定义
    //datatype的定义
    #ifndef datatype
    #define datatype NODE
    #define _ERROR NULL
    #endif
    FILE* rfile=fopen("E:\read5.txt","r");
    FILE* wfile=fopen("E:\write5.txt","w");
    //树结点的定义
    struct Tnode{
        struct Tnode * lchild;
        struct Tnode * rchild;
        char* data;//data用于保存节点信息,类型为字符串
    };
    typedef struct Tnode * Bitree;
    typedef struct Tnode * NODE;
    struct Table{  //为了定义栈
        datatype* Table_head;
        int Length;
        int Max_Length;
    };
    typedef struct Table* mystable;
    
    //栈ADT的定义
    typedef struct Table* mystack;
    //为顺序表分配空间,将所有数据初始化为init
    mystable Assign(const int maxlen,datatype init)
    {
        mystable temp;
        if((temp=(mystable)malloc(sizeof(struct Table)))!=NULL){//分配空间成功
            temp->Max_Length = maxlen;
            temp->Length=0;
            if((temp->Table_head=(datatype *)malloc(sizeof(datatype)*maxlen))!=NULL)
                for(int i=0;i<maxlen;i++)
                    *(temp->Table_head+i)=init;
            else
                return NULL;
            return temp;
        }
        return NULL;
    }
    
    //判断表是否为空
    int isEmpty(const mystable table)
    {
        if (table==NULL)
            return -1;
        if(table->Length == 0)
            return 1;
        return 0;
    }
    
    //判断表是否为满
    int isFull(const mystable table)
    {
        if (table==NULL)
            return -1;
        if(table->Length == table->Max_Length)
            return 1;
        return 0;
    }
    
    //获取position位置的数据
    datatype get(const mystable table,int position)
    {
        if (position>table->Length-1 || position<0)
            return _ERROR;
        return *(table->Table_head + position);
    }
    
    //获取表长
    int getLength(const mystable table)
    {
        if (table==NULL)
            return -1;
        return table->Length;
    }
    
    //从表中删除一个数据
    int Remove(const mystable table,int position)
    {
        int i=0;
        if(table==NULL)
            return -1;
        if(position>table->Length-1 || position<0)
            return 0;
        for(i=position;i<table->Length-1;i++)
            *(table->Table_head+i)=*(table->Table_head+(i+1));
        table->Length--;
        return 1;
    }
    
    //插入一个数据到position位置
    int Insert(mystable table,int position,datatype data)
    {
        int i=0;
        if(table==NULL)
            return -1;
        if(position>table->Length || position<0)
            return 0;
        if(isFull(table)==0){
            for(i=table->Length;i>position;i--)
                *(table->Table_head+i)=*(table->Table_head+(i-1));
            *(table->Table_head+i)=data;
            table->Length++;
        }else{
            mystable temp;
            if((temp=(mystable)malloc(sizeof(struct Table)))==NULL)
                return -1;
           if((temp->Table_head=(datatype*) malloc(sizeof(datatype)*(table->Max_Length+1)))==NULL)
                return -1;
            temp->Length=table->Max_Length+1;
            temp->Max_Length=table->Max_Length+1;
            for(i=0;i<position;i++)
                *(temp->Table_head+i)=*(table->Table_head+i);
            *(temp->Table_head+i)=data;
            for(i++;i<temp->Length;i++)
                *(temp->Table_head+i)=*(table->Table_head+(i-1));
            free(table->Table_head);
            free(table);
            table=temp;
        }
        return 1;
    }
    
    //释放表占用的空间
    int del(const mystable table)
    {
        free(table->Table_head);
        free(table);
        return 1;
    }
    //在表的最后插入一个数据
    int add(const mystable table,datatype x)
    {
        return Insert(table,table->Length,x);
    }
    //初始化栈,分配空间
    mystack initial()
    {
        return Assign(100,0);
    }
    
    //从栈中弹出一个数据
    datatype pop(mystack Stack)
    {
        if(Stack==NULL)
            return _ERROR;
        if(isEmpty(Stack))
            return _ERROR;
        datatype data;
        data=get(Stack,Stack->Length-1);
        Remove(Stack,Stack->Length-1);
        return data;
    }
    
    //返回栈顶的数据但不弹出
    datatype peek(mystack Stack)
    {
        if(Stack==NULL)
            return _ERROR;
        if(isEmpty(Stack))
            return _ERROR;
        datatype data;
        data=get(Stack,Stack->Length-1);
        return data;
    }
    
    //向栈中压入数据
    int push(mystack Stack,datatype x)
    {
        return Insert(Stack,Stack->Length,x);
    }
    
    
    //分配一个新的树节点
    NODE newNode(char* data)
    {
        NODE temp=(NODE)malloc(sizeof(struct Tnode));
        if(temp==NULL)
            return NULL;
        temp->lchild=NULL;
        temp->rchild=NULL;
        temp->data=data;
        return temp;
    }
    
    //字符串转化为中缀顺序表,这是本实验的核心代码
    mystable char_to_infix(char ex[])
    {
        int length=strlen(ex);
        mystable infix=Assign(length,NULL);
        char* temp;
        for (int i = 0; i < length; i++) {
            if ((ex[i] >= '0' && ex[i] <= '9') || ex[i] == '.' ) {
            //若是数字字符则查询直到遇到一个不是数字的字符
                int Count=0;
                for(int j=i;(ex[j] >= '0' && ex[j] <= '9') || ex[j] == '.';j++,Count++);
                temp=(char *)malloc(sizeof(char)*(Count+1));
                for(int j=0;j<Count;j++)
                    temp[j]=ex[i+j];
                temp[Count]='';
                add(infix,newNode(temp));
                i=i+Count-1;
            }else{
                temp=(char *)malloc(sizeof(char)*2);
                temp[0]=ex[i];temp[1]='';
                add(infix,newNode(temp));
            }
        }
        return infix;
    }
    
    //中缀表达式转化为后缀表达式
    mystable infix_to_postfix(mystable infix)
    {
        mystack Stack=initial();
        mystable postfix=Assign(getLength(infix),NULL);
        for (int i = 0; i < getLength(infix); i++) {
            char opF,opS;
            opF=get(infix,i)->data[0];
            if ((opF>='0' && opF<='9') || opF=='.' || (opF>='a' && opF<='z'))
            //数字则直接压入后缀表达式
                add(postfix,get(infix,i));
            else{
                if (getLength(Stack) == 0) {
                    push(Stack,get(infix,i));
                } else if (opF == '(') {
                    push(Stack,get(infix,i));
                } else if (opF == ')') {
                //遇到右括号,将栈中的数据依次弹出,直到遇到左括号
                    do {
                        opS = peek(Stack)->data[0];
                        if (opS != '(')
                            add(postfix,pop(Stack));
                        else
                            pop(Stack);
                    } while (opS != '(');
                } else {
                //比较优先级,若优先级高于栈顶元素则压入栈,否则弹出
                    do {
                        opS = peek(Stack)->data[0];
                        int spriority,fpriority;
                        switch(opS){
                        //设置优先级
                        case '+':spriority=4;break;
                        case '-':spriority=4;break;
                        case '*':spriority=3;break;
                        case '/':spriority=3;break;
                        case '^':spriority=2;break;
                        case '(':spriority=7;break;
                        }
                        switch(opF){
                        case '+':fpriority=4;break;
                        case '-':fpriority=4;break;
                        case '*':fpriority=3;break;
                        case '/':fpriority=3;break;
                        case '^':fpriority=2;break;
                        case '(':spriority=7;break;
                        }
                        if (fpriority >= spriority)
                            add(postfix,pop(Stack));
                        else
                            break;
                    } while (getLength(Stack) != 0);
                    push(Stack,get(infix,i));
                }
            }
        }
        while (getLength(Stack) != 0)
            add(postfix,pop(Stack));
    //释放括号占用的内存
        for(int i=0;i<getLength(infix);i++){
            NODE temp=get(infix,i);
            if(temp->data[0]=='(' || temp->data[0]==')'){
                free(temp->data);
                free(temp);
            }
        }
        //释放栈占用的内存
        del(Stack);
        //释放掉前缀表达式占用的内存
        del(infix);
        return postfix;
    }
    
    //生成表达式树
    Bitree postfix_to_binarytree(mystable postfix)
    {
        mystack Stack=initial();
        for (int i = 0; i < getLength(postfix); i++) {
            char name;
            name=get(postfix,i)->data[0];
            if ((name>='0' && name<='9') || name=='.' || (name>='a' && name<='z')){
                push(Stack,get(postfix,i));
            }else{
                NODE parent=get(postfix,i);
                NODE lchild,rchild;
                //从栈中弹出操作数,将运算符节点的两个儿子指针指向操作数结点
                if(getLength(Stack)!=0){
                    rchild=pop(Stack);
                    parent->rchild=rchild;
                }
                if(getLength(Stack)!=0){
                    lchild=pop(Stack);
                    parent->lchild=lchild;
                }
                push(Stack,parent);
            }
        }
        if(getLength(Stack)!=1){
            return NULL;
        }else{
            NODE result=pop(Stack);
            //释放内存
            free(Stack);
            free(postfix);
            return result;
        }
    }
    
    //打印前缀表达式
    void print_prefix(Bitree node)
    {
        if(node==NULL)
            return;
        fprintf(wfile,"%s",node->data);
        if(node->lchild!=NULL)
            print_prefix(node->lchild);
        if(node->rchild!=NULL)
            print_prefix(node->rchild);
    }
    
    //打印后缀表达式
    void print_postfix(Bitree node)
    {
        if(node==NULL)
            return;
        if(node->lchild!=NULL)
            print_postfix(node->lchild);
        if(node->rchild!=NULL)
            print_postfix(node->rchild);
        fprintf(wfile,"%s",node->data);
    }
    
    
    
    //递归打印叶节点递归函数入口
    void _print_path_with_recursion(Bitree tree,NODE path[],int depth)
    {
        if(tree==NULL)
            return;
        //若为叶节点则打印路径
        if(tree->lchild==NULL && tree->rchild==NULL){
            fprintf(wfile,"%s : %s",tree->data,tree->data);
            for(int i=depth-1;i>=0;i--)
                fprintf(wfile," %s",path[i]->data);
            fprintf(wfile,"%s
    ","");
        }
        if(tree->lchild!=NULL){
            path[depth]=tree;
            _print_path_with_recursion(tree->lchild,path,depth+1);
        }
        if(tree->rchild!=NULL){
            path[depth]=tree;
            _print_path_with_recursion(tree->rchild,path,depth+1);
        }
    }
    
    //非递归打印叶节点
    void print_path_without_recursion(Bitree tree)
    {
        NODE curr=tree;
        NODE path[100];
        //存放深度的数组
        int depth[100];
        int top=0,curdepth=0;
    
        mystack track=initial();
        do{
            if(curr!=NULL){
                if(curr->lchild==NULL && curr->rchild==NULL){
                    fprintf(wfile,"%s : %s",curr->data,curr->data);
                    for(int i=curdepth-1;i>=0;i--)
                        fprintf(wfile," %s",path[i]->data);
                    fprintf(wfile,"%s
    ","");
                    //从栈中弹出下一个要访问的结点,并将当前深度更新为该结点深度
                    curr=pop(track);
                    curdepth=depth[--top];
                }else{
                    path[curdepth]=curr;
                    push(track,curr->rchild);
                    depth[top++]=++curdepth;
                    curr=curr->lchild;
                }
            }else{
                curr=pop(track);
                curdepth=depth[--top];
            }
        }while(curr!=NULL || getLength(track)!=0);
    }
    //递归打印叶节点主程序入口
    void print_path_with_recursion(Bitree tree)
    {
        NODE path[100];
        _print_path_with_recursion(tree,path,0);
    }
    int main(){
        char ch[100];
        int icase=1;
        while(fscanf(rfile,"%s",ch),strcmp(ch,"no")!=0)//输入表达式
      {
        fprintf(wfile,"%s%d%s
    
    ","案例 #",icase++,": ");
        mystable infix=char_to_infix(ch);
        mystable postfix=infix_to_postfix(infix);
        Bitree root=postfix_to_binarytree(postfix);
        if(root==NULL)
            fprintf(wfile,"%s","输入有误!
    
    ");
        else{
            fprintf(wfile,"%s","输出前缀表达式:  ");
            print_prefix(root);//输出前缀式
            fprintf(wfile,"%s
    
    ","");
            fprintf(wfile,"%s","输出后缀表达式:  ");
            print_postfix(root);//输出后缀式2
            fprintf(wfile,"%s
    
    ","");
            fprintf(wfile,"%s
    ","用递归打印从根节点到叶子节点的路径:");
            print_path_with_recursion(root);
            fprintf(wfile,"%s
    ","");
            fprintf(wfile,"%s
    ","用非递归打印从根节点到叶子节点的路径:");
            print_path_without_recursion(root);
        }
     }
        return 0;
    }
    View Code

    任务(3):

    对于拓扑排序,我用了两种方法,一种是利用邻接矩阵:

    #include"iostream"
    #include"stdio.h"
    #include"cmath"
    #include"string.h"
    #include"queue"
    #include"stack"
    #include"vector"
    #include"algorithm"
    #include"fstream"
    using namespace std;
    const int mx=105;
    const int inf=32767;//表示无穷大
    FILE* rfile=fopen("E:\read6.txt","r");
    FILE* wfile=fopen("E:\write6.txt","w");
    int n,m;;//n表示节点的数目,m表示边的数目
    int topoArray[mx];//拓扑排序的数组
    bool visited[mx];//用来标记该顶点是否已被访问过
    bool cnt[mx];//用于拓扑排序中判断某个点是否已进栈
    struct Mgraph//图的邻接矩阵
    {
        int NumVertices,NumEdges;
        int Edges[mx][mx];
    };
    struct EdgeNode//邻接表的边节点类型
    {
        int dest;//边的另一顶点位置
        int weight;//边的权重
        EdgeNode *link;//下一条链指针
    };
    struct VertexNode//顶点节点类型(表头节点)
    {
        int data;
        EdgeNode *first;
    };
    struct ALGraph//邻接表类型
    {
        VertexNode verticeslish[mx];
        int NumVetices,NumEdeges;
    };
    //创建图的邻接矩阵表示
    void Creat_Mgraph(Mgraph &M)
    {
            int i;
            M.NumVertices=n;
            M.NumEdges=m;
            //初始化所有边之间的权值为-1,表示两个结点之间无直接通路
            memset(M.Edges,-1,sizeof(M.Edges));
            for(i=0;i<m;i++)
            {
                int p,q,w;
                fscanf(rfile,"%d%d%d",&p,&q,&w);
                M.Edges[p][q]=w;
            }
    }
    //将邻接矩阵转换为邻接表表示
    void Mgraph_to_ALGraph(Mgraph &M,ALGraph &ALG)
    {
        ALG.NumVetices=M.NumVertices;
        ALG.NumEdeges=M.NumEdges;
        int i,j;
        for(i=0;i<n;i++)
        {
            ALG.verticeslish[i].data=i;
            ALG.verticeslish[i].first=NULL;
            for(j=0;j<n;j++)
            {
                if(M.Edges[i][j]!=-1)
                {
                    EdgeNode  *temp=new EdgeNode;
                    temp->link=ALG.verticeslish[i].first;
                    temp->weight=M.Edges[i][j];
                    temp->dest=j;
                    ALG.verticeslish[i].first=temp;
                }
            }
        }
    }
    //输出图的邻接矩阵表示
    void Output_Mgraph(Mgraph &M)
    {
        int i,j;
        for(i=0;i<M.NumVertices;i++)
        {
            fprintf(wfile,"%d%s",i,": ");
            for(j=0;j<M.NumVertices;j++)
            {
                fprintf(wfile,"%d%s",M.Edges[i][j]," ");
            }
            fprintf(wfile,"%s
    ","");
        }
         fprintf(wfile,"%s
    ","");
    }
    //输出图的邻接表表示
    void Output_ALGraph(ALGraph &ALG)
    {
         int i;
         for(i=0;i<ALG.NumVetices;i++)
         {
             int flag=false;
             fprintf(wfile,"%d%s",i,": ");
             EdgeNode *temp;
             temp=ALG.verticeslish[i].first;
             while(temp!=NULL)
             {
                 flag=true;
                 fprintf(wfile,"%d%s%d%s",temp->dest,"(",temp->weight,")  ");
                 temp=temp->link;
             }
             if(!flag) fprintf(wfile,"%s
    ","");
             fprintf(wfile,"%s
    ","");
         }
    }
    //用dfs递归遍历从0开始的深度优先遍历序列
    void Dfs_From_0(int k,ALGraph &ALG)
    {
        if(!visited[k])
        {
            fprintf(wfile,"%d%s",k," ");
            visited[k]=true;
            EdgeNode *temp=ALG.verticeslish[k].first;
            while(temp!=NULL)
            {
                Dfs_From_0(temp->dest,ALG);
                temp=temp->link;
            }
        }
    }
    //从0开始的广度优先遍历非递归算法
    void Bfs_From_0(int k,ALGraph &ALG)
    {
        memset(visited,false,sizeof(visited));
        fprintf(wfile,"%d%s",k," ");
        visited[k]=true;
        EdgeNode *temp=ALG.verticeslish[k].first;
        queue<EdgeNode *>q;
        while(temp!=NULL)
        {
            if(!visited[temp->dest])
                {q.push(temp);visited[temp->dest]=true;}
                temp=temp->link;
        }
        EdgeNode *cur;
        while(!q.empty())
        {
            cur=q.front();
            q.pop();
            k=cur->dest;
            fprintf(wfile,"%d%s",k," ");
            cur=ALG.verticeslish[k].first;
            while(cur!=NULL)
            {
                if(!visited[cur->dest])
                {q.push(cur);visited[cur->dest]=true;}
                cur=cur->link;
            }
        }
    }
    //判断某个节点是否入度为零
    bool Judge_Column(Mgraph &M,int k)
    {
        int i;
        for(i=0;i<M.NumVertices;i++)
        {
            if(M.Edges[i][k]!=-1)
            {
                return false;
            }
        }
        return true;
    }
    //输出拓扑排序的结果
    void Output_Topoarray(Mgraph &M,int k)
    {
        if(k<M.NumVertices)
            fprintf(wfile,"%s
    ","图中有有向环!");
        else
        {
            fprintf(wfile,"%s","输出该图的拓扑序列: ");
            for(int i=0;i<k;i++)
                fprintf(wfile,"%d%s",topoArray[i]," ");
        }
        fprintf(wfile,"%s
    ","");
    }
    //进行拓扑排序
    void TopologicalSort(Mgraph &M)
    {
        memset(cnt,false,sizeof(cnt));
        stack<int>S;
        int k=0,i,j;
        for(i=0;i<M.NumVertices;i++)
        {
            if(Judge_Column(M,i)&&!cnt[i])
            {
                cnt[i]=true;
                topoArray[k++]=i;
                S.push(i);
            }
        }
        while(!S.empty())
        {
            int cur=S.top();
            S.pop();
            for(j=0;j<M.NumVertices;j++)
                M.Edges[cur][j]=-1;
            for(i=0;i<M.NumVertices;i++)
           {
             if(Judge_Column(M,i)&&!cnt[i])
             {
                cnt[i]=true;
                topoArray[k++]=i;
                S.push(i);
              }
           }
        }
        Output_Topoarray(M,k);
    }
    
    int main()
    {
        int iCase=1;//案例个数
        Mgraph M;
        ALGraph ALG;
        while(fscanf(rfile,"%d%d",&n,&m),n&&m)
        {
             fprintf(wfile,"%s%d%s
    ","案例 #",iCase++,": ");
             Creat_Mgraph(M);
             Mgraph_to_ALGraph(M,ALG);
             fprintf(wfile,"%s
    ","输出图的邻接矩阵表示:");
             Output_Mgraph(M);
             fprintf(wfile,"%s
    ","输出图的邻接表表示:");
             Output_ALGraph(ALG);
             memset(visited,false,sizeof(visited));
             fprintf(wfile,"%s","输出从0开始的递归dfs遍历:");
             Dfs_From_0(0,ALG);
             fprintf(wfile,"%s
    ","");
             fprintf(wfile,"%s","输出从0开始的非递归bfs遍历: ");
             Bfs_From_0(0,ALG);
             fprintf(wfile,"%s
    ","");
             TopologicalSort(M);
             fprintf(wfile,"%s
    ","");
        }
        return 0;
    }
    View Code

    一种是利用邻接表:

    #include <stdio.h>
    #include <stdlib.h>
    #include <Queue>
    #include <string.h>
    #include <Stack>
    using namespace std;
    bool visit[1000];
    int inCount[1000];
    
    typedef struct EdgeNode{
          int dest;
          int cost;
          struct EdgeNode *Link;
    };
    typedef struct VertexNode
    {
          int data;
          struct EdgeNode *first;
    };
    typedef struct ALGraph
    {
          VertexNode *VerticesList;
          int numVertices,numEdges;
    };
    void InitGraph(ALGraph& G)
    {
          G.numVertices=0;
          G.numEdges=0;
          G.VerticesList=new VertexNode[1000];
          for (int i=0;i<1000;i++)
          {
                G.VerticesList[i].first=NULL;
          }
    };
    int GetVertexPos(ALGraph& G,int vertex)/*找出该顶点的顶点号*/
    {
          for (int i=0;i<G.numVertices;i++)
                if (G.VerticesList[i].data==vertex)
                      return i;
          return -1;
    }
    int GetValue(ALGraph& G,int i)/*返回顶点i,不合理则返回0*/
    {
          if (i==-1)
                return 0;
          else
                return G.VerticesList[i].data;
    };
    int FirstNeighbor(ALGraph& G,int v)/*返回顶点v的第一个邻接顶点的顶点号,若无则返回-1*/
    {
          if (v!=-1)
          {
                EdgeNode *p=G.VerticesList[v].first;
                if (p!=NULL)
                      return p->dest;
          }
          else return -1;
    }
    
    int NextNeighbor(ALGraph &g, int v, int w)/*返回在顶点v的邻接顶点w后的下一个顶点号,没有则返回-1*/
    {
        EdgeNode *p;
        p=g.VerticesList[v].first;
        while(p)
        {
            if(p->dest==w&&p->Link!=NULL)
                return p->Link->dest;
            p=p->Link;
        }
        return -1;
    }
    
    void creat(ALGraph& G)
    {
          int i,j,k;
          EdgeNode *s;
          int n,m;
          int weight;
          printf("请输入顶点数和边数:
    ");
          scanf("%d %d",&G.numVertices,&G.numEdges);
          printf("输入顶点信息:
    ");
          for (i=0;i<G.numVertices;i++)
          {
                scanf("%d",&G.VerticesList[i].data);
                G.VerticesList[i].first=NULL;
          }
          printf("输入边的信息:
    ");
          for (k=0;k<G.numEdges;k++)
          {
                scanf("%d %d %d",&i,&j,&weight);
                s=new EdgeNode;
                s->dest=j;
                inCount[j]++;
                s->cost=weight;
                s->Link=G.VerticesList[i].first;
    
                G.VerticesList[i].first=s;
          }
    
    }
    
    int Numberofvertices(ALGraph& G)/*返回图中的顶点个数*/
    {
          return G.numVertices;
    }
    void PrintfGraph(ALGraph& G)/*输出有向图邻接表*/
    {
          int i,j;
          EdgeNode *p;
          printf("图G的顶点数是:%d
    ",G.numVertices);
          printf("顶点向量的值是:");
          for (i=0;i<G.numVertices;i++)
                printf("%d  ",G.VerticesList[i].data);
          printf("
    ");
          printf("图G的边数是:%d
    ",G.numEdges);
          for (i=0;i<G.numVertices;i++){
                for (p=G.VerticesList[i].first;p!=NULL;p=p->Link)
                      printf("(%d,%d,%d)
    ",i,p->dest,p->cost);
          }
    };
    void DFS(ALGraph& G,int v,bool visited[])/*DFS*/
    {
          printf("%d  ",GetValue(G,v));
          visited[v]=true;
          int w=FirstNeighbor(G,v);
          while (w!=-1)
          {
                if (visited[w]==false)
                      DFS(G,w,visited);
                w=NextNeighbor(G,v,w);
          }
    };
    
    
    void BFS(ALGraph&G, int v)/*BFS*/
    {
          int i,k,w,n=Numberofvertices(G);
          for (i=0;i<n;i++)
                visit[i]=false;
          queue <int > q;/*创建队列*/
          if (!visit[v])
          {
                printf("%d  ",G.VerticesList[v].data);
                visit[v]=true;
          }
          q.push(v);
          while (!q.empty())
          {
                int vv=q.front();
                q.pop();
                for (int w = FirstNeighbor(G, vv); w >= 0; w = NextNeighbor(G, vv, w))
                {
                      if (!visit[w])
                      {
                            printf("%d  ",G.VerticesList[w].data);
                            visit[w] = true;
                            q.push(w);
                      }
                }
          }
          delete[]visit;
    };
    void TopologicalSort(ALGraph& g)//拓扑排序算法
    {
    
        stack<int> s;
        for(int i=1;i<=g.numVertices;i++)
            if(!inCount[i])
                s.push(g.VerticesList[i].data);//入度为0者进栈
        int count=0;
        while(!s.empty())
        {
            int v = s.top();
            s.pop();
            printf("%d  ",v);
            count++;
            for(EdgeNode *p = g.VerticesList[v].first ; p!=NULL ; p=p->Link)
            {
                //对i号顶点的每个邻接点的入度减1,新产生的入度为0的顶点进栈
                int k = p->dest;
                if(!(--inCount[g.VerticesList[k].data]))
                      s.push(g.VerticesList[k].data);
            }
        }
        printf("
    ")
        if(count<g.numVertices)
          printf("存在回路
    ");
        else
          printf("存在拓扑排序
    ");
    }
    
    
    int main()
    {
          int start;
          int i,j;
          ALGraph G;
          InitGraph(G);
          creat(G);
          PrintfGraph(G);
          TopologicalSort(G);
          printf("输入从哪个点开始DFS遍历:
    ");
          scanf("%d",&start);
          DFS(G,start,visit);
          printf("
    ");
          printf("输入从哪个点开始BFS遍历:
    ");
          scanf("%d",&start);
          BFS(G,start);
          printf("
    ");
    
          return 0;
    }
    /*
    5 7
    0 1 2 3 4
    0 1 10
    1 2 50
    0 4 100
    0 3 30
    2 4 10
    3 2 20
    3 4 60
    */
    View Code

     实验六:

    1、顺序查找和二分查找

    #include"iostream"
    #include"stdio.h"
    #include"algorithm"
    #include"string.h"
    #include"string"
    #include"fstream"
    #include"cmath"
    #include"queue"
    #include"stack"
    #include"vector"
    using namespace std;
    const int mx=1005;
    FILE* rfile=fopen("E:\read7.txt","r");
    FILE* wfile=fopen("E:\write7.txt","w");
    
    struct SeqList //顺序表的数据结构
    {
        int DataNum;
        int data[mx];
    };
    //顺序查找
    int SeqFind(SeqList &L,int x)
    {
        int step=1;
        L.data[L.DataNum]=x;//监视哨
        for(int i=0;i<=L.DataNum;i++)
        {
            fprintf(wfile,"%s%d%s%d %d
    ","",step++," 步查找到的值和下标分别为:",L.data[i],i);
            if(x==L.data[i]) return i;
        }
    }
    //二分查找
    int BinFind(SeqList &L,int x)
    {
        int step=1;
        int mid,left,high;
        left=0;high=L.DataNum-1;
        while(left<=high)
        {
             mid=(left+high)/2;
             fprintf(wfile,"%s%d%s%d %d
    ","",step++," 步查找到的值和下标分别为:",L.data[mid],mid);
             if(L.data[mid]==x)
                return mid;
             else if(x<L.data[mid])
                high=mid-1;
             else
                left=mid+1;
        }
        return L.DataNum;
    }
    int main()
    {
        int iCase=1;//案例个数
        int num;//元素个数;
        int i,j,FindNum;//FindNum为查找返回的下标
        while(fscanf(rfile,"%d",&num),num!=0)
        {
            fprintf(wfile,"%s%d%s
    ","案例 #",iCase++,": ");
            SeqList L;
            L.DataNum=num;
            fprintf(wfile,"%s","输出原始序列: ");
            for(i=0;i<num;i++)
                {fscanf(rfile,"%d",&L.data[i]);fprintf(wfile,"%d ",L.data[i]);}
            fprintf(wfile,"%s
    ","");
            fscanf(rfile,"%d",&FindNum);
            fprintf(wfile,"%s%d
    
    ","需要查找的数(顺序查找): ",FindNum);
            fprintf(wfile,"%s
    ","输出查找过程: ");
            int FindResult=SeqFind(L,FindNum);
               fprintf(wfile,"%s
    ","输出查找结果: ");
            if(FindResult==L.DataNum)
                fprintf(wfile,"%s%d%s
    
    ","原序列中不存在 ",FindNum,"!");
            else
                fprintf(wfile,"%d%s%d
    
    ",FindNum," 在原序列中的下标为: ",FindResult);
            sort(L.data,L.data+L.DataNum);
            fprintf(wfile,"%s","将上面的序列排好序输出: ");
            for(i=0;i<num;i++)
                fprintf(wfile,"%d%s",L.data[i]," ");
            fprintf(wfile,"%s
    
    ","");
            fprintf(wfile,"%s%d
    
    ","需要查找的数(折半查找): ",FindNum);
            FindResult=BinFind(L,FindNum);
            fprintf(wfile,"%s
    ","输出查找结果: ");
            if(FindResult==L.DataNum)
                fprintf(wfile,"%s%d%s
    
    ","新序列中不存在 ",FindNum,"!");
            else
                fprintf(wfile,"%d%s%d
    
    ",FindNum," 在新序列中的下标为: ",FindResult);
        }
        return 0;
    }
    View Code

    2、直接插入排序 

    #include"iostream"
    #include"stdio.h"
    #include"algorithm"
    #include"string.h"
    #include"string"
    #include"cmath"
    #include"queue"
    #include"stack"
    #include"vector"
    #include"fstream"
    using namespace std;
    const int mx=1005;
    //输出序列
    void Output_Array(int Array[],int Num)
    {
        int i;
        for(i=0;i<Num;i++)
            printf("%d ",Array[i]);
        printf("
    ");
    }
    //直接插入排序
    void Straight_Insertion_Sort(int Array[],int Num)
    {
        int i,j;
        for(i=1;i<Num;i++)
        {
            if(Array[i]<Array[i-1])
            {
                int temp=Array[i];
                for(j=i-1;j>=0&&Array[j]>temp;j--)
                {
                    Array[j+1]=Array[j];
                }
                Array[j+1]=temp;
            }
            printf("第%d次进行插入排序得到的序列: ",i);
            Output_Array(Array,Num);
        }
    }
    
    int main()
    {
        int iCase=1;
        freopen("E:\read8.txt","r",stdin);
        freopen("E:\write8.txt","w",stdout);
        int Array[mx];
        int i,j,Num;
        while(scanf("%d",&Num),Num!=0)
        {
            printf("案例 #%d :
    ",iCase++);
            for(i=0;i<Num;i++)
                scanf("%d",&Array[i]);
            printf("原始序列:");
            for(i=0;i<Num;i++)
                printf("%d ",Array[i]);
            printf("
    ");
            Straight_Insertion_Sort(Array,Num);
        }
    }
    View Code

    3、快速排序

    #include"iostream"
    #include"stdio.h"
    #include"algorithm"
    #include"string.h"
    #include"string"
    #include"cmath"
    #include"queue"
    #include"stack"
    #include"vector"
    #include"map"
    using namespace std;
    const int mx=1005;
    int step;//记录快速排序进行的步数
    int num;//记录序列中元素的个数
    void Quick_Sort(int Array[],int low,int high)
    {
        if(low>=high) return;
        int first=low;
        int last=high;
        int key=Array[first];
        while(first<last)//将比key小的放到key前面,比key大的放到key后面
        {
            while(first<last&&Array[last]>=key) last--;
            Array[first]=Array[last];
            while(first<last&&Array[first]<=key) first++;
            Array[last]=Array[first];
        }
        Array[first]=key;
        printf("第 %d 次排序后的序列: ",step++);//输出序列
        for(int  i=0;i<num;i++)
            printf("%d ",Array[i]);
        printf("
    ");
        Quick_Sort(Array,low,first-1);//分治的思想
        Quick_Sort(Array,first+1,high);
    }
    int main()
    {
        int i,iCase=1;
        int Array[mx];
        freopen("E:\read9.txt","r",stdin);
        freopen("E:\write9.txt","w",stdout);
        while(scanf("%d",&num),num!=0)
        {
            step=1;
            printf("案例 #%d : 
    ",iCase++);
            for(i=0;i<num;i++)
                scanf("%d",&Array[i]);
            printf("进行快速排序:
    ");
            Quick_Sort(Array,0,num-1);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    thinkphp nginx 上配置 并解决get获取到数据现象
    Linux下压缩某个文件夹(文件夹打包)
    Nginx下实现pathinfo及ThinkPHP的URL Rewrite模式支持
    SecureCRT超级终端使用说明
    redis 中文文档
    【Spring学习笔记-MVC-15】Spring MVC之异常处理
    【Spring学习笔记-MVC-14】Spring MVC对静态资源的访问
    【Spring学习笔记-MVC-13.2】Spring MVC之多文件上传
    【Spring学习笔记-MVC-13】Spring MVC之文件上传
    【Spring学习笔记-MVC-12】Spring MVC视图解析器之ResourceBundleViewResolver
  • 原文地址:https://www.cnblogs.com/acm-jing/p/4443442.html
Copyright © 2011-2022 走看看