数据结构第2章课后习题答案(下)

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
EMR Serverless StarRocks,5000CU*H 48000GB*H
网络型负载均衡 NLB,每月750个小时 15LCU
简介: 数据结构第2章课后习题答案(下)

2将两个非递减的有序链表合并为一个非递增的有序链表。要求结果链表仍使用原来两个链表的存储空间, 不另外占用其它的存储空间。表中允许有重复的数据。

[题目分析]

合并后的新表使用头指针Lc指向,pa和pb分别是链表LaLb的工作指针,初始化为相应链表的第一个结点,从第一个结点开始进行比较,当两个链表La和Lb均为到达表尾结点时,依次摘取其中较小者重新链接在Lc表的表头结点之后,如果两个表中的元素相等,只摘取La表中的元素,保留Lb表中的元素。当一个表到达表尾结点,为空时,将非空表的剩余元素依次摘取,链接在Lc表的表头结点之后。

[算法描述]

void MergeList(LinkList& La, LinkList& Lb, LinkList& Lc, )

{//合并链表La和Lb,合并后的新表使用头指针Lc指向

 pa=La->next;  pb=Lb->next;

//pa和pb分别是链表LaLb的工作指针,初始化为相应链表的第一个结点

 Lc=pc=La; //用La的头结点作为Lc的头结点

 Lc->next=NULL;

 while(pa||pb )

{//只要存在一个非空表,用q指向待摘取的元素

   if(!pa)  {q=pb;  pb=pb->next;}

//La表为空,用q指向pb,pb指针后移

   else if(!pb)  {q=pa;  pa=pa->next;}

//Lb表为空,用q指向pa,pa指针后移

   else if(pa->data<=pb->data)  {q=pa;  pa=pa->next;}

//取较小者(包括相等)La中的元素,用q指向pa,pa指针后移

   else {q=pb;  pb=pb->next;}

//取较小者Lb中的元素,用q指向pb,pb指针后移

    q->next = Lc->next;  Lc->next = q;  

//将q指向的结点插在Lc 表的表头结点之后

   }

   delete Lb;             //释放Lb的头结点

}  

3已知两个链表A和B分别表示两个集合,其元素递增排列。请设计算法求出A与B的交集,并存放于A链表中。

[题目分析]

只有同时出现在两集合中的元素才出现在结果表中,合并后的新表使用头指针Lc指向。pa和pb分别是链表LaLb的工作指针,初始化为相应链表的第一个结点,从第一个结点开始进行比较,当两个链表La和Lb均为到达表尾结点时,如果两个表中相等的元素时,摘取La表中的元素,删除Lb表中的元素;如果其中一个表中的元素较小时,删除此表中较小的元素,此表的工作指针后移。当链表La和Lb有一个到达表尾结点,为空时,依次删除另一个非空表中的所有元素。

[算法描述]

void Mix(LinkList& La, LinkList& Lb, LinkList& Lc)

{  pa=La->next;pb=Lb->next;

pa和pb分别是链表LaLb的工作指针,初始化为相应链表的第一个结点

Lc=pc=La; //La的头结点作为Lc的头结点

while(pa&&pb)

{ if(pa->data==pb->data)∥交集并入结果表中。

  { pc->next=pa;pc=pa;pa=pa->next;

   u=pb;pb=pb->next; delete u;}

 else if(pa->data<pb->data) {u=pa;pa=pa->next; delete u;}

else {u=pb; pb=pb->next; delete u;}

}

while(pa) {u=pa; pa=pa->next; delete u;}∥ 释放结点空间

while(pb) {u=pb; pb=pb->next; delete u;}∥释放结点空间

pc->next=null;∥置链表尾标记。

delete Lb;  //释放Lb的头结点

  }

4已知两个链表A和B分别表示两个集合,其元素递增排列。请设计算法求出两个集合A和B 的差集(即仅由在A中出现而不在B中出现的元素所构成的集合),并以同样的形式存储,同时返回该集合的元素个数。

[题目分析]

求两个集合A和B的差集是指在A中删除A和B中共有的元素,即删除链表中的相应结点,所以要保存待删除结点的前驱,使用指针pre指向前驱结点。pa和pb分别是链表LaLb的工作指针,初始化为相应链表的第一个结点,从第一个结点开始进行比较,当两个链表La和Lb均为到达表尾结点时,如果La表中的元素小于Lb表中的元素,pre置为La表的工作指针pa删除Lb表中的元素;如果其中一个表中的元素较小时,删除此表中较小的元素,此表的工作指针后移。当链表La和Lb有一个为空时,依次删除另一个非空表中的所有元素。

[算法描述]

void DifferenceLinkList& La, LinkList& Lb,int *n

{∥差集的结果存储于单链表La中,*n是结果集合中元素个数,调用时为0

pa=La->next; pb=Lb->next;    

∥pa和pb分别是链表LaLb的工作指针,初始化为相应链表的第一个结点

 pre=La;          ∥pre为La中pa所指结点的前驱结点的指针

 while(pa&&pb)

{if(pa->data<q->data){pre=pa;pa=pa->next;*n++;}

∥ A链表中当前结点指针后移

else if(pa->data>q->data)q=q->next;     ∥B链表中当前结点指针后移

   else {pre->next=pa->next;      ∥处理A,B中元素值相同的结点,应删除

         u=pa; pa=pa->next; delete u;}   ∥删除结点

}

}

5设计算法将一个带头结点的单链表A分解为两个具有相同结构的链表B、C,其中B表的结点为A表中值小于零的结点,而C表的结点为A表中值大于零的结点(链表A中的元素为非零整数,要求B、C表利用A表的结点)。

[题目分析]

B表的头结点使用原来A表的头结点,为C表新申请一个头结点。从A表的第一个结点开始,依次取其每个结点p,判断结点p的值是否小于0,利用前插法,将小于0的结点插入B表,大于等于0的结点插入C表。

[算法描述]

void DisCompose(LinkedList A)

{  B=A;

B->next= NULL;    ∥B表初始化

    C=new LNode;∥为C申请结点空间

    C->next=NULL;     ∥C初始化为空表

    p=A->next;        ∥p为工作指针

    while(p!= NULL)

    { r=p->next;      ∥暂存p的后继

      if(p->data<0)

       {p->next=B->next; B->next=p; }∥将小于0的结点链入B表,前插法

      else {p->next=C->next; C->next=p; }∥大于等于0的结点链入C表,前插法

      p=r;∥p指向新的待处理结点。

    }

}

6设计一个算法,通过一趟遍历在单链表中确定值最大的结点。

[题目分析]

假定第一个结点中数据具有最大值,依次与下一个元素比较,若其小于下一个元素,则设其下一个元素为最大值,反复进行比较,直到遍历完该链表。

[算法描述]

ElemType Max (LinkList L ){

if(L->next==NULL) return NULL;

pmax=L->next; //假定第一个结点中数据具有最大值

p=L->next->next;

while(p != NULL ){//如果下一个结点存在

   if(p->data > pmax->data) pmax=p;//如果p的值大于pmax的值,则重新赋值

   p=p->next;//遍历链表

}

return pmax->data;

7设计一个算法,通过遍历一趟,将链表中所有结点的链接方向逆转,仍利用原表的存储空间。

[题目分析]

从首元结点开始,逐个地把链表L的当前结点p插入新的链表头部。

[算法描述]

void  inverse(LinkList &L)

{// 逆置带头结点的单链表 L

   p=L->next;  L->next=NULL;

   while ( p) {

       q=p->next;    // q指向*p的后继

       p->next=L->next;

       L->next=p;       // *p插入在头结点之后

       p = q;

   }

}

8设计一个算法,删除递增有序链表中值大于mink且小于maxk的所有元素(mink和maxk是给定的两个参数,其值可以和表中的元素相同,也可以不同 )。

[题目分析]

分别查找第一个值>mink的结点和第一个值 ≥maxk的结点,再修改指针,删除值大于mink且小于maxk的所有元素。

[算法描述]

void delete(LinkList &L, int mink, int maxk) {

  p=L->next; //首元结点

  while (p && p->data<=mink)

     { pre=p;  p=p->next; } //查找第一个值>mink的结点

  if (p)

{while (p && p->data<maxk)  p=p->next;

                     // 查找第一个值 ≥maxk的结点

     q=pre->next;   pre->next=p;  // 修改指针

     while (q!=p)

        { s=q->next;  delete q;  q=s; } // 释放结点空间

  }//if

}

9已知p指向双向循环链表中的一个结点,其结点结构为data、prior、next三个域,写出算法change(p),交换p所指向的结点和它的前缀结点的顺序。

[题目分析]

知道双向循环链表中的一个结点,与前驱交换涉及到四个结点(p结点,前驱结点,前驱的前驱结点,后继结点)六条链。

[算法描述]

void  Exchange(LinkedList p)

∥p是双向循环链表中的一个结点,本算法将p所指结点与其前驱结点交换。

{q=p->llink

q->llink->rlink=p;   ∥p的前驱的前驱之后继为p

p->llink=q->llink;   ∥p的前驱指向其前驱的前驱。

q->rlink=p->rlink;   ∥p的前驱的后继为p的后继。

q->llink=p;          ∥p与其前驱交换

p->rlink->llink=q;   ∥p的后继的前驱指向原p的前驱

p->rlink=q;          ∥p的后继指向其原来的前驱

}∥算法exchange结束。

10已知长度为n的线性表A采用顺序存储结构,请写一时间复杂度为O(n)、空间复杂度为O(1)的算法,该算法删除线性表中所有值为item的数据元素。

[题目分析]

在顺序存储的线性表上删除元素,通常要涉及到一系列元素的移动(删第i个元素,第i+1至第n个元素要依次前移)。本题要求删除线性表中所有值为item的数据元素,并未要求元素间的相对位置不变。因此可以考虑设头尾两个指针(i=1,j=n),从两端向中间移动,凡遇到值item的数据元素时,直接将右端元素左移至值为item的数据元素位置。

[算法描述]

void  Delete(ElemType A[ ],int  n)

∥A是有n个元素的一维数组,本算法删除A中所有值为item的元素。

{i=1;j=n;∥设置数组低、高端指针(下标)。

while(i<j)

  {while(i<j && A[i]!=item)i++;         ∥若值不为item,左移指针。

   if(i<j)while(i<j && A[j]==item)j--;∥若右端元素为item,指针左移

   if(i<j)A[i++]=A[j--];}

相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
目录
相关文章
|
22天前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之顺序表习题精讲【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找习题精讲等具体详解步骤以及举例说明
|
1月前
|
存储 Java
数据结构第三篇【链表的相关知识点一及在线OJ习题】
数据结构第三篇【链表的相关知识点一及在线OJ习题】
26 7
|
5月前
|
算法 C语言
数据结构和算法学习记录——栈和队列习题-用队列实现栈、用栈实现队列(核心思路、解题过程、完整题解)二
数据结构和算法学习记录——栈和队列习题-用队列实现栈、用栈实现队列(核心思路、解题过程、完整题解)二
42 2
|
5月前
|
存储 算法 测试技术
数据结构学习记录——树习题-Complete Binary Search Tree(题目描述、输入输出示例、数据结构的选择、核心算法、计算左子树的规模)
数据结构学习记录——树习题-Complete Binary Search Tree(题目描述、输入输出示例、数据结构的选择、核心算法、计算左子树的规模)
78 1
|
5月前
|
测试技术 C语言
数据结构学习记录——树习题—Tree Traversals Again(题目描述、输入输出示例、解题思路、解题方法C语言、解析)
数据结构学习记录——树习题—Tree Traversals Again(题目描述、输入输出示例、解题思路、解题方法C语言、解析)
46 1
|
5月前
|
机器学习/深度学习
数据结构学习记录——堆的小习题(对由同样的n个整数构成的二叉搜索树(查找树)和最小堆,下面哪个说法是不正确的)
数据结构学习记录——堆的小习题(对由同样的n个整数构成的二叉搜索树(查找树)和最小堆,下面哪个说法是不正确的)
37 1
|
5月前
|
算法
数据结构和算法学习记录——小习题-二叉树的遍历&二叉搜索树
数据结构和算法学习记录——小习题-二叉树的遍历&二叉搜索树
37 0
|
5月前
|
算法 C语言
数据结构和算法学习记录——栈和队列习题-用队列实现栈、用栈实现队列(核心思路、解题过程、完整题解)一
数据结构和算法学习记录——栈和队列习题-用队列实现栈、用栈实现队列(核心思路、解题过程、完整题解)一
36 0
|
5月前
|
算法 C语言
数据结构和算法学习记录——特殊线性表之栈(下)-销毁栈函数、判断栈是否为空、压栈函数、出栈函数、取栈顶元素、计算栈中有多少个元素、栈有关习题-有效的括号
数据结构和算法学习记录——特殊线性表之栈(下)-销毁栈函数、判断栈是否为空、压栈函数、出栈函数、取栈顶元素、计算栈中有多少个元素、栈有关习题-有效的括号
36 0
|
5月前
|
算法
数据结构和算法学习记录——习题-翻转链表(不带表头结点逆置算法、带表头结点的链表逆置算法)
数据结构和算法学习记录——习题-翻转链表(不带表头结点逆置算法、带表头结点的链表逆置算法)
35 0

热门文章

最新文章

下一篇
无影云桌面