【数据结构实验】链表的创建与功能的实现
一、事先在文件下创建两个txt。
例如在D盘下创建LA.txt和LB.txt,里面写上两个链表所需要的数据。
内容:
二、使用Visual Studio 2022写代码
1.创建一个结构体类型,包含链表所需要的一些类型
typedef struct LNode
{int data;struct LNode* next;
}LNode,*LinkList; //单链表结点类型
2.初始化单链表
void InitList(LNode* &L) //初始化单链表
{L = (LNode*)malloc(sizeof(LNode));L->next = NULL;
}
3.写一个函数用于将d盘下创建好的LA.txt和LB.txt数据以数组的形式导入作为函数返回值
void Input(int v[]) //从已经在目录下创建好的链表数据txt文本里导入数据至数组里返回。
{char filename[100];printf("请输入链表数据文件位置:");scanf("%s", filename);FILE* fp = fopen(filename, "r");int a[6] = { 0 };int i = 0;while (!feof(fp)){fscanf(fp, "%d ", &a[i]);i++;}for (i = 0; i < 6; i++){v[i] = a[i];}fclose(fp); //读完就退出循环
}
4.创建链表,即向初始化好的链表里填入数据
void CreateList(LNode* &L, int a[], int n) //创建List,(链表的数据从传入的列表a中输入。)
{LNode* s, * r; //指向新结点的指针s,始终指向尾结点的指针rL = (LNode*)malloc(sizeof(LNode));r = L;for (int i = 0; i < n; i++) {s = (LNode*)malloc(sizeof(LNode));//为存储数据域的结点s分配内存s->data = a[i];r->next = s;r = s;}r->next = NULL;
}
5.判断是否为空链表功能
bool ListEmpty(LNode* L) //判断是否为空链表。
{if (L->next == NULL){return true;}return false;}
6.将链表设置为空链表功能
void ClearList(LNode* &L)//将L设置为空链表。
{LinkList p = L->next;while (p != NULL){p->data = NULL;p = p->next;}
}
7.返回链表元素个数功能
int ListLength(LNode* L) //计算单链表的元素个数,存在n中返回。
{int n = 0;LNode* p = L; //设置一个指针,初始时指向头结点while (p->next != NULL) {n++;p = p->next;}return n;
}
8.返回链表中第i个元素功能,是“第i个”,也就是索引值为i-1的元素,之后的第i个也是这个意思
bool GetElem(LNode* L, int i, int& e) //求第i个元素的值,赋值给e返回。
{int j = 0;LNode* p = L->next;if (i <= 0|| i > (ListLength(L))) return false; //无效传入值iwhile (j < i-1 && p != NULL) { //移动指针pp = p->next;j++;}if (p == NULL) return false; //若i超出链表长度else {e = p->data; //数据域赋值给e,e是传入的提前定义了的int变量return true;}
}
9.插入元素至链表第i个元素位置
bool ListInsert(LinkList &L, int i, int e) //插入新的元素在链表中第i个元素的位置。
{LinkList p = L,s;int j = 0;if (!p || i<1 || i>(ListLength(L)))//i小于1或大于表长。return false;while (p && j < i-1)//寻找第i-2个节点,并且p指向第i-1个节点。{p = p->next;++j;}s = (LinkList)malloc(sizeof(LNode));//创建一个新指针s指向新元素e。s->data = e;s->next = p->next;//插入新元素至链表中。p->next = s;return true;
}
10.删除链表第i个元素,并返回删除的元素值
bool ListDelete(LinkList& L, int i, int& e) //删除链表中第i个元素,并用e返回其值。
{LinkList p = L, q;int j = 0;while (p->next && j < i-1)//找到第i个节点的直接前驱,令p指向它。{p=p->next;++j;}if (!(p->next) || i<1 || i>(ListLength(L)))//删除位置不合理return false;q = (LinkList)malloc(sizeof(LNode));//创建一个新指针q用于指向第i+1个节点。q = p->next;p->next = q->next;e = q->data;free(q);//释放第i个节点的存储空间。return true;}
11.输出链表功能
void OutputList(LNode* L) //输出链表。
{int element;int count=0; //用于计算链表里有多少个元素。LNode* p = L->next;if (p == NULL)printf("链表不存在。\n");else{while (p != NULL){element = p->data;printf("%d ", element);p = p->next;count++;}printf("\n");printf("链表中此时一共有%d个元素。\n", count);}
}
12.合并两个链表功能(元素按升序排列)
void UnionList(LinkList &LA, LinkList &LB, LinkList &LC) //合并单链表LA和LB得到新的单链表LC,LC元素按非减排列。
{LinkList pa=LA->next, pb=LB->next, pc;LC = pc = LA;//先用LA的头节点作为LC的头节点。while (pa && pb){if (pa->data <= pb->data){pc->next = pa;pc = pa;//pc指向LA中的节点。pa = pa->next;}else{pc->next = pb;pc = pb;pb = pb->next;}pc->next = pa ? pa : pb;//当pa或pb读完后插入另一个的剩余段。}
}
13.销毁单链表功能
void DestroyList(LNode* &L)//销毁单链表
{LNode* pre, * p;pre = L;p = L->next;while (p != NULL) {free(pre);pre = p; p = p->next;}free(pre);
}
三、完整代码(包含main函数)
#include<stdio.h>
#include<stdlib.h>
#pragma warning(disable : 4996) //防止报fopen,fscanf,fprintf 是 unsafe的报错。typedef struct LNode
{int data;struct LNode* next;
}LNode,*LinkList; //单链表结点类型void InitList(LNode* &L) //初始化单链表
{L = (LNode*)malloc(sizeof(LNode));L->next = NULL;
}void Input(int v[]) //从已经在目录下创建好的链表数据txt文本里导入数据至数组里返回。
{char filename[100];printf("请输入链表数据文件位置:");scanf("%s", filename);FILE* fp = fopen(filename, "r");int a[6] = { 0 };int i = 0;while (!feof(fp)){fscanf(fp, "%d ", &a[i]);i++;}for (i = 0; i < 6; i++){v[i] = a[i];}fclose(fp); //读完就退出循环
}void CreateList(LNode* &L, int a[], int n) //创建List,(链表的数据从传入的列表a中输入。)
{LNode* s, * r; //指向新结点的指针s,始终指向尾结点的指针rL = (LNode*)malloc(sizeof(LNode));r = L;for (int i = 0; i < n; i++) {s = (LNode*)malloc(sizeof(LNode));//为存储数据域的结点s分配内存s->data = a[i];r->next = s;r = s;}r->next = NULL;
}void DestroyList(LNode* &L)//销毁单链表
{LNode* pre, * p;pre = L;p = L->next;while (p != NULL) {free(pre);pre = p; p = p->next;}free(pre);
}void ClearList(LNode* &L)//将L设置为空链表。
{LinkList p = L->next;while (p != NULL){p->data = NULL;p = p->next;}
}bool ListEmpty(LNode* L) //判断是否为空链表。
{if (L->next == NULL){return true;}return false;}int ListLength(LNode* L) //计算单链表的元素个数,存在n中返回。
{int n = 0;LNode* p = L; //设置一个指针,初始时指向头结点while (p->next != NULL) {n++;p = p->next;}return n;
}bool GetElem(LNode* L, int i, int& e) //求第i个元素的值,赋值给e返回。
{int j = 0;LNode* p = L->next;if (i <= 0|| i > (ListLength(L))) return false; //无效传入值iwhile (j < i-1 && p != NULL) { //移动指针pp = p->next;j++;}if (p == NULL) return false; //若i超出链表长度else {e = p->data; //数据域赋值给e,e是传入的提前定义了的int变量return true;}
}bool ListInsert(LinkList &L, int i, int e) //插入新的元素在链表中第i个元素的位置。
{LinkList p = L,s;int j = 0;if (!p || i<1 || i>(ListLength(L)))//i小于1或大于表长。return false;while (p && j < i-1)//寻找第i-2个节点,并且p指向第i-1个节点。{p = p->next;++j;}s = (LinkList)malloc(sizeof(LNode));//创建一个新指针s指向新元素e。s->data = e;s->next = p->next;//插入新元素至链表中。p->next = s;return true;
}bool ListDelete(LinkList& L, int i, int& e) //删除链表中第i个元素,并用e返回其值。
{LinkList p = L, q;int j = 0;while (p->next && j < i-1)//找到第i个节点的直接前驱,令p指向它。{p=p->next;++j;}if (!(p->next) || i<1 || i>(ListLength(L)))//删除位置不合理return false;q = (LinkList)malloc(sizeof(LNode));//创建一个新指针q用于指向第i+1个节点。q = p->next;p->next = q->next;e = q->data;free(q);//释放第i个节点的存储空间。return true;}void OutputList(LNode* L) //输出链表。
{int element;int count=0; //用于计算链表里有多少个元素。LNode* p = L->next;if (p == NULL)printf("链表不存在。\n");else{while (p != NULL){element = p->data;printf("%d ", element);p = p->next;count++;}printf("\n");printf("链表中此时一共有%d个元素。\n", count);}
}void UnionList(LinkList &LA, LinkList &LB, LinkList &LC) //合并单链表LA和LB得到新的单链表LC,LC元素按非减排列。
{LinkList pa=LA->next, pb=LB->next, pc;LC = pc = LA;//先用LA的头节点作为LC的头节点。while (pa && pb){if (pa->data <= pb->data){pc->next = pa;pc = pa;//pc指向LA中的节点。pa = pa->next;}else{pc->next = pb;pc = pb;pb = pb->next;}pc->next = pa ? pa : pb;//当pa或pb读完后插入另一个的剩余段。}
}int main()
{int La[6] = { 0 };//创建两个数组用于存储LA和LB的元素。int Lb[6] = { 0 };int e=0;LinkList LA,LB,LC;Input(La); //将文件中已经写好的链表元素导入La和Lb的数组中。Input(Lb);InitList(LA); //初始化链表。InitList(LB);InitList(LC);CreateList(LA, La, 4);//从La和Lb数组中取元素创建两个具体的链表LA和LB。CreateList(LB, Lb, 6);if (ListEmpty(LA)) //测试判非空函数是否正常运行printf("The List is empty!\n");elseprintf("The List is not empty!\n");if (ListInsert(LA, 2, e)) //测试插入元素的函数是否正常运行{printf("新元素插入链表成功!\n");OutputList(LA);} elseprintf("新元素插入链表失败!\n失败原因可能是输入的i值不合法或链表L没有创建!");if (ListDelete(LA, 2, e)) //测试删除元素的函数是否正常运行printf("删除成功!删除的元素的值为:%d\n",e);elseprintf("删除失败!\n失败原因可能是输入的i值不合法或链表L没有创建!");if (GetElem(LA, 2, e))printf("取到的元素为%d\n", e);elseprintf("输入的i值不合法或链表不存在!");OutputList(LA); //测试输出链表的函数是否正常运行。OutputList(LB);UnionList(LA, LB, LC); //测试将两个链表合并的函数是否正常运行OutputList(LC); ClearList(LA); //测试清空链表的函数是否正常运行OutputList(LA);return 0;
}
四、总结
单链表实现的难点在于弄清楚指针和传值的关系,其次是定义的结构类型的区分。
【数据结构实验】链表的创建与功能的实现相关推荐
- 数据结构单链表的创建以及简单操作
在数据结构中: 目录 一.数据节点类型结构体封装 二.创建单链表 1.创建链表 2.头部插入 3.遍历链表 4.尾部插入 5.释放链表 链表可以解决顺序表无法开辟连续空间的问题,大大提高了内存的利用率 ...
- 数据结构--双链表的创建和操作
http://www.cnblogs.com/jingliming/p/4602144.html#0-tsina-1-42616-397232819ff9a47a7b7e80a40613cfe1 一. ...
- SDUT_2118 数据结构实验之链表三:链表的逆置
点击打开链接 数据结构实验之链表三:链表的逆置 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem De ...
- c语言单链表功能,[数据结构]单链表(C语言)的各种功能
06-03阅读200,000 + 链表是一种常见的基本数据结构,在此充分利用了结构指针. 链表可以动态存储和分配,即链表是一个功能非常强大的数组. 他可以在节点中定义多种数据类型,并可以根据需要随意添 ...
- 数据结构实验之链表五:单链表的拆分-sdut
数据结构实验之链表五:单链表的拆分 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Problem Description 输入N个 ...
- SDUT_2122 数据结构实验之链表七:单链表中重复元素的删除
提交代码 数据结构实验之链表七:单链表中重复元素的删除 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Proble ...
- SDUT—2054数据结构实验之链表九:双向链表 (基本建立)
点击打开链接 数据结构实验之链表九:双向链表 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem Des ...
- SDUT_2121数据结构实验之链表六:有序链表的建立 (对建立的单项链表结构进行排序)
点击打开链接 数据结构实验之链表六:有序链表的建立 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem ...
- SDUT_2119 数据结构实验之链表四:有序链表的归并
点击打开链接 数据结构实验之链表四:有序链表的归并 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem ...
最新文章
- [杂谈]杂谈章2 eclipse没有(添加)“Dynamic Web Project”
- activity重启问题
- SBO用户清理(最近一直未登录过用户)
- python云盘服务_Python无所不能?五分钟教会你用python打造个人云盘!
- VTK:Math之NormalizeVector
- 如何计算MP3总时长的问题(三)--对于变比特率MP3求总时长
- C++ 传递字符串数组给函数参数
- 微服务升级_SpringCloud Alibaba工作笔记0009---阿里云部署微服务_在内网不同机器上_报错_注册中心找不到对应的机器_遇到java.net.UnknownHostExceptio
- 有什么手机python编辑器_好用的Python编辑器有哪些?
- 计算机类中外合作办学情况,郑州大学2021年河南省本科一批各专业录取分数统计...
- GCC、VS对C++标准的支持情况总结(转载)
- 实验、配置Eigrp 验证,汇总
- 用74l138实现一个一位全减器_用react实现一个仿ionic button组件
- 投入产出表直接消耗系数和完全消耗系数Stata版本(1990-2017年)
- EDA技术与市场分析
- HTML5实习手机端浏览器拍照和本地上传
- JS基础(乾坤未定,你我皆是黑马4-2)
- 【华为上机真题】分子弹
- LoRa模块无线通信技术在距离测量和定位上的应用——东胜物联
- 视频分析(三):背景减法
热门文章
- 【ubuntu20.04设置中文输入法】
- php给网页加水印_两种php给图片加水印的实现代码
- obs windows 编译 obs browser
- 用Java基础来编写一个彩票中奖代码
- 物联网在中国的崛起,具有什么样的价值?
- 中国电子设计自动化(EDA)软件行业未来发展趋势与投资前景分析报告22022-2028年版
- 用 python 来操作 docx, xlsx 格式文件(二)(使用 docx 库操作 docx 格式文件
- Roxe:下一代全球支付网络
- Elasticsearch学习--索引快速检索
- java按键程序_一个使用JAVA编写的类似按键精灵的程序,支持脚本文件编写(含源代码)...