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  
        }  
    }  
}
原文地址:https://www.cnblogs.com/hlb430/p/2613059.html