数据结构实验二——单链表的基本操作(2021级zzu)
数据结构实验二——单链表的基本操作
ps: 滴~
打卡第二天,好困啊~~~~~~
数据结构实验二——单链表的基本操作
一、实验目的
了解线性表的链式存储结构和顺序存取特性,熟练掌握线性表的链式存储结构的C语言描述方法,熟练掌握动态链表的基本操作查找、插入、定位等,能在实际应用中选择适当的链表结构。掌握用链表表示特定形式的数据的方法,并能编写出有关运算的算法。
二、实验内容(选其中之一写实验报告)
(1) 已知线性表中的元素以值递增有序排列,并以单链表作存储结构。试写一高效算法,删除表中所有值大于mink且小于maxk的元素(若表中存在这样的元素)同时释放被删结点空间,并分析你的算法的时间复杂度(注意:mink和maxk是给定的两个参变量,它们的值可以和表中的元素相同,也可以不同)。
(2) 完成单链表上的如下操作:
a. 逆序建立单链表;
b. 遍历单链表 (输出单链表每个元素的值);
c. 在单链表第5个元素前插入一个值为 999 的元素;
d. 删除单链表第 5 个元素。
三、问题描述
上述题目概况:
- 删除线性表中一个开区间内的所有元素;
- 单链表的逆序建立、遍历、插入、删除操作。
四、数据结构定义
两部分均采用链式存储结构,数据元素类型整型。
五、算法思想及算法设计
(实验代码部分没有中文注释,在此部分给出)
5.1 实验内容(1)
题目:已知线性表中的元素以值递增有序排列,并以单链表作存储结构。试 写一高效算法,删除表中所有值大于mink且小于maxk的元素(若表中存在这样 的元素)同时释放被删结点空间,并分析你的算法的时间复杂度(注意:mink和 maxk是给定的两个参变量,它们的值可以和表中的元素相同,也可以不同)
思考:
大致分为以下两步:
<1> 建立一个单链表,用来存储线性表元素;
<2> 找到(mink,maxk)区间内的元素并删除,同时链接起剩余的部分以免链表断开。
5.1.1 理论实现和代码实现
<1> 建立单链表:应用结构体表示链表节点,每个节点有数据域和指针域:数 据域存放元素值,指针域指向后继节点。此处只应用了 malloc函数开辟空间,同 时还要考虑节点的指向问题。
//建立单链表
typedef struct Node
{
int data;
struct Node* next;
}*node, Link;
void InitLink(node& L) // main 函数中应用此函数
{
L = (node)malloc(sizeof(Link));
L->next = NULL;
L->data = -1;
}
void CreatLink(node& L)
{
int length, x;
printf("Please input the length of this List: ");
scanf("%d", &length);
node NewNode;
node p = (node)malloc(sizeof(Link));
p = L;
printf("Please input its content: \n");
for (int i = 0; i < length; ++i)
{
NewNode = (node)malloc(sizeof(Link));
scanf("%d", &x);
NewNode->data = x;
NewNode->next = NULL;
p->next = NewNode;
p = NewNode;
}
}
<2> 查找、删除和链接:在单链表中找满足大小关系条件的节点,只能从头结点开始往后一一遍历。利用 p指针往后寻找,由于这个表递增,如果存在满足条件的节点,当 p->data > mink 时退出循环,另设一个 pre 保存每次循环的上一个p 指针。将此 p 指针继续往后遍历,p->data >= maxk 时退出,链接 pre 和此时的 p,另设 q 完成 free。
void Delete(node& L, int mink, int maxk) {
if (mink > maxk) {
printf("Error!");
return;
}
node p = L->next, pre, q, s;
if (p == NULL)
return;
q = pre = (node)malloc(sizeof(Link));
while (p->data <= mink) {
pre = p;
p = p->next;
}
if (p) {
while (p && p->data < maxk) {
p = p->next;
}
q = pre->next;
pre->next = p;
while (q != p) {
s = q->next;
free(q);
q = s;
}
}
}
/*最坏的情况是从头遍历到尾,中间元素全部删除;
最好的情况是第一个元素就遍历结束;
而在各种情况下,比较多少次最终是由 maxk 决定,凡是小于 maxk 的元素,都要遍历一次;
查找到位置之后,便开始遍历删除————整个过程没有循环的嵌套,是 x 次循环的简单相加;
所以时间复杂度为 O(n).*/
5.2 实验内容(2)
题目:完成单链表上的如下操作:
a. 逆序建立单链表 ;
b. 遍历单链表 (输出单链表每个元素的值) ;
c. 在单链表第5个元素前插入一个值为 999 的元素.;
d. 删除单链表第 5 个元素。
思考:
任务a头插法即可完成逆序建立单链表;
任务b从头结点开始循环遍历即可;
任务c 和 d 注意指针指向即可。
5.2.1 代码实现
- a. 头插法逆序建立:
void CreatLink2(node& L) {
int length, x;
printf("Please input the length of this List: ");
scanf("%d", &length);
node NewNode;
printf("Please input its content: \n");
for (int i = 0; i < length; ++i) {
NewNode = (node)malloc(sizeof(Link));
scanf("%d", &x);
NewNode->data = x;
// 以下两行是关键语句
NewNode->next = L->next;
L->next = NewNode;
}
}
//任务b,c,d 在“七、实验代码”部分
六、运行示例
-
区间删除操作示例:
-
实验内容(2)关于单链表操作较为简单,这里不再给出图示。
七、实验代码
- 实验内容(1):
//FileName: code2.1.cpp
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
int data;
struct Node* next;
}*node,Link;
void InitLink(node& L)
{
L = (node)malloc(sizeof(Link));
L ->next=NULL;
L->data = -1;
}
void CreatLink(node& L)
{
int length, x;
printf("Please input the length of this List: ");
scanf("%d", &length);
node NewNode;
node p = (node)malloc(sizeof(Link));
p = L;
printf("Please input its content: \n");
for (int i = 0; i < length; ++i)
{
NewNode = (node)malloc(sizeof(Link));
scanf("%d", &x);
NewNode->data = x;
NewNode->next = NULL;
p->next = NewNode;
p = NewNode;
}
}
void Delete(node& L, int mink, int maxk) {
if (mink > maxk) { printf("Error!"); return; }
node p = L->next,pre,q,s;
if (p == NULL)return;
q = pre = (node)malloc(sizeof(Link));
while (p->data <= mink)
{
pre = p;
p = p->next;
}
if (p)
{
while (p && p->data < maxk)
{
p = p->next;
}
q = pre->next;
pre->next = p;
while (q != p)
{
s = q->next;
free(q);
q = s;
}
}
}
void DisplayLink(node L)
{
while (L->next != NULL)
{
printf("%d ", L->next->data);
L = L->next;
}
}
int main()
{
node L;
InitLink(L);
CreatLink(L);
int mink,maxk;
printf("Please input the range you want DELETE: ");
scanf("%d %d", &mink, &maxk);
Delete(L, mink, maxk);
DisplayLink(L);
}
- 实验内容(2):
//FileName: code2.2.cpp
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
int data;
struct Node* next;
}*node, Link;
void InitLink(node& L)
{
L = (node)malloc(sizeof(Link));
L->next = NULL;
L->data = -1;
}
void CreatLink2(node& L)
{
int length, x;
printf("Please input the length of this List: ");
scanf("%d", &length);
node NewNode;
printf("Please input its content: \n");
for (int i = 0; i < length; ++i)
{
NewNode = (node)malloc(sizeof(Link));
scanf("%d", &x);
NewNode->data = x;
NewNode->next = L->next;
L->next = NewNode;
}
}
void DisplayLink(node L)
{
while (L->next != NULL)
{
printf("%d ", L->next->data);
L = L->next;
}
}
int main()
{
node L;
InitLink(L);
CreatLink2(L);
printf("This List has: ");
DisplayLink(L);
printf("\n");
printf("We will input 999 in the fifth room.....");
int cnt = 0; node NewNode,p = L;
NewNode = (node)malloc(sizeof(Link));
NewNode->data = 999;
while (p != NULL)
{
p = p->next;
cnt++;
if (cnt == 4)break;
}
if (p == NULL) { printf("List's length is NOT enough! !"); return 0; }
NewNode->next = p->next;
p->next = NewNode;
printf("Now, this List has: \n");
DisplayLink(L);
printf("\nDelete the fifth data, then List has: ");
node q = L->next, s = L; cnt = 0;
while (q != NULL)
{
s = q;
q = q->next;
cnt++;
if (cnt == 4)break;
}
s->next = q->next;
free(q); q = NULL;
DisplayLink(L);
}
八、算法测试结果
输入线性表:1、5、9、12、54、66 —–> 输入 mink=5, 输入 maxk=18 —–> 删除后:1、5、54、66
示例:
输入线性表:1、3、5、7、9、11、13、15
—–> 逆置:15、13、11、9、7、5、3、1
——> 第五个位置插入999: 15、13、11、9、999、7、5、3、1
——> 删除第五个位置元素: 15、13、11、9、7、5、3、1
示例:
九、分析与总结
9.1 算法复杂度分析及优、缺点分析
实验内容(1):最坏的情况是从头遍历到尾,中间元素全部删除;最好的情况是第一个元素就遍历结束;而在各种情况下,比较多少次最终是由 maxk决定,凡是小于 maxk 的元素,都要遍历一次;查找到位置之后,便开始遍历删除———— 整个过程没有循环的嵌套,x次循环的简单相加,所以时间复杂度为 O(n)。采用链式存储,删除链接操作效率高,但是存储密度低,空间利用率低。
实验内容(2):每有一个结点就要操作一次,时间复杂度O(n)。同样采用链式存储,删除链接操作效率高,但是存储密度低,空间利用率低。
9.2 实验总结
<1> 系统性地练习了单链表的建立插入删除操作,在一些特定问题 (如删除一个区间内的元素) 上予以探讨,学会利用辅助指针解决问题;
<2> 初步理解链表思想,理解结构体、指针在链表中的作用,体会到链表在插入、删除操作上的快速便捷;
<3> 引发了初步的思考,每个节点可以增添一个指向前驱节点的指针,方便解决问题。
ps: 溜了溜了~~~

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐
所有评论(0)