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

    ◆2.11② 设顺序表L中的数据元素递增有序。
    试写一算法,将x插入到L的适当位置上,并保
    持该表的有序性。
    要求实现下列函数:
    void InsertOrderList(SqList &L, ElemType x)
    /* 在有序的顺序表 L 中保序插入数据元素 x */
    顺序表类型定义如下:
    typedef struct {
    ElemType *elem;
    int length;
    int listsize;
    } SqList;

    void InsertOrderList(SqList &L, ElemType x)  
    // 在有序的顺序表 L 中保序插入数据元素 x  
    {  
        ElemType *p,*q;  
        p=L.elem;      
        while(*p<x&&p<=(L.elem+L.length-1)){//注意此处必须要注意-1,  
        //容易粗心犯错的地方!  
            ++p;  
       }  
       //p为大于X的第一个元素指针     
       if(L.length==L.listsize){  
       L.elem=(ElemType *)realloc(L.elem,L.listsize+10);  
           if(L.elem){  
                exit(OVERFLOW);  
           }  
           L.listsize+=10;  
       }  
       for(q=L.elem+L.length-1;q>=p;q--){  
            *(q+1)=*q;  
       }  
       *p=x;  
       ++L.length;  
    }

    ◆2.12③ 设A=(a1,…,am)和B=(b1,…,bn)均为有序顺序表,
    A’和B’分别为A和B中除去最大共同前缀后的子表(例如,
    A=(x,y,y,z,x,z),B=(x,y,y,z,y,x,x,z),则两者中最大
    的共同前缀为(x,y,y,z), 在两表中除去最大共同前缀后
    的子表分别为A’=(x,z)和B’=(y,x,x,z))。若A’=B’=空表,
    则A=B;若A’=空表,而B’≠ 空表,或者两者均不为空表,
    且A’的首元小于B’的首元,则A<b;否则a>B。试写一个比
    较A和B大小的算法。(注意:在算法中,不要破坏原表A
    和B,也不一定先求得A’和B’才进行比较)。
    要求实现下列函数:
    char Compare(SqList A, SqList B);
    /* 比较顺序表A和B, */
    /* 返回’<', 若A<b; *="" <br=""> /* '=', 若A=B; */
    /* '>‘, 若A>B */
    顺序表类型定义如下:
    typedef struct {
    ElemType *elem;
    int length;
    int listsize;
    } SqList;

    char Compare(SqList A, SqList B)  
    // 比较顺序表A和B,   
    //   返回'<', 若A<B;  
    //       '=', 若A=B;  
    //       '>', 若A>B  
    {     
        char a,b;  
        int la=1,lb=1;  
        while(la<=A.length&&lb<=B.length){  
            if(*(A.elem+la-1)>*(B.elem+lb-1)){return '>';}  
            else if(*(A.elem+la-1)<*(B.elem+lb-1)){return '<';}            
            ++la;  
            ++lb;  
        }  
        if(A.length==B.length) return '=';  //此处应先判断长度是否相等!!  
        if(la==A.length+1){return '<';}  
        if(lb==B.length+1){return '>';}  
          
    }

    2.13② 试写一算法在带头结点的单链表结构上实现线性表操作
    Locate(L,x)。
    实现下列函数:
    LinkList Locate(LinkList L, ElemType x);
    // If ‘x’ in the linked list whose head node is pointed
    // by ‘L’, then return pointer pointing node ‘x’,
    // otherwise return ‘NULL’
    单链表类型定义如下:
    typedef struct LNode {
    ElemType data;
    struct LNode *next;
    } LNode, *LinkList;

    LinkList Locate(LinkList &L, ElemType x)  
    //  If 'x' in the linked list whose head node is pointed  
    //  by 'L', then return pointer ha pointing node 'x',  
    //  otherwise return 'NULL'  
    {  
        LinkList p=L->next;  
        while(p){         
            if(x==p->data){  
                return p;  
            }  
            p=p->next;  
        }  
        return NULL;                  
    }

    2.14② 试写一算法在带头结点的单链表结构上实现线性表
    操作Length(L)。
    实现下列函数:
    int Length(LinkList L);
    // Return the length of the linked list
    // whose head node is pointed by ‘L’
    单链表类型定义如下:
    typedef struct LNode{
    ElemType data;
    struct LNode *next;
    } LNode, *LinkList;

    int Length(LinkList L)  
    // Return the length of the linked list   
    // whose head node is pointed by 'L'  
    {  
        int i=0;  
        LinkList p=L;  
        while(p->next){  
            ++i;   
            p=p->next;  
        }  
        return i;  
    }

    2.17② 试写一算法,在无头结点的动态单链表上实现
    线性表操作INSERT(L,i,b),并和在带头结点的动态单
    链表上实现相同操作的算法进行比较。
    实现下列函数:
    void Insert(LinkList &L, int i, ElemType b);
    单链表类型定义如下:
    typedef struct LNode{
    ElemType data;
    struct LNode *next;
    } LNode, *LinkList;

    //思路不是很清晰,很多细节问题,调试了很长时间  
    //主要考虑问题:1、i为0或负数时  2、i在链表长度内 3、i为链表长度+1时  4、代码精简  
    void Insert(LinkList &L, int i, ElemType b)  
    {      
        int j,count;  
        LinkList p=L,q=L;    
        if(i<0){exit(OVERFLOW);}  
        for(count=0;p!=NULL;++count){  
            p=p->next;  
        }  
        if(1==i){  
            p=(LinkList)malloc(sizeof(LNode));  
            p->data=b;  
            p->next=L;  
            L=p;          
        }   
        else if (i>1&&i<=count+1){          
            for(p=L,j=1;j<=i-1&&p;++j){  
            q=p;//p为第j个元素的指针,q为p的j-1个指针  
            p=p->next;  
            }  
            p=(LinkList)malloc(sizeof(LNode));  
            p->data=b;  
            p->next=q->next;  
            q->next=p;  
        }  
    }

    2.18② 同2.17题要求。试写一算法,
    实现线性表操作DELETE(L,i)。
    实现下列函数:
    void Delete(LinkList &L, int i);
    单链表类型定义如下:
    typedef struct LNode{
    ElemType data;
    struct LNode *next;
    } LNode, *LinkList;

    void Delete(LinkList &L, int i)  
    {  
        int j;  
        int count=0;  
        LinkList p=L,q;  
    //1、求链表长度  
        while(p){  
            p=p->next;  
            ++count;  
        }  
    //2、查找第i-1号元素  
    //特殊位置首位、末尾  
        p=L;  
        if(1==i){  
            L=p->next;  
            free(p);  
        } //i==0时没问题  
        else if(i>1&&i<=count)  
        {  
            for(p=L,j=1;j<i-1;++j){  
            p=p->next;  
            }  
            q=p->next;  
            p->next=q->next;  
            free(q);  
        }  
                  
    }

    2.20② 同2.19题条件,试写一高效的算法,删除表中所
    有值相同的多余元素 (使得操作后的线性表中所有元素的
    值均不相同) 同时释放被删结点空间,并分析你的算法的
    时间复杂度。
    实现下列函数:
    void Purge(LinkList &L);
    单链表类型定义如下:
    typedef struct LNode{
    ElemType data;
    struct LNode *next;
    } LNode, *LinkList;

    void Purge(LinkList &L)  
    {  
        ElemType last=L->next->data;  
        LinkList q=L->next,p=L->next;  
        while(p){  
            if(last==p->data&&p!=L->next){  
                q->next=p->next;  
                free(p);  
                p=q;  
            }  
            else   
            {last=p->data;}   
            q=p;         
           p=p->next;  
        }  
          
    }

    ◆2.21③ 试写一算法,实现顺序表的就地逆置,
    即利用原表的存储空间将线性表(a1,a2,…,an)
    逆置为(an,an-1,…,a1)。
    实现下列函数:
    void Inverse(SqList &L);
    顺序表类型定义如下:
    typedef struct {
    ElemType *elem;
    int length;
    int listsize;
    } SqList;

    void Inverse(SqList &L)  
    {  
        int i;  
        ElemType *p,temp;  
        p=L.elem;  
        for(i=0;i<L.length/2;++i){  
            temp=*(L.elem+i);  
            *(L.elem+i)=*(L.elem+L.length-i-1);  
            *(L.elem+L.length-i-1)=temp;  
        }          
    }

    ◆2.22③ 试写一算法,对单链表实现就地逆置。
    实现下列函数:
    void Inverse(LinkList &L);
    /* 对带头结点的单链表L实现就地逆置 */
    单链表类型定义如下:
    typedef struct LNode{
    ElemType data;
    struct LNode *next;
    } LNode, *LinkList;

    void Inverse(LinkList &L)   
    /* 对带头结点的单链表L实现就地逆置 */  
    {  
        LinkList last,cur,q;  
        q=L->next; //保存首元素地址  
        last=L->next;//上一个指针  
        cur=L->next; //当前操作的指针  
        if(cur){  
            while(cur){//此处没注意,写成了!cur,大意失荆州啊!   
                cur=L->next;  
                L->next=cur->next;  
                cur->next=last;          
                if(cur){last=cur;}  
            }  
           L->next=last;  
           q->next=NULL;  
       }      
    }

    2.23③ 设线性表A=(a1,…,am), B=(b1,…,bn),试写
    一个按下列规则合并A、B为线性表C的算法,即使得
    C=(a1,b1,…,am,bm,bm+1,…,bn) 当m≤n时;
    或者 C=(a1,b1,…,an,bn,an+1,…,am) 当m>n时。
    线性表A、B和C均以单链表作存储结构,且C表利用A表和
    B表中的结点空间构成。注意:单链表的长度值m和n均未
    显式存储。
    实现下列函数:
    void Merge(LinkList ha, LinkList hb, LinkList &hc)
    /* 依题意,合并带头结点的单链表ha和hb为hc */
    单链表类型定义如下:
    typedef struct LNode{
    ElemType data;
    struct LNode *next;
    } LNode, *LinkList;

    void Merge(LinkList ha, LinkList hb, LinkList &hc)  
    /* 依题意,合并带头结点的单链表ha和hb为hc  */  
    {  
        LinkList cur_a,cur_b,cur_c;  
        cur_a=ha->next;  
        cur_b=hb->next;     
        cur_c=ha;//这里要注意给cur_c赋值,不然地址为空  
        while(cur_a&&cur_b){  
            cur_c->next=cur_a;//Lc的next指向a;  
            cur_c=cur_c->next;//cur_c指向c->next  
            cur_a=cur_a->next;//cur_a指向a->next  
            cur_c->next=cur_b;//cur_c的next指向b  
            cur_c=cur_c->next;//cur_c指向b  
            cur_b=cur_b->next;//cur_b指向b->next  
        }  
        if(cur_a){  
            cur_c->next=cur_a;  
        }  
        if(cur_b){  
            cur_c->next=cur_b;  
        }   
        hc=ha;  
    }

    ◆2.24④ 假设有两个按元素值递增有序排列的线性表
    A和B,均以单链表作存储结构,请编写算法将A表和B表
    归并成一个按元素值递减有序(即非递增有序,允许表
    中含有值相同的元素)排列的线性表C, 并要求利用原
    表(即A表和B表)的结点空间构造C表。
    实现下列函数:
    void Union(LinkList &lc, LinkList la, LinkList lb);
    /* 依题意,利用la和lb原表的结点空间构造lc表 */
    单链表类型定义如下:
    typedef struct LNode{
    ElemType data;
    struct LNode *next;
    } LNode, *LinkList;

    void Union(LinkList &lc, LinkList &la, LinkList &lb)  
    {  
        LinkList temp,last,q;  
        if(la->next->data<=lb->next->data){  
            q=la->next;last=la->next;  
        }  
        else {  
            q=lb->next;last=lb->next;  
        }  
        while(la->next&&lb->next){  
            if(la->next->data<=lb->next->data){  
                temp=la->next;  
                la->next=temp->next;  
                temp->next=last;              
              last=temp;  
            }  
            else{  
                temp=lb->next;  
                lb->next=temp->next;  
                temp->next=last;              
                 last=temp;  
            }          
        }   
        //  
        while(la->next){  
            temp=la->next;  
            la->next=temp->next;  
            temp->next=last;              
            last=temp;  
        }  
        while(lb->next){  
            temp=lb->next;  
            lb->next=temp->next;  
            temp->next=last;              
             last=temp;  
        }  
       q->next=NULL;  
       lc=la;  
       lc->next=temp;  
    }

    2.31② 假设某个单向循环链表的长度大于1,且表
    中既无头结点也无头指针。已知s为指向链表中某个
    结点的指针,试编写算法在链表中删除指针s所指结
    点的前驱结点。
    实现下列函数:
    ElemType DeleteNode(LinkList s);
    /* 删除指针s所指结点的前驱结点,并返回被删结点的元素值 */
    单链表类型定义如下:
    typedef struct LNode{
    ElemType data;
    struct LNode *next;
    } LNode, *LinkList;

    ElemType DeleteNode(LinkList s)   
    /* 删除指针s所指结点的前驱结点,并返回被删结点的元素值 */  
    {  
        ElemType e;  
        LinkList p,temp=s;  
        while(temp->next->next!=s){  
            temp=temp->next;  
        }  
        e=temp->next->data;  
        p=temp->next;  
        temp->next=s;  
        free(p);      
        return e;          
    }

    2.32② 已知有一个单向循环链表,其每个结点中
    含三个域:prev、data和next,其中data为数据域,
    next为指向后继结点的指针域,prev也为指针域,
    但它的值为空(NULL),试编写算法将此单向循环链
    表改为双向循环链表,即使prev成为指向前驱结点
    的指针域。
    实现下列函数:
    void PerfectBiLink(BiLinkList &CL);
    双向循环链表类型定义如下:
    typedef struct BiNode {
    ElemType data;
    int freq; // 2.38题用
    struct BiNode *prev,
    *next;
    } BiNode, *BiLinkList;

    void PerfectBiLink(BiLinkList &CL)  
    {  
        BiLinkList p;  
        p=CL;  
        p->next->prev=p;  
        p=p->next;  
        while(p!=CL){  
            p->next->prev=p;  
            p=p->next;  
        }  
    }

    ◆2.33③ 已知由一个线性链表表示的线性表中含有
    三类字符的数据元素(如:字母字符、数字字符和其
    它字符),试编写算法将该线性链表分割为三个循环
    链表,其中每个循环链表表示的线性表中均只含一类
    字符。
    实现下列函数:
    void Split(LinkList &lc, LinkList &ld, LinkList &lo, LinkList ll);
    单链表类型定义如下:
    typedef struct LNode{
    ElemType data;
    struct LNode *next;
    } LNode, *LinkList;

    void Split(LinkList &lc, LinkList &ld, LinkList &lo, LinkList ll)  
    {  
        LinkList p,cur_c,cur_d,cur_o;  
        p=ll->next;  
        cur_c=lc;  
        cur_d=ld;  
        cur_o=lo;  
        while(p){  
            if(p->data>='A'&&p->data<='z'){              
                cur_c->next=p;  
                cur_c=cur_c->next;  
            }  
            else if(p->data>='0'&&p->data<='9'){  
                cur_d->next=p;  
                cur_d=cur_d->next;  
            }  
            else{  
                cur_o->next=p;  
                cur_o=cur_o->next;  
            }  
        p=p->next;  
        }  
        cur_c->next=lc;  
        cur_d->next=ld;  
        cur_o->next=lo;  
    }

    2.37④ 设以带头结点的双向循环链表表示的线性
    表L=(a1,a2,…,an)。试写一时间复杂度为O(n)的
    算法,将L改造为L=(a1,a3,…,an,…,a4,a2)。
    实现下列函数:
    void ReverseEven(BiLinkList &L);
    双向循环链表类型定义如下:
    typedef struct BiNode {
    ElemType data;
    int freq; // 2.38题用
    struct BiNode *prev,
    *next;
    } BiNode, *BiLinkList;

    void ReverseEven(BiLinkList &L)  
    {     
        BiLinkList last,p,temp;  
        int count=0; //用count计结点个数  
        p=L->next; //p指向第一个元素  
        while(p!=L->prev){//求链表长度-1  
            ++count;  
            p=p->next;          
        }      
        last=p;//获得最后一个元素的地址  
        if(count>=2){  
        p=p->prev;  
        while(p!=L->next){//当p指向的不是第一个元素时         
            if(0==count%2){//判断是否序号为偶数的结点  
                temp=p;  
                p=p->prev;  
                temp->prev->next=temp->next;  
                temp->next->prev=temp->prev;  
                last->next=temp;  
                temp->prev=last;  
                last=temp;              
            }  
            else{//奇号结点则继续往前  
                p=p->prev;   
            }   
            --count;  
        }  
        last->next=L;//构建循环  
        L->prev=last;//构建循环  
        }  
    }

    ◆2.39③ 试对稀疏多项式Pn(x)采用存储量同多项式项
    数m成正比的顺序存储结构,编写求Pn(x0)的算法(x0为
    给定值),并分析你的算法的时间复杂度。
    实现下列函数:
    float Evaluate(SqPoly pn, float x);
    /* pn.data[i].coef 存放ai, */
    /* pn.data[i].exp存放ei (i=1,2,…,m) */
    /* 本算法计算并返回多项式的值。不判别溢出。 */
    /* 入口时要求0≤e1<e2<...<em,算法内不对此再作验证* <br=""> 多项式的顺序存储结构:
    typedef struct {
    int coef;
    int exp;
    } PolyTerm;
    typedef struct {
    PolyTerm *data;
    int length;
    } SqPoly;

    float Evaluate(SqPoly pn, float x)  
    /* pn.data[i].coef 存放ai,                      */  
    /* pn.data[i].exp存放ei (i=1,2,...,m)            */  
    /* 本算法计算并返回多项式的值。不判别溢出。      */  
    /* 入口时要求0≤e1<e2<...<em,算法内不对此再作验证*/  
    {  
        int i=0,j=1,cur;//没想到这题目的数据i是从零开始的。  
        float total=0,temp=1;      
        while(i<pn.length){  
            for(cur=pn.data[i].exp;j<=cur;++j){  
                temp*=x;  
            }  
            total+=temp*(pn.data[i].coef);  
            ++i;  
        }          
        return total;  
    }

    ◆2.41② 试以循环链表作稀疏多项式的存储结构,
    编写求其导函数的算法,要求利用原多项式中的结
    点空间存放其导函数(多项式),同时释放所有无
    用(被删)结点。
    实现下列函数:
    void Difference(LinkedPoly &pa);
    /* 稀疏多项式 pa 以循环链表作存储结构, */
    /* 将此链表修改成它的导函数,并释放无用结点 */
    链式多项式的类型定义:
    typedef struct PolyNode {
    int coef;
    int exp;
    struct PolyNode *next;
    } PolyNode, *PolyLink; // 多项式元素(项)结点类型
    typedef PolyLink LinkedPoly; // 链式多项式

    void Difference(LinkedPoly &pa)  
    /* 稀疏多项式 pa 以循环链表作存储结构,     */  
    /* 将此链表修改成它的导函数,并释放无用结点 */  
    {  
        LinkedPoly cur=pa->next,last=pa->next,tail=pa->next;  
        if(pa->next){//此处改为cur时遇到空表会出错,不知道为什么  
        if(0==last->exp){cur=cur->next;last->coef=0;}      
        while(cur!=pa){  
            last->coef=cur->coef*(cur->exp);  
            last->exp=cur->exp-1;  
            tail=last;  
            last=last->next;  
            cur=cur->next;                          
        }  
        if(cur=last->next){free(last);tail->next=pa;}  
        }  
    }
  • 相关阅读:
    CSDN社区之星专訪:我的蜕变之路
    Linux中运行.sh脚本,异常/bin/sh^M: bad interpreter: No such file or directory。
    00075_BigInteger
    Delphi中Interface接口的使用方法
    Delphi结构体的扩展,可以自动初始化,反初始化,自定义拷贝函数.
    关于指针和堆栈
    Delphi 中的 procedure of object
    MikroTik RouterOS防火墙与过滤详解
    用 ROS 做内网DNS服务器
    GR32 TImage32的图层绘制原理
  • 原文地址:https://www.cnblogs.com/hlb430/p/2613062.html
Copyright © 2011-2022 走看看