双链表及链表应用实验
循环双链表实验报告

南京工程学院实验报告课程名称数据结构与算法实验实验项目名称线性表实验学生班级软件工程161 实验学生姓名潘登学号 202161024 实验时间 2017.11.2 实验地点图书馆A406实验成绩评定指导教师签字年月日一、实验目的和要求实验目的:验证教材中线性表链式存储结构的基本操作,设计并实现指定操作的算法,并做算法分析。
实验要求:①使用Java语言,采用泛型类;②争取最佳的算法效率(一次遍历)。
所有算法不能调用size()求元素个数后再操作。
③各类的成员方法,不改变参数list引用的链表,插入结点等操作都是深拷贝。
④声明返回各类对象(如SinglyList<T>)的成员方法,不改变调用者(this),this深拷贝。
⑤讨论各链表浅拷贝与深拷贝的差别,画出示意图。
二、实验题目2-145.void replaceAll(DoublyList<T>pattern,DoublyList<T>list)//替换所有与pattern匹配的子表为list三、实验方法与步骤(需求分析、算法设计思路、流程图等)需求分析:1.在target链表中寻找与pattern链表匹配的子联表2.用list链表替换该子联表3.过程简洁,效率高,一次遍历算法设计思路:先利用循环寻找到与pattern匹配的子联表,若无,则跳过该成员函数,若有,则以list链表为原型的循环双链表list2(构造循环双链表的效率更高),最后将list2整体替换子链(节省删除链表时间),同时list2变为空链表流程图:四、实验原始纪录(源程序、数据结构等)节点类public class DoubleNode<T>{public T data;public DoubleNode<T> prev,next;public DoubleNode(T data,DoubleNode<T> prev,DoubleNode<T> next)//创建节点public DoubleNode()//创建空节点public String toString()//输出节点元素}双链表类public class DoublyList<T> extends DoubleNode<T>{public DoubleNode<T> head;//头结点public DoublyList()//创建空链表public boolean isEmpty()//判断是否为空public int size()//长度 //以递归方式{return size(this.head.next);}private int size(DoubleNode<T> p){if(p!=null)return 1+size(p.next);elsereturn 0;}public DoubleNode<T> insert(int i,T x)//中间插入public DoubleNode<T> insert (T x)//尾插入public String toString()//输出链表}循环双链表类public class CirDoublyList<T> extends DoublyList<T>{public DoubleNode<T> head;public CirDoublyList()//创建空链表public CirDoublyList(DoublyList<T> list)//将list的数据拷贝到一个新的循环双链表{this.head=new DoubleNode<T>();this.head.prev=this.head;this.head.next=this.head;DoubleNode<T> L=list.head.next;while(L!=null){insert(L.data);L=L.next;}}public boolean isEmpty()//判断是否为空public int size()//长度以递归方式private int size(DoubleNode<T> p)public DoubleNode<T> insert(int i,T x)//中间插入public DoubleNode<T> insert(T x)//尾插入public void replaceAll(DoublyList<T> pattern, DoublyList<T> list)//用list 替换pattern{DoubleNode<T> T1=this.head.next;DoubleNode<T> p=T1;DoubleNode<T> q=pattern.head.next;while(p!=this.head&&q!=null&&p.data.equals(q.data))//匹配pattern链表{p=p.next;q=q.next;}if(q==null){CirDoublyList<T> list2=new CirDoublyList<T>(list);//创建list的循环双链表T1.prev.next=list2.head.next;list2.head.next.prev=T1.prev;p.prev=list2.head.prev;list2.head.prev.next=p;}}public String toString()//正序输出public String toPreviousString()//反序输出}主函数类import java.util.Scanner;public class SeqMain{public static void main(String[] args){CirDoublyList<String> target=new CirDoublyList<String>();DoublyList<String> pattern=new DoublyList<String>();DoublyList<String> list=new DoublyList<String>();int i;String ch;System.out.print("请输入target链表:");String str1=new Scanner(System.in).nextLine();for(i=0;i<str1.length();i++){ch=str1.substring(i, i+1);target.insert(ch);}System.out.print("请输入pattern链表:");String str2=new Scanner(System.in).nextLine();for(i=0;i<str2.length();i++){ch=str2.substring(i, i+1);pattern.insert(ch);}System.out.print("请输入list链表:");String str3=new Scanner(System.in).nextLine();for(i=0;i<str3.length();i++){ch=str3.substring(i, i+1);list.insert(ch);}target.replaceAll(pattern, list);System.out.println(target.toString());}}五、实验结果及分析(计算过程与结果、数据曲线、图表等)实验结果展示:六、实验总结与思考本实验是对链表的比较基础的运用(链表的查找,删除,插入)以及熟悉递归算法,算法本身并不难实现,难点在于算法的效率要高,可读性要强,这也是所有代码需要注意的,要做到每个指针都尽到最大的利用。
双向链表的算法设计与实现实验报告

数学与计算科学学院实验报告
实验项目名称双向链表的算法设计与实现
所属课程名称__数据结构A
实验类型设计型
实验日期__
班级信计1402
学号201453100214
姓名俞凯烨
成绩
【实验小结】(收获体会)
附录1:源程序
附录2:实验报告填写说明
1.实验项目名称:要求与实验教学大纲一致。
2.实验目的:目的要明确,要抓住重点,符合实验教学大纲要求。
3.实验原理:简要说明本实验项目所涉及的理论知识。
4.实验环境:实验用的软、硬件环境。
5.实验方案(思路、步骤和方法等):这是实验报告极其重要的内容。
概括整个实验过程。
对于验证性实验,要写明依据何种原理、操作方法进行实验,要写明需要经过哪几个步骤来实现其操作。
对于设计性和综合性实验,在上述内容基础上还应该画出流程图、设计思路和设计方法,再配以相应的文字说明。
对于创新性实验,还应注明其创新点、特色。
6.实验过程(实验中涉及的记录、数据、分析):写明具体实验方案的具体实施步骤,包括实验过程中的记录、数据和相应的分析。
7.实验结论(结果):根据实验过程中得到的结果,做出结论。
8.实验小结:本次实验心得体会、思考和建议。
9.指导教师评语及成绩:指导教师依据学生的实际报告内容,给出本次实验报告的评价。
双向链表报告

数据结构实验报告实验名称:双向链表1.实验要求根据线性表的抽象数据类型定义,选择下面任意种链式结构实现线性表,并完成线性表基本功能。
双向链表1.构造:使用头插法尾插法两种方式。
2.插入:要求建立的链表按照关键字从小到大有序3.删除4.查找5.获取链表长度6.销毁7.编写main()函数测试线性表的正确性。
2. 程序分析2.1 存储结构存储结构:双向链表结构2.2 关键算法分析1.关键算法:(1)构造函数:首先运用冒泡排序法进行排序,操作将输入的数据排序,然后逐一将各个数据存放到各个节点之中。
(2)查找操作:形参为查找位数,从头遍历链表进行逐个节点查找,//p=p->next;最后返回值为所查找的节点的地址。
(3)插入操作:建立新节点,运用后插操作,根据所插入的数据的大小自动找到所需插入的位置,并进行后插操作,将该节点插入到查找数字之后。
(4)删除:查找得到被删除节点的前一个节点将该节点的next指针跳过该节点指向被删除节点的下一个节点2.算法步骤:1.插入操作:s->data=x;s->next=p->next;s->prior=p;p->next=s;p->next->prior=s后插(1)将数据值赋给节点数据域(2)将s节点的next指向p节点的下一个节点(3)s的前驱指针指向p(4)p的next指针指向s(5)p的下一个节点的前驱指针指向s2.删除操作:p=Get(i-1);Node<T>*q=p->next;p->next=q->next;q->next->prior=p;T x=q->data;(1)查找得到所删除节点的前一个节点(2)创建新的节点指向将被删除的节点(3)查找所的节点的next指针指向被删除节点的下一个节点(4)将被删除节点的下一个节点的前驱指针指向查找所得节点3. 程序运行结果1.主函数流程2.(1)插入时:首先自动的判断所需输入数字的位置然后建立新的节点,然后进行后插入操作。
实验2-链表的应用

实验2 链表的应用一、实验目的●了解并掌握链表的概念与定义●能够实现并运用链表●熟练运用链表的基本操作二、实验环境●个人计算机一台,CPU主频1GHz以上,1GB以上内存,2GB以上硬盘剩余空间。
●Windows2000、Windows XP或Win 7操作系统●Code::Blocks(版本12.11或近似版本,英文版),或VC++ 6.0三、实验内容1 基本部分(必做)1.单向链表的创建与操作设单向链表中节点的数据域的数据类型为整型,编写函数实现以下操作:(1)实现单向链表的创建(包括初始化)与输出操作,节点的个数及节点的数据由用户输入。
(源代码:ds3-1.c)(2)查找给定的单链表中的第i个节点,并将其地址返回。
若不存在第i 个节点,则返回空地址。
(源代码:ds3-2.c)(3)查找给定的单链表中值为n的节点,并将其地址返回。
若不存在值为n的节点,则返回空地址。
同时,还应通过参数传回该节点的序号。
(源代码:ds3-3.c)(4)删除给定的单链表中的第i个节点,成功返回1,失败返回0。
(源代码:ds3-4.c)(5)删除给定的单链表中值为n的节点,成功返回1,失败返回0。
(源代码:ds3-5.c)(6)在给定的单链表的第i位上插入值为n的节点。
(源代码:ds3-6.c)(7)在给定单链表的值为m的节点的前面插入一个值为n的节点。
(源代码:ds3-7.c)2.双向循环链表的创建与操作设双向链表中节点的数据域的数据类型为整型,编写函数实现以下操作:(1)实现双向循环链表的创建(包括初始化)与输出操作,节点的个数及节点的数据可以在程序中直接确定。
(源代码:ds4-1.c)(2)删除给定的双向循环链表中值为n的节点,成功返回1,失败返回0。
(源代码:ds4-2.c)(3)在给定的双向循环链表中的第i位上插入值为n的节点,成功返回1,失败返回0。
(源代码:ds4-3.c)2 提高部分(选做)已知链表A和B中节点的值都按照从小到大的顺序排序,且任何两个节点的值都不相同。
双向链表排序实验报告

双向链表排序实验报告陈祎智实验报告<2> 1. 问题描述: 双向链表的排序。
要求:输入一个双向链表,显示些双向链表并对此双向链表排序2.课题分析(结构图):3.数据结构的设计: typedef struct node { int info;struct node *llink,*rlink;}NODE; 双向链表的排序双向链表存储结构快速排序定义输入数据结点4.流程图5.源程序:#include<iostream.h> #include<stdlib.h> #include <stdio.h> 开始创建链表初始化链表从中间分成两部排序链表插入 10 个值输出排序链表终止typedef struct Link/*双向链表结构体*/ {int data;struct Link *lift;struct Link *right; }linkx,*linky; linky Init();/*建立双向链表*/ void PrLink(linky p);/*输出双向链表*/ linky Sort(linky head);/*对双向链表排序*/ linky S head,linky one,linky two);/*任意交换双向链表两个结点的地址*/ void main(void) {linky head;head=Init();head=Sort(head);PrLink(head); } linky (Init())/*建立链表*/ {linky p,q,head;int n=0;head=p=q=(linky)malloc(sizeof(linkx));printf(“排序前的链表: “);scanf(“%d“,&p->data);/*输入数据*/head->lift=NULL;n++;while(n!=10)/*一直输入到规定的数字个数停止*/ {q=p;p=(linky)malloc(sizeof(linkx));scanf(“%d“,&p->data);/*输入数据*/q->right=p;p->lift=q;n++; }p->right=NULL;return(head); } linky S head,linky one,linky two)/*任意交换两个结点*/ {linky temp;if(one->lift==NULL&&two->right==NULL)/*首和尾巴的交换*/{if(one->right==two)/*只有两个结点的情况下*/{two->right=one;two->lift=NULL;one->lift=two;one->right=NULL;head=two;}else/*有间隔的首尾交换*/{one->right->lift=two;two->lift->right=one;two->right=one->right;one->lift=two->lift;two->lift=one->right=NULL;head=two;/*尾结点成为头结点*/}}else if(two->right==NULL)/*尾和任意一个交换*/ {if(one->right==two)/*交换最后两个结点*/{one->lift->right=two;two->lift=one->lift;two->right=one;one->lift=two;one->right=NULL;}else/*和前面其他结点交换*/{temp=two->lift;temp->right=one;one->lift->right=two;one->right->lift=two;two->lift=one->lift;two->right=one->right;one->lift=temp;one->right=NULL;}}else if(one->lift==NULL)/*头和任意一个交换*/ {if(one->right==two)/*交换头两个结点*/{two->right->lift=one;one->right=two->right;one->lift=two;two->right=one;two->lift=NULL;head=two;}else/*头结点和后面其他结点交换*/{temp=one->right;temp->lift=two;one->lift=two->lift;one->right=two->right;two->lift->right=one;two->right->lift=one;two->right=temp;two->lift=NULL;head=two;/*交换的结点成为头结点*/}}else/*当中的任意两个交换*/{if(one->right==two)/*交换连在一起的两个结点*/ {temp=one->lift;one->lift->right=two;one->right->lift=two;one->lift=two;one->right=two->right;two->right->lift=one;two->right=one;two->lift=temp;else/*交换隔开的两个结点*/{one->lift->right=two;one->right->lift=two;one->lift=two->lift;temp=one->right;one->right=two->right;two->lift->right=one;two->right->lift=one;two->right=temp;two->lift=one->lift;}}return(head); } linky Sort(linky head)/*对链表排序*/ {linky i,j,t,p;int max;p=head;for(i=p;i->right!=NULL;i=i->right)/*用选择法的思想对这些结点排序*/max=i->data;for(j=i->right;j!=NULL;j=j->right)if(j->data<max){max=j->data;t=j;}if(max!=i->data)/*假如没有找到比 i 小的结点*/{head=S);/*因为最终返回的是头结点,而头结点又有可能变化,所以每次头结点返回*/i=t;}}return(head); } void PrLink(linky p)/*输出链表*/ { linky q;printf(“排序后: “);do{q=p;printf(“%d “,p->data);p=p->right;free(q);/*释放输出结点*/}while(p!=NULL);}6.调试记录:第一次输入 136 134 158 123 197 124 156 170 103 101 实现排序第二次调试输入 12367 15842 12564 13729 49875 1546 15423 15794 54612 15437.软件说明程序调试运行成功后,排序前随机输入十个不同的数值,快速排序后将由小到大输出这十个数值的排序。
数据结构第二章实验报告

数据结构第二章实验报告一、实验目的数据结构第二章主要涉及线性表的相关知识,本次实验的目的在于通过实际操作和编程实现,深入理解线性表的概念、存储结构以及基本操作,巩固所学的理论知识,并提高编程能力和问题解决能力。
二、实验环境本次实验使用的编程语言为C++,编程环境为Visual Studio 2019。
三、实验内容(一)顺序表的实现顺序表是一种用顺序存储方式实现的线性表。
在实验中,我们定义了一个结构体来表示顺序表,包括存储数据的数组和表示表长度的变量。
实现了顺序表的初始化、插入、删除、查找等基本操作。
(二)链表的实现链表是一种通过指针链接实现的线性表。
我们分别实现了单向链表和双向链表。
在单向链表中,每个节点包含数据和指向下一个节点的指针;双向链表则在此基础上增加了指向前一个节点的指针,使得链表的操作更加灵活。
(三)线性表的应用运用实现的线性表解决了一些实际问题,如数据排序、查找特定元素等。
四、实验步骤(一)顺序表的实现步骤1、定义顺序表结构体,包括数据数组和长度变量。
2、实现顺序表的初始化函数,将长度初始化为 0。
3、插入操作:首先判断表是否已满,如果未满,在指定位置插入元素,并将后续元素后移。
4、删除操作:首先判断指定位置是否合法,然后将该位置元素删除,并将后续元素前移。
5、查找操作:遍历表中的元素,找到目标元素返回其位置,否则返回-1。
(二)链表的实现步骤1、单向链表定义单向链表节点结构体,包含数据和指向下一个节点的指针。
实现链表的初始化函数,创建头节点。
插入操作:分为头插法和尾插法,根据插入位置的不同选择相应的方法。
删除操作:找到要删除的节点,将其前后节点连接起来,释放删除节点的内存。
查找操作:遍历链表,找到目标元素返回节点指针,否则返回NULL。
2、双向链表定义双向链表节点结构体,包含数据、指向前一个节点和指向下一个节点的指针。
初始化函数与单向链表类似,但需要同时处理前后指针。
插入和删除操作:在单向链表的基础上,同时更新前后节点的指针。
数据结构实验二链表
数据结构实验二1、实验目的∙熟练掌握线性表的链式存储结构定义及基本操作∙理解循环链表和双链表的特点和基本运算2、实验内容:建立单链表,完成链表(带表头结点)的基本操作:建立链表、插入、删除、查找、输出、求前驱、求后继、两个有序链表的合并操作。
其他基本操作还有销毁链表、将链表置为空表、求链表的长度、获取某位置结点的内容、搜索结点。
1.问题描述:利用线性表的链式存储结构,设计一组输入数据(假定为一组整数),能够对单链表进行如下操作:∙初始化一个带表头结点的空链表;∙创建一个单链表是从无到有地建立起一个链表,即一个一个地输入各结点数据,并建立起前后相互链接的关系。
又分为逆位序(插在表头)输入n 个元素的值和正位序(插在表尾)输入n 个元素的值;∙插入结点可以根据给定位置进行插入(位置插入),也可以根据结点的值插入到已知的链表中(值插入),且保持结点的数据按原来的递增次序排列,形成有序链表。
∙删除结点可以根据给定位置进行删除(位置删除),也可以把链表中查找结点的值为搜索对象的结点全部删除(值删除);∙输出单链表的内容是将链表中各结点的数据依次显示,直到链表尾结点;∙求前驱结点是根据给定结点的值,在单链表中搜索其当前结点的后继结点值为给定的值,将当前结点返回;∙求后继结点是根据给定结点的值,在单链表中搜索其当前结点的值为给定的值,将后继结点返回;∙两个有序链表的合并是分别将两个单链表的结点依次插入到第3 个单链表中,继续保持结点有序;编写主程序,实现对各不同的算法调用。
其它的操作算法描述略。
2.实现要求:对链表的各项操作一定要编写成为C(C++)语言函数,组合成模块化的形式,还要针对每个算法的实现从时间复杂度和空间复杂度上进行评价。
∙“初始化算法”的操作结果:构造一个空的线性表L,产生头结点,并使L 指向此头结点;∙“建立链表算法”初始条件:空链存在;操作结果:选择逆位序或正位序的方法,建立一个单链表,并且返回完成的结果;∙“链表(位置)插入算法”初始条件:已知单链表L 存在;操作结果:在带头结点的单链线性表L 中第i 个位置之前插入元素e;∙“链表(位置)删除算法”初始条件:已知单链表L 存在;操作结果:在带头结点的单链线性表L 中,删除第i 个元素,并由e 返回其值;∙“输出算法”初始条件:链表L 已存在;操作结果:依次输出链表的各个结点的值;∙“求前驱算法”初始条件: 线性表L 已存在;操作结果: 若cur_e 是L 的数据元素,且不是第一个,则用pre_e 返回它的前驱;∙“求后继算法”初始条件: 线性表L 已存在;操作结果: 若cur_e 是L 的数据元素,且不是最后一个,则用next_e 返回它的后继;∙“两个有序链表的合并算法”初始条件: 线性表单链线性表La 和Lb 的元素按值非递减排列;操作结果:归并La 和Lb 得到新的单链表。
数据结构中的双向链表实现和应用场景
数据结构中的双向链表实现和应用场景双向链表是一种常用的数据结构,它在许多实际应用中都发挥着重要的作用。
本文将介绍双向链表的实现原理以及一些常见的应用场景。
一、双向链表的实现原理双向链表由一系列节点组成,每个节点包含两个指针,一个指向前一个节点,一个指向后一个节点。
相比于单向链表,双向链表可以实现双向遍历,提高了一些操作的效率。
1.1 节点定义双向链表的节点通常由数据域和两个指针域组成,例如:```struct Node {int data; // 节点数据Node* prev; // 前一个节点指针Node* next; // 后一个节点指针};```1.2 插入操作在双向链表中插入一个节点可以分为两种情况:在表头插入和在表尾插入。
在表头插入时,只需修改原来头节点的prev指针为新节点的地址,并将新节点的next指针指向原头节点即可。
在表尾插入时,需要先找到原来的尾节点,然后将尾节点的next指针指向新节点的地址,并将新节点的prev指针指向尾节点的地址。
1.3 删除操作删除操作与插入操作类似,同样分为在表头和表尾删除节点。
在表头删除时,只需将头节点的next指针指向新的头节点,同时将新头节点的prev指针置为空。
在表尾删除时,需要先找到尾节点的前一个节点,然后将该节点的next指针置为空。
1.4 查找操作双向链表支持从前向后和从后向前两种遍历方式。
从前向后遍历时,我们可以利用节点的next指针不断向后遍历得到所有节点。
同样,从后向前遍历时,可以利用节点的prev指针不断向前遍历得到所有节点。
二、双向链表的应用场景双向链表广泛应用于各种软件和系统中,下面列举了一些常见的应用场景。
2.1 浏览器的历史记录在浏览器中,经常需要记录用户浏览过的网页历史记录。
这时可以使用双向链表来实现。
每当用户访问一个新的网页,就在双向链表中插入一个新节点,同时将新节点的next指针指向前一个节点,prev指针指向后一个节点。
数据结构实验报告双链表
级数据结构实验报告实验名称:实验1 线性表学生姓名:班级:班内序号:学号:日期:1.实验要求1根据线性表的抽象数据类型的定义,选择下面任一种链式结构实现线性表,并完成线性表的基本功能。
1、双链表线性表的基本功能:1、构造:使用头插法、尾插法两种方法2、插入:要求建立的链表按照关键字从小到大有序3、删除4、查找5、获取链表长度6、销毁7、其他:可自行定义3编写测试main()函数测试线性表的正确性。
、4必须要有异常处理,比如删除空链表时需要抛出异常;5保持良好的编程的风格:代码段与段之间要有空行和缩近标识符名称应该与其代表的意义一致函数名之前应该添加注释说明该函数的功能关键代码应说明其功能递归程序注意调用的过程,防止栈溢出2. 程序分析2.1 存储结构2.2 关键算法分析 1.头插构造(一),自然语言1为将要插入的元素建立一个结点 2将结点连入头结点与原第二结点之间 (二),伪代码1初始化一个空链表2 为每个数组元素建立一个结点3将元素插进头结点与原第一结点间并连接上前后结点 4将原第一结点与头结点之间的连接断掉并连接到此元素上 (三),示意图first(b) 非空双循环链表 图2-19 双循环链表示意图(a) 空双循环链表图2-21双链表头插示意图(四),时间复杂度为O(1)2插入(一),自然语言1依次向后扫描直到目标位置,如果目标位置超出范围则抛出错误2更改目标位置前后指针,使插入元素连接进链表(二),伪代码1 定义工作指针p,计数器j清零2 执行下列操作,直到p超出链表范围或指向第i-1个结点2.1工作指针p后移;2.2j加1;3 更改目标位置的前后链接,连接上目标元素(三),具体代码template<class T>void LinkList<T>::Insert(int i,T x){Node<T> *p=first; int j=0;while(j<i-1){p=p->next;if(p==first)throw"x异常";j++;}{Node<T> *s=new Node<T>;s->data=x; s->next=p->next;s->prior=p;p->next->prior=s;p->next=s; //将元素链接在链表中}}(四),示意图双链表插入操作示意图(五),时间复杂度为O(n)3.删除(一),自然语言1依次向后扫描直到目标位置,如果目标位置超出范围则抛出错误2将目标元素删除(二),伪代码1 定义工作指针p,计数器j清零2 工作指针p后移2.1若p超出链表范围则抛出异常2.2 将p结点元素赋予x2.3 将p前驱后继从链表上摘下并将前驱后继相连2.4 释放被删除结点2.5返回x(三),具体代码template<class T>T LinkList<T>::Delete(int i){Node<T> *p=first;int j=0,x;while(j<i){p=p->next;if(p==first)throw"位置异常";//工作指针超过队尾则异常j++; //将工作指针移动到需删除元素的位子}if(p->next==first) cout<<"位置异常"<<endl;else{Node<T> *q=p;x=q->data;(p->prior)->next=p->next;(p->next)->prior=p->prior; //使该结点前后相连delete q; //删除该结点return x;}}(四)图2-22 双链表删除操作示意图(五),时间复杂度为O(n)2.3 其他3. 程序运行结果主函数流程自然语言1.定义a,b两个数组2. a,b分别头插尾插赋予list1 ,2两个双链表并输出3.获取List2中第二个节点4.在list2第二位插入8并输出List25.查找List2中3所在位置6.获取List2链表长度7.删除list2中第三个节点并输出执行结果4. 总结在这次实验中,我不仅更加深刻的了解了线性表表的结构,关于前驱,后继在表中的作用,与表中元素的联系,插入删除等操作的具体过程与使结构上发生的变化,查找,替换等操作的原理,而且对模板类这个上学期尚未学到的内容有了一个较为初步的认识。
数据结构实验二链表的实现和应用
⑶编写一个主程序对所实现的线性表进行测试;
⑷线性表的应用:①设线性表L1和L2分别代表集合A和B,试设计算法求A和B的并集C,并用线性表L3代表集合C;②设线性表L1和L2中的数据元素为整数,且均已按值非递减有序排列,试设计算法对L1和L2进行合并,用线性表L3保存合并结果,要求L3中的数据元素也按值非递减有序排列。(选做)
switch(compare(qa,qb))
{
case 1:
{
qc->coef=qa->coef;
qc->expn=qa->expn;
qa=qa->next;break;
}
case 0:
{
qc->coef=qa->coef+qb->coef;
qc->expn=qa->expn;
qa=qa->next;
DestroyPolyn(pc);
pd=SubtractPolyn(pa,pb);
printf("多项式a-b:");PrintPolyn(pd);
DestroyPolyn(pd);
pf=MultiplyPolyn(pa,pb);
printf("多项式a*b:");PrintPolyn(pf);
DestroyPolyn(pf);
Polyn qa=pa->next;
Polyn qb=pb->next;
hf=(Polyn)malloc(sizeof(struct Polynomial)); //建立头结点
hf->next=NULL;
for(;qa;qa=qa->next)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
循环链表、双链表及链表应用实验实验报告实验目的(1)理解单循环链表及双循环链表的特点。
(2)掌握这两种结构的算法设计。
(3)运用链表存储数据并设计有关算法。
(4)理解头结点、头指针概念以及设置头结点的优点实验运行环境Visual C++实验任务为使实验程序简洁直观, 同样是将实验程序中将所需要的函数以调用库函数的形式给出, 并假设将库函数放在程序文件"linklist.h"中, 同时假设该库函数文件中定义了链表结构中的指针类型为link, 结点类型为node, 双链表中结点的类型为dunode, 其中有data、next和prior等字段, data的类型为int, 而next和prior分别为指示其下一个和前一个结点的指针, 类型为dulink(即dunode *)。
类似地, 定义了部分常用运算, 如构建链表、显示链表等。
各运算的名称较为直观, 并有相应的注释, 因而易于理解和实现。
读者在上机实验时, 需要自己设计出所涉及到的库函数, 或者将函数放在实验程序中, 以方便实验程序的调试。
实验要求1.求链表中第i个结点的指针(函数),若不存在,则返回NULL。
2.在第i个结点前插入值为x的结点。
3.删除链表中第i个元素结点。
4.在一个递增有序的链表L中插入一个值为x的元素,并保持其递增有序特性。
5.将单链表L中的奇数项和偶数项结点分解开,并分别连成一个带头结点的单链表,然后再将这两个新链表同时输出在屏幕上,并保留原链表的显示结果,以便对照求解结果。
6.求两个递增有序链表L1和L2中的公共元素,并以同样方式连接成链表L3。
实验内容第一题:依次访问无头结点的单循环链表的各结点。
实验测试数据基本要求:第一组数据:链表元素为(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60)第二组数据:链表元素为(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)实验准备:p=head; //因为没有首位,所以输入一点,令为首位do{/*访问节点的语句*/;p=p->next;}while(p!=head); //只让循环进行一次,避免进入死循环,所以用p!=head//作为判断条件第二题:设计算法以判断一个带头结点的单循环链表是否满足这样的条件:其中每个结点的元素值与其序号的差的绝对值不大于3。
若成立, 返回TRUE, 否则返回FALSE。
实验测试数据基本要求:第一组数据:链表元素为(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 15, 16, 18)第二组数据:链表元素为(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 20, 18)实验准备:If((p->data-i<=3)&&( p->data-i>=-3))return TRUE;//判断每个结点的元素值与其序号的差的绝对值是否不大于3else return FALSE;第三题:利用递增有序的单循环链表表示集合, 分别求两个链表表示的集合的交、并集所构成的链表。
实验测试数据基本要求:第一组第一个链表元素为(1, 3, 6, 10, 15, 16, 17, 18, 19, 20)第二个链表元素为(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 18, 20, 30)第二组第一个链表元素为(1, 3, 6, 10, 15, 16, 17, 18, 19, 20)第二个链表元素为(2, 4, 5, 7, 8, 9, 12, 22)第三组第一个链表元素为()第二个链表元素为(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)实验准备:C=x^y,node*px,*py; //建立一个表C 和指针px pypx->data==py->data;px=px->next;py=py->next;//如果px指向的数据//等于py指向的数据,px 和px 就同时向后继续px->data>py->data;py=py->next;// 如果px指向的元素如果大于py,根据递增//有序,则只需py向后搜索比当前py指向的数据大的//数据来和当前px指向的数据判断是否相等px->data<py->data;px=px->next; // 如果px指向的元素如果小于py,根据递//增有序,则只需px向后搜索比当前px指向的数据大//的数据来和当前py指向的数据判断是否相等x=xUy;//取表x,将y与x元素做同样比较py->data!=px->data;将py->data插入x表;第四题:编写算法以构造带头结点的双循环链表。
实验测试数据基本要求:第一组数据:链表元素为(1,2,3,4,5,6,7,8,9,10)第二组数据:链表元素为(10,30,40,55,60,70,88,99,100)实验准备:struct dnode{elementtype data;dnode*prior,*next;};//先建立空表head=new dnode;指针指向null;p指向当前节点;//然后进行尾插入;p->next=s;s->prior=p;p=head;首尾相接;第五题:编写算法以判断一个带头结点的双循环链表是否是对称的, 若成立, 返回TRUE, 否则返回FALSE。
实验测试数据基本要求:第一组数据:链表元素为(1, 2, 3, 4, 5, 4, 3, 2, 1)第二组数据:链表元素为(1, 2, 3, 4, 5, 5, 4, 3, 2, 1)第三组数据:链表元素为(1, 2, 3, 4, 5, 6, 3, 2, 1)第四组数据:链表元素为(1, 2, 3, 4, 5, 5, 6, 4, 3, 2, 1)实验准备:{px=head->next;py=head->prior;//指针px指向后一数据,//指针py指向头元素的前一数据while(px!=py) //如果指针px和py指向的不是同一数//以此来作为结束循环的条件{if(px->data!=py->data) //只要有任意px和py指向数据不相等,return false; //则该链表是不对称的px=px->next;py=py->prior;} //只要任意px和py指向//数据未出现不相等,则继续向后查找return ture;实验程序#include <iostream.h>#include<stdlib.h>struct Node{int data1;Node *next1;};struct Dnode{int data2;Dnode *prior,*next2;};class list{private:Node*head1,*rear1;public:list();void first(); //第一题函数bool second(); //第二题函数void third_1(list &L1,list &L2); //第三题函数——交集void third_2(list &L1,list &L2); //第三题函数——并集void creat(); //创建单链表};class double_list{private:Dnode*head2,*rear2;public:double_list();void fourth(); //第四题函数bool fifth(); //第五题函数void creat_d(); //创建双链表};list::list(){head1=new Node;head1->next1=NULL;rear1=head1;}void list::creat() //创建单链表函数{Node*u;int x;cout<<"请输入单循环链表的数据,输入-1完成输入"<<endl;cin>>x;while(x!=-1){u=new Node;u->data1=x;rear1->next1=u;rear1=u;cin>>x;}rear1->next1=head1;}double_list::double_list(){head2=new Dnode;head2->next2=NULL;head2->prior=NULL;rear2=head2;}void double_list::creat_d() //创建双链表函数{Dnode*u;int x;cout<<"请输入双循环链表的数据,输入-1完成输入"<<endl;cin>>x;while(x!=-1){u=new Dnode;u->data2=x;rear2->next2=u;u->prior=rear2;rear2=u;cin>>x;}rear2->next2=head2;head2->prior=rear2;}void list::first() //第一题函数:访问无头结点的单循环链表的各结点{Node*u=head1;head1=u->next1;rear1->next1=head1;delete u;Node*p=head1;do{cout<<p->data1<<'\t';p=p->next1;}while(p!=head1);cout<<endl;}bool list::second() //第二题函数:判断一个带头结点的单循环链表是否满足{ //每个结点的元素值与其序号的差的绝对值不大于3Node*p=head1->next1;bool n=true;for(int i=1;p!=head1&&n!=false;i++,p=p->next1){if(i-p->data1<=3||p->data1-i<=3)n=true;else n=false;}return n;}void list::third_1(list &L1,list &L2) //第三题函数——交集:利用递增有序的单循环链{ //表表示集合,分别求两个链表表示的集合的交、并集所构成的链表Node*pa,*pb,*u;pa=L1.head1->next1;pb=L2.head1->next1;while(pa!=L1.head1&&pb!=L2.head1){if(pa->data1<pb->data1)pa=pa->next1;else if(pa->data1>pb->data1)pb=pb->next1;else{u=new Node;u->data1=pa->data1;rear1->next1=u;rear1=u;pa=pa->next1;pb=pb->next1;cout<<u->data1<<'\t';}rear1->next1=head1;}}void list::third_2(list &L1,list &L2) //第三题函数—并集:利用递增有序的单循环链, { //表表示集合分别求两个链表表示的集合的交、并集所//构成的链表Node*pa,*pb,*u;pa=L1.head1->next1;pb=L2.head1->next1;while(pa!=L1.head1&&pb!=L2.head1){if(pa->data1<pb->data1){u=new Node;u->data1=pa->data1;rear1->next1=u;rear1=u;pa=pa->next1;cout<<u->data1<<'\t';}else if(pa->data1>pb->data1){u=new Node;u->data1=pb->data1;rear1->next1=u;rear1=u;pb=pb->next1;cout<<u->data1<<'\t';}else{u=new Node;u->data1=pa->data1;rear1->next1=u;rear1=u;pa=pa->next1;pb=pb->next1;cout<<u->data1<<'\t';}rear1->next1=head1;}if(pa==L1.head1){for(;pb!=L2.head1;pb=pb->next1){u=new Node;u->data1=pb->data1;rear1->next1=u;rear1=u;cout<<u->data1<<'\t';}rear1->next1=head1;}elsefor(;pa!=L1.head1;pa=pa->next1){u=new Node;u->data1=pa->data1;rear1->next1=u;rear1=u;cout<<u->data1<<'\t';}rear1->next1=head1;}void double_list::fourth() //第四题函数:构造带头结点的双循环链表{rear2->next2=head2;head2->prior=rear2;Dnode*p=head2->next2;while(p!=head2){cout<<p->data2<<'\t';p=p->next2;}cout<<endl;}bool double_list::fifth() //第五题函数:判断一个带头结点的双循环链表是否是对称{Dnode*pa,*pb;bool n=true;pa=head2->next2;pb=head2->prior;while(pa!=pb&&pa->next2!=pb){if(pa->data2!=pb->data2){n=false; break;}pa=pa->next2;pb=pb->prior;}if(pa->next2==pb&&pa->data2!=pb->data2)n=false;return n;}int main(){list L_1,L_2,L_3;double_list D_1,D_2,D_3;int choice;cout<<" 数据结构实验二——循环链表、双链表及链表应用实验"<<endl;cout<<endl;cout<<"第1题:依次访问无头结点的单循环链表的各结点"<<endl;cout<<"第2题:判断一个带头结点的单循环链表是否满足: "<<endl;cout<<" 其中每个结点的元素值与其序号的差的绝对值不大于3"<<endl;cout<<"第3题:利用递增有序的单循环链表表示集合求两个链表表示的集合的交、并集所构成的链表"<<endl;cout<<"第4题:构造带头结点的双循环链表"<<endl;cout<<"第5题:判断一个带头结点的双循环链表是否是对称"<<endl;cout<<"退出程序:0"<<endl;cout<<endl;cout<<"请选择一道题"<<endl;;cin>>choice;switch(choice){case 1:{L_1.creat();L_1.first();break;}case 2:{L_1.creat();if(L_1.second())cout<<"true"<<endl;else cout<<"false"<<endl;break;}case 3:{L_1.creat();L_2.creat();L_3.third_1(L_1,L_2);break;}case 4:{L_1.creat();L_2.creat();L_3.third_2(L_1,L_2);break;}case 5:{D_1.creat_d();D_1.fourth();break;}case 6:{D_1.creat_d();if(D_1.fifth())cout<<"true"<<endl;elsecout<<"false"<<endl; break;}case 0:{cout<<endl<<"EXIT"<<endl;exit(1);break;}default:{cout<<"输入错误,请重新输入"<<endl; break;}}return 0;}实验程序运行结果第一题:第二题:第四题:。