zoukankan      html  css  js  c++  java
  • anyview 数据结构习题集 第5章答案

    5.18⑤ 试设计一个算法,将数组A中的元素
    A[0..n-1]循环右移k位,并要求只用一个元素
    大小的附加存储,元素移动或交换次数为O(n)。
    要求实现以下函数:
    void Rotate(Array1D &a, int n, int k);
    一维数组类型Array1D的定义:
    typedef ElemType Array1D[MAXLEN];

    void Rotate(Array1D &a, int n, int k)  
    /* a[n] contains the elements,          */  
    /* rotate them right circlely by k sits */  
    {  
        ElemType *p=a,temp;  
        int i,j;  
        if(0!=k%n){//k不是n的倍数时  
            for(i=1;i<=k;++i){  
                temp=a[n-1];  
                for(j=n-2;j>=0;--j){  
                    a[j+1]=a[j];                  
                }  
                a[0]=temp;  
            }  
        }              
    }

    5.21④ 假设稀疏矩阵A和B均以三元组表作为存储结构。
    试写出矩阵相加的算法,另设三元组表C存放结果矩阵。
    要求实现以下函数:
    Status AddTSM(TSMatrix A,TSMatrix B,TSMatrix &C);
    /* 三元组表示的稀疏矩阵加法: C=A+B */
    稀疏矩阵的三元组顺序表类型TSMatrix的定义:
    #define MAXSIZE 20 // 非零元个数的最大值
    typedef struct {
    int i,j; // 行下标,列下标
    ElemType e; // 非零元素值
    }Triple;

    typedef struct {
    Triple data[MAXSIZE+1]; // 非零元三元组表,data[0]未用
    int mu,nu,tu; // 矩阵的行数、列数和非零元个数
    }TSMatrix;

    Status AddTSM(TSMatrix A,TSMatrix B,TSMatrix &C)  
    /* 三元组表示的稀疏矩阵加法: C=A+B */  
    {  
        int ai,bi,ci,aj,bj,cj,apos,bpos,cpos;  
        apos=bpos=cpos=1;  
        if(A.mu!=B.mu||A.nu!=B.nu){  
            return ERROR;      
        }  
        C.mu=A.mu;  
        C.nu=A.nu;  
        while(apos<=A.tu&&bpos<=B.tu){  
            ai=A.data[apos].i;  
            bi=B.data[bpos].i;  
            if(ai>bi){  
                ci=bi;  
                while(ci==B.data[bpos].i){  
                    C.data[cpos].i=ci;  
                    C.data[cpos].j=B.data[bpos].j;  
                    C.data[cpos].e=B.data[bpos].e;  
                    ++bpos;  
                    ++cpos;  
                }  
            }  
            else if(ai<bi){  
                ci=ai;  
                while(ci==A.data[apos].i){  
                    C.data[cpos].i=ci;  
                    C.data[cpos].j=A.data[apos].j;  
                    C.data[cpos].e=A.data[apos].e;  
                    ++apos;  
                    ++cpos;  
                }  
            }  
            else{  
                ci=ai;  
                aj=A.data[apos].j;  
                bj=B.data[bpos].j;  
                if(aj>bj){  
                    C.data[cpos].i=ci;  
                    C.data[cpos].j=bj;  
                    C.data[cpos].e=B.data[bpos].e;  
                    ++cpos;  
                    ++bpos;  
                }  
                else if(aj<bj){  
                    C.data[cpos].i=ci;  
                    C.data[cpos].j=aj;  
                    C.data[cpos].e=A.data[apos].e;  
                    ++cpos;  
                    ++apos;  
                }  
                else{  
                    cj=ai;  
                    C.data[cpos].e=A.data[apos].e+B.data[bpos].e;  
                    if(0!=C.data[cpos].e){  
                        C.data[cpos].i=ci;  
                        C.data[cpos].j=aj;  
                        ++cpos;  
                    }  
                    ++apos;  
                    ++bpos;  
                }  
            }  
        }//A稀疏矩阵完或者B稀疏矩阵完。  
        while(apos<=A.tu){//如果A矩阵中仍有元素  
            C.data[cpos].i=A.data[apos].i;  
            C.data[cpos].j=A.data[apos].j;  
            C.data[cpos].e=A.data[apos].e;  
            ++cpos;  
            ++apos;  
        }  
        while(bpos<=B.tu){//如果B矩阵中仍有元素  
            C.data[cpos].i=B.data[bpos].i;  
            C.data[cpos].j=B.data[bpos].j;  
            C.data[cpos].e=B.data[bpos].e;  
            ++cpos;  
            ++bpos;  
        }  
        C.tu=--cpos;  
        return OK;  
    }

    5.23② 三元组表的一种变型是,从三元组表中去掉
    行下标域得到二元组表,另设一个行起始向量,其每
    个分量是二元组表的一个下标值,指示该行中第一个
    非零元素在二元组表中的起始位置。试编写一个算法,
    由矩阵元素的下标值i,j求矩阵元素。试讨论这种方
    法和三元组表相比有什么优缺点。
    要求实现以下函数:
    Status GetElem(T2SMatrix M, int i, int j, ElemType &e);
    /* 求二元组矩阵的元素A[i][j]的值e */
    稀疏矩阵的二元组顺序表+行起始向量的类型T2SMatrix的定义:
    typedef struct{
    int j;
    ElemType e;
    }TwoTuples;
    typedef struct{
    TwoTuples data[MAXSIZE];
    int cpot[MAXROW]; // 这个向量存储每一行在二元组中的起始位置
    int mu,nu,tu;
    } T2SMatrix; // 二元组矩阵类型

    Status GetElem(T2SMatrix M, int i, int j, ElemType &e)  
    /* 求二元组矩阵的元素A[i][j]的值e  */  
    {  
        //竟然忘了这个是稀疏矩阵,e如果不是非零元素就是零元素  
        //还要判断i j的合法性!!  
        int cur,last;  
        cur=M.cpot[i];  
        last=M.cpot[i+1];  
        e=0;  
        if(i>M.mu||j>M.nu||i<=0||j<=0){  
            return ERROR;  
        }  
        while(cur<last){  
            if(M.data[cur].j==j){  
                e=M.data[cur].e;  
                return OK;  
            }  
            ++cur;  
        }  
        return OK;  
    }

    5.26③ 试编写一个以三元组形式输出用十字链表
    表示的稀疏矩阵中非零元素及其下标的算法。
    要求实现以下函数:
    void OutCSM(CrossList M, void(*Out3)(int, int, int));
    /* 用函数Out3,依次以三元组格式输出十字链表表示的矩阵 */
    稀疏矩阵的十字链表存储表示:
    typedef struct OLNode {
    int i,j; // 该非零元的行和列下标
    ElemType e; // 非零元素值
    OLNode *right,*down; // 该非零元所在行表和列表的后继链域
    }OLNode, *OLink;
    typedef struct {
    OLink *rhead,*chead; // 行和列链表头指针向量基址
    int mu,nu,tu; // 稀疏矩阵的行数、列数和非零元个数
    }CrossList;

    void OutCSM(CrossList M, void(*Out3)(int, int, int))  
    /* 用函数Out3,依次以三元组格式输出十字链表表示的矩阵 */  
    {  
        int i=1,row,col,e;  
        OLink p,q;  
        for(i=1;i<=M.mu;++i){  
            p=M.rhead[i];  
            while(p){              
                Out3(p->i,p->j,p->e);  
                p=p->right;  
            }              
        }  
    }

    5.30③ 试按表头、表尾的分析方法重写求广义表
    的深度的递归算法。
    要求实现以下函数:
    int GListDepth(GList ls);
    /* Return the depth of list */
    广义表类型GList的定义:
    typedef enum {ATOM,LIST} ElemTag;
    typedef struct GLNode{
    ElemTag tag;
    union {
    char atom;
    struct {
    GLNode *hp, *tp;
    } ptr;
    }un;
    } *GList;

    int GListDepth(GList ls)  
    /* Return the depth of list */  
    {  
        int max=0,len=0;  
        GList p;  
        if(!ls){  
            return 1;  
        }  
        if(ls->tag==ATOM){  
            return 0;  
        }  
        for(max=0,p=ls;p;p=p->un.ptr.tp){  
            len=GListDepth(p->un.ptr.hp);  
            if(max<len){  
                max=len;  
            }  
        }  
        return max+1;  
    }

    5.32④ 试编写判别两个广义表是否相等的递归算法。
    要求实现以下函数:
    Status Equal(GList A, GList B);
    /* 判断广义表A和B是否相等,是则返回TRUE,否则返回FALSE */
    广义表类型GList的定义:
    typedef enum {ATOM,LIST} ElemTag;
    typedef struct GLNode{
    ElemTag tag;
    union {
    char atom;
    struct {
    GLNode *hp, *tp;
    } ptr;
    }un;
    } *GList;

    Status Equal(GList A, GList B)  
    /* 判断广义表A和B是否相等,是则返回TRUE,否则返回FALSE */  
    {  
    //基本思想:分三种情况1、若果都为原子节点,则判断是否相等  2、如果都为广义表,则递归返回两个广义表比较结果  
    //3、其它情况直接返回FALSE;  
        if(ATOM==A->tag&&ATOM==B->tag){//情况1  
            if(A->un.atom==B->un.atom){  
                return TRUE;  
            }  
            else{  
                return FALSE;  
            }  
          
        }  
        else if(LIST==A->tag&&LIST==B->tag){//情况2  
                return Equal(A->un.ptr.hp,B->un.ptr.hp)&&Equal(A->un.ptr.tp,B->un.ptr.tp);  
        }  
        else{//情况3  
            return FALSE;  
        }          
    }

    5.33④ 试编写递归算法,输出广义表中所有原子项
    及其所在层次。
    要求实现以下函数:
    void OutAtom(GList A, int layer, void(*Out2)(char, int));
    /* 递归地用函数Out2输出广义表的原子及其所在层次,layer表示当前层次 */
    广义表类型GList的定义:
    typedef enum {ATOM,LIST} ElemTag;
    typedef struct GLNode{
    ElemTag tag;
    union {
    char atom;
    struct {
    GLNode *hp, *tp;
    } ptr;
    }un;
    } *GList;

    void OutAtom(GList A, int layer, void(*Out2)(char, int))  
    /* 递归地用函数Out2输出广义表的原子及其所在层次,layer表示当前层次 */  
    {  
        if(A){  
            GList p;         
            if(ATOM==A->tag){  
                Out2(A->un.atom,layer);  
            }  
            else{  
                   p=A->un.ptr.hp;  
                   OutAtom(p,layer+1,Out2);  
                   p=A->un.ptr.tp;  
                   OutAtom(p,layer,Out2);//表尾所在层是当前层,所以此处不能为layer+1  
            }  
        }  
    }
  • 相关阅读:
    软件工程 2016.6.28 日报
    软件工程课程总结
    工大助手--项目总结
    工大助手--加权平均分计算
    工大助手--数据查询
    7.5
    7月4日日报
    7.3日报
    6.30日报
    6.29.日报
  • 原文地址:https://www.cnblogs.com/hlb430/p/2613059.html
Copyright © 2011-2022 走看看