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  
        }  
    }  
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM