数据结构实践项目——链表

简介: 本组项目针对《数据结构基础系列(2):线性表》课程第8-15节 8. 线性表的链式存储 9. 建立单链表 10. 单链表基本操作的实现 11. 单链表应用举例 12. 双链表 13. 循环链表 14. 线性表的应用 15. 有序表 【项目1 - 建立单链表】   定义单链表存储结构,用头插法和尾插法建立单链表,并显示建立好以后的结果。   请

本组项目针对《数据结构基础系列(2):线性表》课程第8-15节
8. 线性表的链式存储
9. 建立单链表
10. 单链表基本操作的实现
11. 单链表应用举例
12. 双链表
13. 循环链表
14. 线性表的应用
15. 有序表

【项目1 - 建立单链表】
  定义单链表存储结构,用头插法和尾插法建立单链表,并显示建立好以后的结果。
  请在下面代码的基础上开展工作:

#include <stdio.h>
#include <malloc.h>
typedef int ElemType;
typedef struct LNode        //定义单链表结点类型
{
    ElemType data;
    struct LNode *next;     //指向后继结点
} LinkList;

void CreateListF(LinkList *&L,ElemType a[],int n);//头插法建立单链表
void CreateListR(LinkList *&L,ElemType a[],int n);//尾插法建立单链表
void DestroyList(LinkList *&L); //销毁单链表
void DispList(LinkList *L)  //输出单链表

int main()
{
    LinkList *L1, *L2;
    ElemType a[8]= {7, 9, 8, 2, 0, 4, 6, 3};
    CreateListF(L1, a, 8);
    printf("头插法建表结果:");
    DispList(L1);
    CreateListR(L2, a, 6);
    printf("尾插法建表结果:");
    DispList(L2);
    DestroyList(L1);
    DestroyList(L2);
    return 0;
}
//在下面写自定义函数(实现相关算法)的代码

参考解答

【项目2 - 建设“单链表”算法库】
  按照“0207将算法变程序”部分建议的方法,建设自己的专业基础设施算法库。这一周,建的是单链表的算法库。
  算法库包括两个文件:
  头文件:linklist.h,包含定义顺序表数据结构的代码、宏定义、要实现算法的函数的声明;
  源文件:linklist.cpp,包含实现各种算法的函数的定义
  
  请采用程序的多文件组织形式,建立如上的两个文件,另外再建立一个源文件(如main.cpp),编制main函数,完成相关的测试工作。
  测试工作可以采用“渐进”的思路,每次涉及的函数应该尽可能少。
  例如,首先设计测试函数,可以涉及初始化线性表、销毁线性表、输出线性表、插入数据元素对应的函数,设计的测试函数可以是

#include "linklist.h"
int main()
{
    LinkList *L;
    InitList(L);
    ListInsert(L, 1, 15);
    ListInsert(L, 1, 10);
    ListInsert(L, 1, 5);
    ListInsert(L, 1, 20);
    DispList(L);
    DestroyList(L);
    return 0;
}

参考解答

【项目3 - 单链表应用】
  完成下面的应用时,除项目中给出的特殊要求,其余工作均可利用项目2完成的算法支持。
  1、设计一个算法,将一个带头结点的数据域依次为a1,a2,…,an(n≥3)的单链表的所有结点逆置,即第一个结点的数据域变为an,…,最后一个结点的数据域为a1。实现这个算法,并完成测试。

提示:实现算法时,可以设计下面的函数:void Reverse(LinkList *&L)

  2、已知L1和L2分别指向两个单链表的头结点,且已知其长度分别为m、n,请设计算法将L2连接到L1的后面。实现这个算法,完成测试,并分析这个算法的复杂度。

提示:实现算法时,可以设计下面的函数:void Link(LinkList &L1, LinkList &L2)

  3、设计一个算法,判断单链表L是否是递增的。实现这个算法,并完成测试。

[参考解答]

【项目4 - 建设双链表算法库(选做)】
  算法库包括两个文件:
  头文件:dlinklist.h,包含定义顺序表数据结构的代码、宏定义、要实现算法的函数的声明;
  源文件:dlinklist.cpp,包含实现各种算法的函数的定义
  请采用程序的多文件组织形式,建立如上的两个文件,另外再建立一个源文件(如main.cpp),编制main函数,完成相关的测试工作。
参考解答

【项目5 - 猴子选大王】
  一群猴子,编号是1,2,3 …m,这群猴子(m个)按照1-m的顺序围坐一圈。从第1只开始数,每数到第n个,该猴子就要离开此圈,这样依次下来,直到圈中只剩下最后一只猴子,则该猴子为大王。输入m和n,输出为大王的猴子是几号。

提示:
(1)链表解法:可以用一个循环单链表来表示这一群猴子。表示结点的结构体中有两个成员:一个保存猴子的编号,一个为指向下一个人的指针,编号为m的结点再指向编号为1的结点,以此构成环形的链。当数到第n个时,该结点被删除,继续数,直到只有一个结点。
(2)使用结构数组来表示循环链:结构体中设一个成员表示对应的猴子是否已经被淘汰。从第一个人未被淘汰的数起,每数到n时,将结构中的标记改为0,表示这只猴子已被淘汰。当数到数组中第m个元素后,重新从第一个数起,这样循环计数直到有m-1被淘汰。
(3)该问题为计算机科学中的经典问题,很多实际的问题可以抽象到这种模型上来。感兴趣的同学请搜索“约瑟夫问题”。
参考解答

【项目5- 循环双链表应用】
  设非空线性表ha和hb都用带头节点的循环双链表表示。设计一个算法Insert(ha,hb,i)。其功能是:i=0时,将线性表hb插入到线性表ha的最前面;当i>0时,将线性表hb插入到线性表ha中第i个节点的后面;当i大于等于线性表ha的长度时,将线性表hb插入到线性表ha的最后面。
  请在实现算法时,除项目中给出的特殊要求,其余工作均可利用项目4完成的算法支持。
参考解答

【项目6 - 多项式求和】
  用单链表存储一元多项式,并实现两个多项式的加法。

提示:
1、存储多项式的数据结构
  多项式的通式是 pn(x)=anxn+an1xn1+...+a1x+a0 。n次多项式共有n+1项。直观地,可以定义一个数组来存储这n+1个系数。以多项式 p(x)=3.4x109.6x8+7.2x2+x 为例,存储这个多项式的数组如下图:
这里写图片描述
  可以看出,这种方案适合对某些多项式的处理。但是,在处理一些次数高但项数少的多项式时,存在浪费空间的现象,会有很多闲置的0。
  可以使用如下定义的单链表结构存储多项式:链表中的每一个结点是多项式中的一项,结点的数据域包括指数和系数两部分,由指针域连接起多项式中的各项。

typedef struct pnode //定义单链表结点类型,保存多项式中的一项,链表构成多项式 {
double coef; //系数,浮点数
int exp; //指数,正整数*
struct pnode *next; //指向下一项的指针
} PolyNode;

  用于表示多项式的链表将如下图所示,在建立多项式的链表时,已经令结点按指数由大到小的顺序排列。
这里写图片描述

2、多项式加法在链表存储结构下的实现
  链表存储结构下,多项式加法的实现 在如上定义的单链表存储结构基础上,讨论实现多项式加法的算法。
  两个多项式相加,其规则是对具有相同指数的项,令其系数相加。设两个待相加的多项式的链表的头指针分别为head1(第一个多项式)和head2(第二个多项式),两者的和保存到链表head1中。只需要先将head1和head2链表的首结点作为当前结点(分别用p1和p2指向)开始检测,在遍历链表的过程中,分情况作如下处理:
  (1)若两个多项式中当前结点的指数值相同,则它们的系数相加,结果保存到p1结点,并将p2结点删除。如果相加后的系数不为0,p1指向第一个多项式的下一个结点,准备随后的工作,否则,不保存系数为0的项,将当前p1结点删除。
  (2)当两个多项式中对应结点的指数值不相等时,若p1指向的结点的指数大,则p1简单地指向下一结点即可;而p2指向的结点大时,需要将p2结点插入到p1前,然后p2再重新指回到第二个多项式中的下一结点,继续进行处理。
  (3)检测过程直到其中的任一个链表结束。若p1不为空,第一个多项式中的剩余项已经在链表中,不作处理,如果p2不为空,只需要将p2链接到相加后的第一个多项式末尾。
  上面的讨论假设多项式链表中,已经按指数由大到小排序,在加法之前,采取多种手段保证这一前提成立。

参考解答

目录
相关文章
|
1月前
|
存储 机器学习/深度学习 算法
C 408—《数据结构》算法题基础篇—链表(下)
408考研——《数据结构》算法题基础篇之链表(下)。
91 29
|
1月前
|
存储 算法 C语言
C 408—《数据结构》算法题基础篇—链表(上)
408考研——《数据结构》算法题基础篇之链表(上)。
103 25
|
2月前
|
存储 C语言 C++
【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
160 77
|
2月前
|
C++
【C++数据结构——树】二叉树的性质(头歌实践教学平台习题)【合集】
本文档介绍了如何根据二叉树的括号表示串创建二叉树,并计算其结点个数、叶子结点个数、某结点的层次和二叉树的宽度。主要内容包括: 1. **定义二叉树节点结构体**:定义了包含节点值、左子节点指针和右子节点指针的结构体。 2. **实现构建二叉树的函数**:通过解析括号表示串,递归地构建二叉树的各个节点及其子树。 3. **使用示例**:展示了如何调用 `buildTree` 函数构建二叉树并进行简单验证。 4. **计算二叉树属性**: - 计算二叉树节点个数。 - 计算二叉树叶子节点个数。 - 计算某节点的层次。 - 计算二叉树的宽度。 最后,提供了测试说明及通关代
60 10
|
2月前
|
存储 C++
【C++数据结构——树】哈夫曼树(头歌实践教学平台习题) 【合集】
【数据结构——树】哈夫曼树(头歌实践教学平台习题)【合集】目录 任务描述 相关知识 测试说明 我的通关代码: 测试结果:任务描述 本关任务:编写一个程序构建哈夫曼树和生成哈夫曼编码。 相关知识 为了完成本关任务,你需要掌握: 1.如何构建哈夫曼树, 2.如何生成哈夫曼编码。 测试说明 平台会对你编写的代码进行测试: 测试输入: 1192677541518462450242195190181174157138124123 (用户分别输入所列单词的频度) 预
72 14
【C++数据结构——树】哈夫曼树(头歌实践教学平台习题) 【合集】
|
2月前
|
Java C++
【C++数据结构——树】二叉树的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现二叉树的基本运算。​ 相关知识 创建二叉树 销毁二叉树 查找结点 求二叉树的高度 输出二叉树 //二叉树节点结构体定义 structTreeNode{ intval; TreeNode*left; TreeNode*right; TreeNode(intx):val(x),left(NULL),right(NULL){} }; 创建二叉树 //创建二叉树函数(简单示例,手动构建) TreeNode*create
61 12
|
2月前
|
算法 C++
【C++数据结构——图】最小生成树(头歌实践教学平台习题) 【合集】
【数据结构——图】最小生成树(头歌实践教学平台习题)目录 任务描述 相关知识 测试说明 我的通关代码: 测试结果:【合集】任务描述 本关任务:编写一个程序求图的最小生成树。相关知识 为了完成本关任务,你需要掌握:1.建立邻接矩阵,2.Prim算法。建立邻接矩阵 上述带权无向图对应的二维数组,根据它建立邻接矩阵,如图1建立下列邻接矩阵。注意:INF表示无穷大,表示整数:32767 intA[MAXV][MAXV];Prim算法 普里姆(Prim)算法是一种构造性算法,从候选边中挑
48 10
|
2月前
|
存储 算法 C++
【C++数据结构——图】图的邻接矩阵和邻接表的存储(头歌实践教学平台习题)【合集】
本任务要求编写程序实现图的邻接矩阵和邻接表的存储。需掌握带权有向图、图的邻接矩阵及邻接表的概念。邻接矩阵用于表示顶点间的连接关系,邻接表则通过链表结构存储图信息。测试输入为图的顶点数、边数及邻接矩阵,预期输出为Prim算法求解结果。通关代码提供了完整的C++实现,包括输入、构建和打印邻接矩阵与邻接表的功能。
59 10
|
2月前
|
C++
【C++数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】
【数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】(1)遇到左括号:进栈Push()(2)遇到右括号:若栈顶元素为左括号,则出栈Pop();否则返回false。(3)当遍历表达式结束,且栈为空时,则返回true,否则返回false。本关任务:编写一个程序利用栈判断左、右圆括号是否配对。为了完成本关任务,你需要掌握:栈对括号的处理。(1)遇到左括号:进栈Push()开始你的任务吧,祝你成功!测试输入:(()))
48 7
|
2月前
|
存储 C++ 索引
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
【数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】初始化队列、销毁队列、判断队列是否为空、进队列、出队列等。本关任务:编写一个程序实现环形队列的基本运算。(6)出队列序列:yzopq2*(5)依次进队列元素:opq2*(6)出队列序列:bcdef。(2)依次进队列元素:abc。(5)依次进队列元素:def。(2)依次进队列元素:xyz。开始你的任务吧,祝你成功!(4)出队一个元素a。(4)出队一个元素x。
53 13
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】