C++链表的插入删除及查找
- 格式:docx
- 大小:18.40 KB
- 文档页数:6
c语言中linklist类型LinkList类型是C语言中常用的数据结构之一,它是一种线性链表的实现方式。
在计算机科学中,链表是一种常见的数据结构,用于存储和操作一系列元素。
链表由一系列节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。
链表中的第一个节点称为头节点,最后一个节点称为尾节点。
链表可以根据需要动态地增加或删除节点,相比于数组,链表的大小可以根据实际需求进行调整。
链表的实现可以使用不同的方式,其中最常见的是单向链表。
在单向链表中,每个节点只有一个指针,指向下一个节点。
这种实现方式简单且高效,适用于大多数场景。
除了单向链表,还有双向链表和循环链表等其他实现方式。
链表的优点是可以快速在任意位置插入或删除节点,而无需移动其他节点。
这是由于链表中的节点通过指针相互连接,而不是像数组那样连续存储。
另外,链表的大小可以根据需要进行动态调整,而数组的大小是静态的。
这使得链表在处理动态数据集合时非常有用。
然而,链表也有一些缺点。
首先,访问链表中的任意节点都需要从头节点开始遍历,直到找到目标节点。
这导致了链表的访问时间复杂度为O(n),而数组的访问时间复杂度为O(1)。
其次,链表需要额外的内存空间来存储指针信息,这会占用更多的存储空间。
在C语言中,可以使用结构体来定义链表节点,例如:```typedef struct Node {int data;struct Node *next;} Node;typedef struct LinkedList {Node *head;Node *tail;} LinkedList;```上述代码定义了一个包含数据和指针的节点结构体Node,以及一个包含头节点和尾节点指针的链表结构体LinkedList。
通过这样的定义,可以方便地进行链表的操作,比如插入、删除和遍历等。
链表的插入操作可以分为三步:创建新节点、修改指针、更新链表的头尾指针。
例如,插入一个新节点到链表末尾的代码如下:```void insert(LinkedList *list, int data) {Node *newNode = (Node *)malloc(sizeof(Node));newNode->data = data;newNode->next = NULL;if (list->head == NULL) {list->head = newNode;list->tail = newNode;} else {list->tail->next = newNode;list->tail = newNode;}}```链表的删除操作也类似,可以分为三步:找到目标节点、修改指针、释放内存。
计算机学院实验报告课程名称:数据结构实验名称:单链表学生姓名:***学生学号:***********实验日期:2012一、实验目的1.理解数据结构中带头结点单链表的定义和逻辑图表示方法。
2.掌握单链表中结点结构的C++描述。
3.熟练掌握单链表的插入、删除和查询算法的设计与C++实现。
二、实验内容1.编制一个演示单链表插入、删除、查找等操作的程序。
三、实验步骤1.需求分析本演示程序用C++6.0编写,完成单链表的生成,任意位置的插入、删除,以及确定某一元素在单链表中的位置。
①输入的形式和输入值的范围:插入元素时需要输入插入的位置和元素的值;删除元素时输入删除元素的位置;查找操作时需要输入元素的值。
在所有输入中,元素的值都是整数。
②输出的形式:在所有三种操作中都显示操作是否正确以及操作后单链表的内容。
其中删除操作后显示删除的元素的值,查找操作后显示要查找元素的位置。
③程序所能达到的功能:完成单链表的生成(通过插入操作)、插入、删除、查找操作。
④测试数据:A.插入操作中依次输入11,12,13,14,15,16,生成一个单链表B.查找操作中依次输入12,15,22返回这3个元素在单链表中的位置C.删除操作中依次输入2,5,删除位于2和5的元素2.概要设计1)为了实现上述程序功能,需要定义单链表的抽象数据类型:(1)insert初始化状态:单链表可以不为空集;操作结果:插入一个空的单链表L。
(2)decelt操作结果:删除已有的单链表的某些结点。
(3)display操作结果:将上述输入的元素进行排列显示。
(4)modify操作结果:将上述输入的某些元素进行修改。
(5)save操作结果:对上述所有元素进行保存。
(6)load操作结果:对上述元素进行重新装载。
3.使用说明程序执行后显示======================1.单链表的创建2.单链表的显示3.单链表的长度4.取第i个位置的元素5.修改第i个位置的元素6.插入元素到单链表里7.删除单链表里的元素8.合并两个单链表9.退出系统=======================5.源代码:#include<iostream>using namespace std;#define true 1#define false 0#define ok 1#define error 0#define overflow -2typedef int Status;typedef int ElemType;typedef struct LNode{ ElemType data;struct LNode *next;}LNode,*LinkList;void CreateList(LinkList &L,int n){ LinkList p;L=new LNode;L->next=NULL;LinkList q=L;for(int i=1;i<=n;i++){ p=new LNode;cin>>p->data;p->next=NULL;q->next=p;q=p; }}Status GetElem(LinkList L,int i,ElemType &e){ LinkList p=L->next;int j=1;while(p&&j<i){ p=p->next;++j; }if(!p||j>i) return error;e=p->data;return ok;}Status LinkInsert(LinkList &L,int i,ElemType e) { LinkList p=L;int j=0;while(p&&j<i-1){ p=p->next;++j; }if(!p||j>i-1)return error;LinkList s=new LNode;s->data=e;s->next=p->next;p->next=s;return ok;}Status ListDelete(LinkList &L,int i,ElemType &e){ LinkList p=L;LinkList q;int j=0;while(p->next&&j<i-1){p=p->next;++j; }if(!(p->next)||j>i-1) return error;q=p->next;p->next=q->next;e=q->data;delete(q);return ok;}void MergeList(LinkList &La,LinkList &Lb,LinkList &Lc) {LinkList pa,pc,pb;pa=La->next;pb=Lb->next;Lc=pc=La;while(pa&&pb){ if(pa->data<=pb->data){ pc->next=pa;pc=pa;pa=pa->next; }else{ pc->next=pb;pc=pb;pb=pb->next; }}pc->next=pa?pa:pb;delete(Lb);}void show(LinkList L){ LinkList p;p=L->next;while(p){ cout<<p->data<<"-->";p=p->next; }cout<<endl;}int Length(LinkList L,int i){ i=0;LinkList p=L->next;while(p){ ++i;p=p->next; }return i;}void xiugai(LinkList L){ int i,j=1;ElemType k;ElemType e,m;LinkList p=L->next;cout<<"请输入要修改的元素位置(0<i<length):";cin>>i;GetElem(L,i,e);cout<<"该位置的元素:"<<e<<endl;cout<<"修改后的元素值:";cin>>k;while(p&&j<i){ p=p->next;++j; }m=p->data;p->data=k;cout<<"修改后的单链表显示如下:"<<endl;show(L);}void hebing(){ int a,b;LinkList La,Lb,Lc;cout<<"请输入第一个有序链表的长度:"<<endl;cin>>a;cout<<"请输入第一个有序链表的元素共("<<a<<"个):"<<endl;CreateList(La,a);show(La);cout<<"请输入第二个有序链表的长度:"<<endl;cin>>b;cout<<"请输入第二个有序链表的元素共("<<b<<"个):"<<endl;CreateList(Lb,b);show (Lb);MergeList(La,Lb,Lc);cout<<"合并后的有序链表如下:"<<endl;show(Lc);}void main(){ int select;int x;ElemType y;LinkList list;for(;;){ cout<<" 单链表的基本操作"<<endl;cout<<" 1.单链表的创建"<<endl;cout<<" 2.单链表的显示"<<endl;cout<<" 3.单链表的长度"<<endl;cout<<" 4.取第i个位置的元素"<<endl;cout<<" 5.修改第i个位置的元素"<<endl;cout<<" 6.插入元素到单链表里"<<endl;cout<<" 7.删除单链表里的元素"<<endl;cout<<" 8.合并两个单链表"<<endl;cout<<" 9.退出系统"<<endl;cout<<"请选择:";cin>>select;switch(select){ case 1:cout<<"请输入单链表的长度:"<<endl;cin>>x;cout<<"请输入"<<x<<"个元素"<<endl;CreateList(list,x);break;case 2: cout<<"单链表显示如下:"<<endl;show(list);break;case 3: int s;cout<<"单链表的长度为:"<<Length(list,s)<<endl;break;case 4: cout<<"请选择所要取出元素的位置:";cin>>x;while(x<0||x>Length(list,s)){ cout<<"输入有误,请重新输入"<<endl;cout<<"请选择所要取出元素的位置:";cin>>x; }GetElem(list,x,y);cout<<"该位置的元素为:"<<y<<endl;break;case 5: xiugai(list); break;case 6: cout<<"请选择要插入的位置:"; cin>>x;while(x<0||x>Length(list,s)){ cout<<"输入有误,请重新输入"<<endl;cout<<"请选择所要插入元素的位置:";cin>>x; }cout<<"要插入的元素值:";cin>>y;LinkInsert( list,x,y);cout<<"插入后单链表显示如下:"<<endl;show(list);break;case 7: cout<<"请选择要删除的位置:"; cin>>x;while(x<0||x>Length(list,s)){ cout<<"输入有误,请重新输入"<<endl;cout<<"请选择所要删除元素的位置:";cin>>x; }ListDelete(list,x,y);cout<<"要删除的元素值:"<<y<<endl;cout<<"删除后的单链表显示如下:"<<endl;show(list);break;case 8: hebing();break;case 9: exit(0);break;default : cout<<"输入有误,请重新输入"<<endl;break;}}}6.测试结果四、实验总结(结果分析和体会)单链表的最后一个元素的next为null ,所以,一旦遍历到末尾结点就不能再重新开始;而循环链表的最后一个元素的next为第一个元素地址,可返回头结点进行重新遍历和查找。
数据结构C语言版实验报告一、实验目的本次实验旨在通过使用 C 语言实现常见的数据结构,加深对数据结构基本概念、原理和操作的理解,提高编程能力和解决实际问题的能力。
二、实验环境操作系统:Windows 10编程环境:Visual Studio 2019编程语言:C 语言三、实验内容1、线性表顺序表的实现与操作链表的实现与操作2、栈和队列栈的实现与应用(表达式求值)队列的实现与应用(模拟排队)3、树和二叉树二叉树的遍历(前序、中序、后序)二叉搜索树的实现与操作4、图图的存储结构(邻接矩阵、邻接表)图的遍历(深度优先搜索、广度优先搜索)四、实验步骤及结果1、线性表顺序表的实现与操作定义顺序表的数据结构,包括数组和表的长度。
实现顺序表的初始化、插入、删除、查找等操作。
测试顺序表的各种操作,输出操作结果。
```cinclude <stdioh>include <stdlibh>define MAX_SIZE 100typedef struct {int dataMAX_SIZE;int length;} SeqList;//初始化顺序表void initList(SeqList L) {L>length = 0;}//插入元素到顺序表int insertList(SeqList L, int pos, int element) {if (L>length >= MAX_SIZE || pos < 0 || pos > L>length) {return 0;}for (int i = L>length 1; i >= pos; i) {L>datai + 1 = L>datai;}L>datapos = element;L>length++;return 1;}//删除顺序表中的元素int deleteList(SeqList L, int pos) {if (pos < 0 || pos >= L>length) {return 0;}for (int i = pos; i < L>length 1; i++){L>datai = L>datai + 1;}L>length;return 1;}//查找顺序表中的元素int searchList(SeqList L, int element) {for (int i = 0; i < Llength; i++){if (Ldatai == element) {return i;}}return -1;}int main(){SeqList L;initList(&L);insertList(&L, 0, 10);insertList(&L, 1, 20);insertList(&L, 2, 30);printf("顺序表元素: ");for (int i = 0; i < Llength; i++){printf("%d ", Ldatai);}printf("\n");int pos = searchList(L, 20);if (pos!=-1) {printf("元素 20 在顺序表中的位置: %d\n", pos);} else {printf("顺序表中未找到元素 20\n");}deleteList(&L, 1);printf("删除元素后的顺序表元素: ");for (int i = 0; i < Llength; i++){printf("%d ", Ldatai);}printf("\n");return 0;}```实验结果:成功实现顺序表的初始化、插入、删除、查找等操作,输出结果符合预期。
c链表库函数全文共四篇示例,供读者参考第一篇示例:C语言是一种广泛应用于系统编程的高级语言,而链表(Linked List)是C语言中常用的数据结构之一。
在C语言中,链表并不像数组一样有现成的库函数可以直接调用,需要通过自定义函数来实现链表的操作。
为了方便使用链表,不少开发者封装了链表操作的库函数,提供了一些常用的链表操作接口,以供开发者使用。
本文将介绍一些常见的C链表库函数及其用法。
一、链表的概念及基本操作链表是一种线性表的存储结构,由若干节点(Node)组成,每个节点包含数据域和指针域。
数据域用于存放数据,指针域用于指向下一个节点。
链表的最后一个节点指针域为空(NULL),表示链表的末尾。
常见的链表操作包括创建链表、插入节点、删除节点、遍历链表、查找节点等。
下面我们来看看C语言中常用的链表库函数。
二、常见的C链表库函数1. 创建链表在C语言中,创建链表的函数通常包括初始化链表头节点和链表节点的操作。
```#include <stdio.h>#include <stdlib.h>//定义链表节点typedef struct node {int data;struct node* next;} Node;2. 插入节点插入节点是链表操作中的重要操作,可以在链表的任意位置插入新节点。
常见的插入方式包括头部插入和尾部插入。
```//头部插入节点void insertNodeAtHead(Node* head, int data) {Node* newNode = (Node*)malloc(sizeof(Node));newNode->data = data;newNode->next = head->next;head->next = newNode;}以上是常见的C链表库函数,这些函数可以帮助我们更方便地操作链表。
在实际开发中,可以根据需要自定义更多的链表操作函数,以满足具体的需求。
C常用数据结构与算法1.数据结构1.1 数组- 定义- 常用操作:访问元素、添加元素、删除元素、查找元素 - 应用场景1.2 链表- 定义- 常用操作:插入节点、删除节点、查找节点- 单链表、双链表、循环链表的区别- 应用场景1.3 栈- 定义- 常用操作:入栈、出栈、查看栈顶元素、判断栈是否为空 - 可使用数组或链表实现- 应用场景1.4 队列- 定义- 常用操作:入队、出队、查看队首元素、查看队尾元素、判断队列是否为空- 可使用数组或链表实现- 应用场景1.5 哈希表- 定义- 常用操作:插入键值对、删除键值对、根据键查找值、计算哈希值- 冲突解决方法:开放寻址法、链地质法- 应用场景2.常用算法2.1 排序算法- 冒泡排序- 插入排序- 选择排序- 快速排序- 归并排序- 堆排序2.2 查找算法- 线性查找- 二分查找- 插值查找- 哈希查找- 树查找(二叉搜索树、平衡二叉树、红黑树)2.3 图算法- 广度优先搜索- 深度优先搜索- 最短路径算法(Dijkstra算法、Floyd-Warshall算法) - 最小树算法(Prim算法、Kruskal算法)2.4 动态规划- 背包问题- 最长公共子序列- 最大子数组和3.附件:无4.法律名词及注释:- C: C是一种通用的、面向对象的编程语言,由微软公司开发。
- 数据结构:数据结构是计算机中组织和存储数据的方式。
- 算法:算法是解决问题的一系列步骤或过程。
- 数组:数组是一种线性数据结构,由一系列元素组成,每个元素都有唯一的索引值。
- 链表:链表是一种线性数据结构,由一系列节点组成,每个节点都包含数据和指向下一个节点的指针。
- 栈:栈是一种后进先出(LIFO)的数据结构,只能在栈顶进行操作。
- 队列:队列是一种先进先出(FIFO)的数据结构,只能在队首和队尾进行操作。
- 哈希表:哈希表是一种使用哈希函数将键映射到值的数据结构。
- 排序算法:排序算法是将一组数据按照特定顺序排列的算法。
C语言程序设计实验实验报告7实验名称:链表实现学生信息管理系统实验目的:通过设计链表实现学生信息管理系统,掌握链表的操作方法及其应用。
实验内容:设计一个学生信息结构体,包括学号、姓名、性别、年龄和成绩五个成员变量,并选择链式结构存储这些数据。
实现以下功能:1. 添加学生信息:从键盘输入学号、姓名、性别、年龄和成绩等信息,添加到链表中。
2. 删除学生信息:从链表中删除指定学号的学生信息。
5. 按成绩排序:按学生的成绩从高到低排序,并输出所有学生的信息。
7. 退出程序:退出学生信息管理系统。
实验方法:1. 设计学生信息结构体,定义链表节点结构体,并编写初始化链表和销毁链表的函数。
2. 编写添加学生信息函数,新建链表节点并插入链表末尾。
3. 编写删除学生信息函数,根据学号查找需要删除的节点,先将该节点从链表中删除,再释放节点空间。
4. 编写修改学生信息函数,根据学号查找需要修改的节点,并修改其成员变量。
6. 编写按成绩排序函数,使用冒泡排序法对链表进行排序,并输出所有学生的信息。
7. 编写输出所有学生信息函数,遍历链表并输出每个节点的信息。
8. 完成学生信息管理系统的主函数,实现菜单及相应功能的选择。
实验结果:依次选择菜单中的各个功能,添加、修改、删除、查找、排序和输出学生信息都能实现。
经测试,程序稳定运行,功能正常,符合需求。
本次实验主要让我们掌握了链式结构的概念、链表节点的定义、链表的初始化、插入、查找、删除和销毁链表的操作方法,以及在实际应用中如何使用链表来实现数据管理。
虽然链表操作相对于数组稍微有些繁琐,但其可以灵活处理数据结构的长度变化,具有更高的可扩展性和更好的操作效率,可以更好的适应各种实际需求。
在实验中,还需要注意节点指针的正确使用、各个函数之间的调用关系和输入输出数据格式的合理选择等问题,以保证程序能够正常运行。
同时,还需要保持认真细致的态度,严格按照实验需求和要求来完成每个步骤,以达到更好的实验效果和运行效率。
哈希链表的c语言实现哈希链表的C语言实现哈希链表是一种常用的数据结构,用于存储和操作大量的数据。
它结合了哈希表和链表的特点,具有快速查找和高效插入删除的优势。
本文将介绍如何使用C语言实现哈希链表,并详细讲解其原理和操作。
一、哈希链表的原理哈希链表是通过哈希函数将数据的键映射到一个唯一的索引位置,然后使用链表来解决哈希冲突。
哈希函数可以是简单的取模运算,也可以是复杂的算法,关键在于保证映射的唯一性和均匀性。
二、哈希链表的结构在C语言中,我们可以使用结构体来定义哈希链表的节点和链表本身。
节点包含一个键值对,即存储的数据和对应的键,以及一个指向下一个节点的指针。
链表则包含一个指向第一个节点的指针。
```c// 定义哈希链表节点typedef struct Node {int key;int value;struct Node* next;} Node;// 定义哈希链表typedef struct HashTable {int size;Node** table;} HashT able;```三、哈希链表的操作1. 初始化哈希链表在初始化哈希链表时,需要指定链表的大小,并分配相应大小的内存空间。
同时,需要将每个节点的指针初始化为空。
2. 插入节点插入节点时,首先通过哈希函数计算出节点的索引位置,然后将节点插入到对应索引位置的链表中。
如果该位置已经存在节点,则将新节点插入到链表的头部。
3. 查找节点查找节点时,也需要通过哈希函数计算出节点的索引位置,然后遍历链表,找到对应的节点。
如果找到了节点,则返回节点的值;否则,返回空。
删除节点时,首先通过哈希函数计算出节点的索引位置,然后遍历链表,找到对应的节点并删除。
需要注意的是,删除节点时需要维护链表的连续性。
四、示例代码下面是一个简单的示例代码,演示了如何使用C语言实现哈希链表的初始化、插入、查找和删除操作。
```c#include <stdio.h>#include <stdlib.h>// 初始化哈希链表HashTable* initHashTable(int size) {HashTable* ht = (HashTable*)malloc(sizeof(HashTable));ht->size = size;ht->table = (Node**)malloc(sizeof(Node*) * size);for (int i = 0; i < size; i++) {ht->table[i] = NULL;}return ht;}void insertNode(HashTable* ht, int key, int value) { int index = key % ht->size;Node* newNode = (Node*)malloc(sizeof(Node)); newNode->key = key;newNode->value = value;newNode->next = ht->table[index];ht->table[index] = newNode;}// 查找节点int findNode(HashTable* ht, int key) {int index = key % ht->size;Node* cur = ht->table[index];while (cur) {if (cur->key == key) {return cur->value;}cur = cur->next;}return -1;}void deleteNode(HashTable* ht, int key) { int index = key % ht->size;Node* cur = ht->table[index];Node* pre = NULL;while (cur) {if (cur->key == key) {if (pre) {pre->next = cur->next;} else {ht->table[index] = cur->next; }free(cur);return;}pre = cur;cur = cur->next;}}int main() {HashTable* ht = initHashTable(10);insertNode(ht, 1, 10);insertNode(ht, 2, 20);insertNode(ht, 11, 30);printf("%d\n", findNode(ht, 1));printf("%d\n", findNode(ht, 2));printf("%d\n", findNode(ht, 11));deleteNode(ht, 2);printf("%d\n", findNode(ht, 2));free(ht->table);free(ht);return 0;}```五、总结本文介绍了哈希链表的C语言实现,并详细讲解了其原理和操作。
链表c语言经典例题
链表是计算机科学中的经典数据结构之一,常用于存储和操作动态数据。
以下是一些常见的链表例题,可以帮助理解链表的基本操作和应用。
1. 链表的创建:
- 创建一个空链表。
- 创建一个包含指定节点值的链表。
2. 链表的插入操作:
- 在链表的头部插入一个节点。
- 在链表的尾部插入一个节点。
- 在指定位置插入一个节点。
3. 链表的删除操作:
- 删除链表的头节点。
- 删除链表的尾节点。
- 删除指定数值的节点。
4. 链表的查找操作:
- 查找链表中指定数值的节点。
- 查找链表的中间节点。
5. 链表的逆序操作:
- 反转整个链表。
- 反转链表的前 N 个节点。
- 反转链表的一部分区间内的节点。
6. 链表的合并操作:
- 合并两个有序链表,使其有序。
- 合并 K 个有序链表,使其有序。
7. 链表的环检测:
- 判断链表中是否存在环,若存在,则返回环的起始节点。
8. 链表的拆分操作:
- 将一个链表按照奇偶位置拆分成两个链表。
以上是一些链表的经典例题,通过解答这些例题,可以加深对链表结构和基本操作的理解。
在编写对应的 C 语言代码时,需要注意链表节点的定义、指针的使用以及内存的动态分配和释放等问题。
实验一线性表的基本操作一、实验目的与基本要求1.掌握数据结构中的一些基本概念。
数据、数据项、数据元素、数据类型和数据结构,以及它们之间的关系。
2.了解数据的逻辑结构和数据的存储结构之间的区别与联系;数据的运算与数据的逻辑结构的关系。
3.掌握顺序表和链表的基本操作:插入、删除、查找以及表的合并等运算。
4.掌握运用C语言上机调试线性表的基本方法。
二、实验条件1.硬件:一台微机2.软件:操作系统和C语言系统三、实验方法确定存储结构后,上机调试实现线性表的基本运算。
四、实验内容1.建立顺序表,基本操作包括:初始化,建立一个顺序存储的链表,输出顺序表,判断是否为空,取表中第i个元素,定位函数(返回第一个与x相等的元素位置),插入,删除。
2.建立单链表,基本操作包括:初始化,建立一个链式存储的链表,输出顺序表,判断是否为空,取表中第i个元素,定位函数(返回第一个与x相等的元素位置),插入,删除。
3.假设有两个按数据元素值非递减有序排列的线性表A和B,均以顺序表作为存储结构。
编写算法将A表和B表归并成一个按元素值非递增有序(允许值相同)排列的线性表C。
(可以利用将B中元素插入A中,或新建C表)4.假设有两个按数据元素值非递减有序排列的线性表A和B,均以单链表作为存储结构。
编写算法将A表和B表归并成一个按元素值递减有序(即非递增有序,允许值相同)排列的线性表C。
五、附源程序及算法程序流程图1.源程序(1)源程序(实验要求1和3)#include<stdio.h>#include<malloc.h>#include<stdlib.h>#define LIST_INIT_SIZE 100#define LISTINCREMENT 10typedef struct arr{int * elem;int length;int listsize;}Sqlist;void menu(); //菜单void InitList(Sqlist *p); // 创建线性表void ShowList(Sqlist *p); // 输出顺序线性表void ListDelete(Sqlist *p,int i,int &e); // 在顺序线性表中删除第i个元素,并用e返回其值void ListInsert(Sqlist *p); // 在顺序线性表中第i个元素前插入新元素evoid ListEmpty(Sqlist *p); // 判断L是否为空表void GetList(Sqlist *p,int i,int &e); // 用e返回L中第i个数据元素的值void ListInsert(Sqlist *p,int i,int e);bool compare(int a,int b);void LocateElem(Sqlist *L,int e); // 在顺序线性表L中查找第1个值与e满足compare()d元素的位序void MergeList_L(Sqlist *La,Sqlist *Lb); // 归并void main(){Sqlist La;Sqlist Lb;int n,m,x;menu();scanf("%d",&n);while(n){switch(n){case 0: ; break;case 1:InitList(&La);break;case 2:ListEmpty(&La);break;case 3:printf("请输入插入的位序:\n");scanf("%d",&m);printf("请出入要插入的数:\n");scanf("%d",&x);ListInsert(&La,m,x);break;case 4:printf("请输入删除元素的位序:\n");scanf("%d",&m);ListDelete(&La,m,x);printf("删除的元素为:%d\n",x);break;case 5:printf("请输入要找的与线性表中相等的数:\n");scanf("%d",&m);LocateElem(&La,m);break;case 6:printf("请输入查找的位序:\n");scanf("%d",&m);GetList(&La,m,x);printf("La中第%d个元素的值为%d\n",m,x);break;case 7:ShowList(&La);break;case 8:InitList(&Lb);break;case 9:MergeList_L(&La,&Lb);printf("归并成功!");break;}menu();scanf("%d",&n);}}/*菜单*/void menu(){printf("********************\n\n");printf(" 0.退出\n\n");printf(" 1.创建线性表La\n\n");printf(" 2.判断La是否为空表\n\n");printf(" 3.插入元素(La)\n\n");printf(" 4.删除元素(La)\n\n");printf(" 5.定位元素(La)\n\n");printf(" 6.取元素(La)\n\n");printf(" 7.输出线性表\n\n");printf(" 8.创建线性表Lb\n\n");printf(" 9.归并为一个线性表La\n\n");printf("********************\n\n");}/*创建顺序线性表L*/void InitList(Sqlist *L){int n;int i=0;L->elem=(int *)malloc(LIST_INIT_SIZE*sizeof(int));if(NULL==L->elem)printf("储存分配失败!\n");else{L->length=0;L->listsize=LIST_INIT_SIZE;printf("输入顺序表a:\n");scanf("%d",&n);while(n){L->elem[i]=n;i++;L->length++;L->listsize=L->listsize-4;scanf("%d",&n);}}}/*输出顺序线性表*/void ShowList(Sqlist *p){int i;if(0==p->length)printf("数组为空!\n");elsefor(i=0;i<p->length;i++)printf("%d ",p->elem[i]);printf("\n");}/*判断L是否为空表*/void ListEmpty(Sqlist *p)if(0==p->length)printf("L是空表!\n");elseprintf("L不是空表!\n");}/*在顺序线性表中第i个元素前插入新元素e */void ListInsert(Sqlist *p,int i,int e){int *newbase;int *q1;int *q2;while(i<1||i>p->length+1){printf("您输入的i超出范围!\n请重新输入要插入的位置\n:");scanf("%d",&i);}if(p->length>=p->listsize){newbase=(int *)realloc(p->elem,(p->listsize+LISTINCREMENT)*sizeof(int));if(!newbase)exit(0);else{p->elem=newbase;p->listsize+=LISTINCREMENT;}}q1=&(p->elem[i-1]);for(q2=&(p->elem[p->length-1]);q2>=q1;--q2)*(q2+1)=*q2;*q1=e;++p->length;}/*/在顺序线性表中删除第i个元素,并用e返回其值*/void ListDelete(Sqlist *p,int i,int &e){int *q1,*q2;while(i<1||i>p->length){printf("您输入的i超出范围!请重新输入:");scanf("%d",&i);}q1=&(p->elem[i-1]);e=*q1;q2=p->elem+p->length-1;for(++q1;q1<=q2;++q1)*(q1-1)=*q1;--p->length;}/*对比a与b相等*/bool compare(int a,int b){if(a==b)return 1;elsereturn 0;}/*在顺序线性表L中查找第1个值与e满足compare()d元素的位序*/ void LocateElem(Sqlist *L,int e){int i=1;int *p;p=L->elem;while(i<=L->length && !compare(*p++,e))++i;if(i<=L->length)printf("第1个与e相等的元素的位序为%d\n",i);elseprintf("没有该元素!\n");}/*用e返回L中第i个数据元素的值*/void GetList(Sqlist *p,int i,int &e){Sqlist *p1;p1=p;e=p1->elem[i-1];}/* 已知顺序线性表La和Lb是元素按值非递减排列*//* 把La和Lb归并到La上,La的元素也是按值非递减*/void MergeList_L(Sqlist *La,Sqlist *Lb){int i=0,j=0,k,t;int *newbase;Sqlist *pa,*pb;pa=La;pb=Lb;while(i<pa->length && j<pb->length){if(pa->elem[i] >= pb->elem[j]){if(pa->listsize==0){newbase=(int*)realloc(pa->elem,(pa->listsize+LISTINCREMENT)*sizeof(int));if(!newbase)exit(0);}for(k=pa->length-1; k>=i; k--)pa->elem[k+1]=pa->elem[k];pa->length++;pa->elem[i]=pb->elem[j];i++;j++;}elsei++;}while(j<pb->length){if( pa->listsize < pb->length-j ){newbase=(int*)realloc(pa->elem,(pa->listsize+LISTINCREMENT)*sizeof(int));if(!newbase)exit(0);}for(j;j<pb->length;j++,i++){pa->elem[i]=pb->elem[j];pa->length++;}}for(i=0;i<pa->length/2;i++){t=pa->elem[i];pa->elem[i]=pa->elem[pa->length-i-1];pa->elem[pa->length-i-1]=t;}}(2)源程序(实验要求2和4)#include<stdio.h>#include<malloc.h>#include<stdlib.h>typedef struct LNode{int data;struct LNode *next;}LNode, *LinkList;void menu();LinkList InitList();void ShowList(LinkList L);void ListDelete(LinkList L,int i,int &e);void ListEmpty(LinkList L);void GetList(LinkList L,int i,int &e);void ListInsert(LinkList L,int i,int e);bool compare(int a,int b);void LocateElem(LinkList L,int e);LinkList MergeList_L(LinkList La,LinkList Lb);int total=0;void main(){LinkList La;LinkList Lb;La=(LinkList)malloc(sizeof(struct LNode));La->next=NULL;Lb=(LinkList)malloc(sizeof(struct LNode));Lb->next=NULL;int n;int m;int x;menu();scanf("%d",&n);while(n){switch(n){case 0: ; break;case 1:La->next=InitList();break;case 2:ListEmpty(La);break;case 3:printf("请输入要插入到第几个节点前:\n");scanf("%d",&m);printf("请输入插入的数据:\n");scanf("%d",&x);ListInsert(La,m,x);break;case 4:printf("请输入删除元素的位序:\n");scanf("%d",&m);ListDelete(La,m,x);printf("删除的元素为:%d\n",x);break;case 5:printf("请输入要找的与线性表中相等的数:\n");scanf("%d",&m);LocateElem(La,m);break;case 6:printf("请输入查找的位序:\n");scanf("%d",&m);GetList(La,m,x);printf("La中第%d个元素的值为%d\n",m,x);break;case 7:ShowList(La);break;case 8:Lb->next=InitList();break;case 9:La=MergeList_L(La,Lb);printf("归并成功\n");break;}menu();scanf("%d",&n);}}void menu(){printf("********************\n\n");printf(" 0.退出\n\n");printf(" 1.创建线性表La\n\n");printf(" 2.判断是否为空表\n\n");printf(" 3.插入元素\n\n");printf(" 4.删除元素\n\n");printf(" 5.定位元素\n\n");printf(" 6.取元素\n\n");printf(" 7.输出线性表\n\n");printf(" 8.创建线性表Lb\n\n");printf(" 9.归并两线性表\n\n");printf("********************\n\n");}// 创建链式线性表LLinkList InitList(){int count=0;LinkList pHead=NULL;LinkList pEnd,pNew;pEnd=pNew=(LinkList)malloc(sizeof(struct LNode));printf("请输入数据:\n");scanf("%d",&pNew->data);while(pNew->data){count++;if(count==1){pNew->next=pHead;pEnd=pNew;pHead=pNew;}else{pNew->next=NULL;pEnd->next=pNew;pEnd=pNew;}pNew=(LinkList)malloc(sizeof(struct LNode));printf("请输入数据:\n");scanf("%d",&pNew->data);}free(pNew);total=total+count;return pHead;}// 判断L是否为空表void ListEmpty(LinkList L){if(NULL==L->next)printf("此表为空表!\n");elseprintf("此表不为空表!\n");}// 在链式线性表中第i个元素前插入新元素e void ListInsert(LinkList L,int i,int e){LinkList p;LinkList s;p=L;int j=0;while(p&&j<i-1){p=p->next;++j;}if(!p||j>i-1)printf("不存在您要找的节点!\n");else{s=(LinkList)malloc(sizeof(int));s->data=e;s->next=p->next;p->next=s;printf("插入节点成功!\n");}}// 输出链式线性表void ShowList(LinkList L){LinkList p;p=L->next;if(p==NULL)printf("此表为空表!\n");elsewhile(p){printf("%d ",p->data);p=p->next;}printf("\n");}// 在链式线性表中删除第i个元素,并用e返回其值void ListDelete(LinkList L,int i,int &e){LinkList p;LinkList q;p=L;int j=0;while(p->next && j<i-1){p=p->next;++j;}if(!(p->next)||j>i-1)printf("没有找到要删除的位置!");else{q=p->next;p->next=q->next;e=q->data;free(q);}}// 用e返回L中第i个数据元素的值void GetList(LinkList L,int i,int &e){LinkList p;p=L->next;int j=0;while(p->next && j<i-1){p=p->next;++j;}if(!(p)||j>i-1)printf("没有找到要查找的位置!");elsee=p->data;}// 对比a与b相等bool compare(int a,int b){if(a==b)return 1;elsereturn 0;}// 在链式线性表L中查找第1个值与e满足compare()d元素的位序void LocateElem(LinkList L,int e){int i=0;LinkList p;p=L;while(p->next && !compare(p->data,e)){p=p->next;i++;}if(NULL==p->next){if(0==compare(p->data,e))printf("没有该元素!\n");elseprintf("第1个与e相等的元素的位序为%d\n",i);}elseif(compare(p->data,e))printf("没有该元素!\n");}LinkList MergeList_L(LinkList La,LinkList Lb){int i,j,k;LinkList pa_1,pb_1,pa_2,pb_2,pc,pd;pa_1=La->next;pc=pa_2=La;pb_1=pb_2=Lb->next;if(pa_1->data > pb_1->data){pc=pa_2=Lb;pa_1=Lb->next;pb_1=pb_2=La->next;}while(pa_1 && pb_1){if(pa_1->data >= pb_1->data){pa_2->next=pb_1;pb_2=pb_1->next;pb_1->next=pa_1;pb_1=pb_2;pa_2=pa_2->next;}else{pa_1=pa_1->next;pa_2=pa_2->next;}}if(pb_1)pa_2->next=pb_1;pd=(LinkList)malloc(sizeof(struct LNode));pd->next=NULL;pa_2=pd;k=total;for(i=0;i<total;i++){pa_1=pc->next;for(j=1;j<k;j++)pa_1=pa_1->next;pb_1=(LinkList)malloc(sizeof(struct LNode));pa_2->next=pb_1;pa_2=pa_2->next;pa_2->data=pa_1->data;k--;}pa_2->next=NULL;return pd;}2.流程图(实验要求1和3)图1 主函数流程图图2创建线性表La流程图图3判断La是否为空表流程图图4 插入元素(La)流程图图5删除元素(La)流程图图6定位元素(La)流程图图7取元素(La)流程图图8输出线性表流程图图9输出线性表流程图流程图(实验要求2和4)图10主函数流程图图11创建线性表La流程图图12判断是否为空表流程图图13插入元素流程图图14删除元素流程图图15定位元素流程图图图16取元素流程图图17创建Lb流程图图18归并两表流程图六、运行结果1. (实验要求1和3)点击运行,首先出现的是菜单界面,选择菜单选项进行操作,如图所示。
数据结构单链表实验报告一、实验目的1、深入理解单链表的数据结构及其基本操作。
2、掌握单链表的创建、插入、删除、查找等操作的实现方法。
3、通过实际编程,提高对数据结构和算法的理解和应用能力。
二、实验环境1、操作系统:Windows 102、编程语言:C 语言3、开发工具:Visual Studio 2019三、实验原理单链表是一种常见的数据结构,它由一系列节点组成,每个节点包含数据域和指针域。
指针域用于指向下一个节点,从而形成链表的链式结构。
单链表的基本操作包括:1、创建链表:通过动态分配内存创建链表的头节点,并初始化链表为空。
2、插入节点:可以在链表的头部、尾部或指定位置插入新的节点。
3、删除节点:根据给定的条件删除链表中的节点。
4、查找节点:在链表中查找满足特定条件的节点。
四、实验内容(一)单链表的创建```cinclude <stdioh>include <stdlibh>//定义链表节点结构体typedef struct Node {int data;struct Node next;} Node;//创建单链表Node createList(){Node head =(Node)malloc(sizeof(Node));if (head == NULL) {printf("内存分配失败!\n");return NULL;}head>data = 0;head>next = NULL;return head;}int main(){Node list = createList();//后续操作return 0;}```在创建单链表时,首先为头节点分配内存空间。
若内存分配失败,则提示错误信息并返回`NULL`。
成功分配内存后,初始化头节点的数据域和指针域。
(二)单链表的插入操作插入操作分为三种情况:头部插入、尾部插入和指定位置插入。
1、头部插入```cvoid insertAtHead(Node head, int data) {Node newNode =(Node)malloc(sizeof(Node));if (newNode == NULL) {printf("内存分配失败!\n");return;}newNode>data = data;newNode>next = head>next;head>next = newNode;}```头部插入时,创建新节点,将新节点的数据域赋值,并将其指针域指向原头节点的下一个节点,然后更新头节点的指针域指向新节点。