双向链表的算法设计与实现实验报告
循环双链表实验报告

南京工程学院实验报告课程名称数据结构与算法实验实验项目名称线性表实验学生班级软件工程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());}}五、实验结果及分析(计算过程与结果、数据曲线、图表等)实验结果展示:六、实验总结与思考本实验是对链表的比较基础的运用(链表的查找,删除,插入)以及熟悉递归算法,算法本身并不难实现,难点在于算法的效率要高,可读性要强,这也是所有代码需要注意的,要做到每个指针都尽到最大的利用。
数据结构双向链表-推荐下载

二〇一二 年
//头文件 #define Student EType #define HeadEType int #include<iostream.h> #include <stdlib.h> #include<string.h> #include<iomanip.h> //以下是数据类型的定义 struct Student {
实验项目 1:线性表存储及运算
学 号
实验地点
评语:数据结构实验报告ຫໍສະໝຸດ 数据结构《实验 1》实验报告
姓 名
指导教师
按时完成实验;实验内容和过程记录完整;回答问题完整、
正确;实验报告的撰写认真、格式符合要求;无抄袭的行为。
线性表链式存储(双向链表)插入、删除运算
1、预习要求:线性表的插入、删除相关概念及运算,完成线性表元素的插入、删除。 2、实验目的: (1)了解线性表的插入、删除相关概念; (2)理解线性表的插入、删除过程和结构定义; (3)掌握算法转换为程序的过程中的变化。 3、实验内容及要求: (1)分别建立包含 10 个数据元素的链式存储线性表; (2)从键盘输入一个数据元素,插入到线性表中第 k(包含 0 号位置)个位置; (3)从键盘输入一个数据元素关键字或位置 k(包含 1 号位置),从线性表中删除相应 数据元素; (4)给出程序及插入、删除前和插入、删除后线性表结果。 4、实验设备(环境)及要求 硬件:支持 Intel Pentium Ⅱ及其以上 CPU ,内存 128MB 以上、硬盘 1GB 以上容量 的微机。 软件:配有 Windows98/2000/XP 操作系统,安装 Visual C++ 。 5、实验时间:6 学时 6、该文档的文件名不要修改,存入<学号> <姓名> 命名的文件夹中 7、该表中的数据只需填空,已有内容不要修改
双向链表实验报告

13软工转本1 钱剑滨实验报告双向链表实验报告信息工程系 13软工转本1 日期 2016年03月12日姓名钱剑滨学号 13131116 电话一、实验内容编写关于双向链表操作的C语言程序,要求包含双向链表的创建(生成)、输出(遍历)、查找、任意位置插入、有顺序插入、删除、等。
二、实验步骤1.分析操作所需思路,熟练运用单链表的各种特点。
2.编写程序,利用函数特性进行操作。
3.运行程序,纠正错误,对预测结果进行验证。
4.分析总结单链表的优缺点,并可以做到熟练掌握双向链表的各种操作。
三、设计概要1.本实验包含了7个函数:a)主函数main()b)创建链表函数Listcreate()c)数据输出函数Listprint()d)查找数据函数Listlocate()e)无序插入函数Listinsert_discretion ()f)有序插入函数Listinsert_orderg)删除数据函数Listdelete()2.明确函数的功能;a)Listcreate() 创建一个可控长度的斐波那契数列的双向链表。
b)Listprint() 将此链表中的数据全部输出。
c)Listlocate() 查找此链表中任意位置元素的值。
d)Listinsert_discretion ()向此链表的某个位置插入一组数据。
e)Listinsert_order() 向数列中插入一个数,使插入后的数列任然有序f)Listdelete() 将此链表的某个位置的一组数据删除。
四、程序设计1.函数前包含的头文件名、结点类型定义、全局变量和函数声明#include <stdio.h>#include <malloc.h>typedef struct number //定义结构体{struct number *prior;int num;struct number *next;}number;number *head; //定义全局变量头节点int k = 0; //k记录元素个数,防止溢出/*函数声明*/void Listcreate(); //建立链表void Listprint(); //全体输出void Listlocate(); //查找void Listinsert_discretion(); //任意位置插入void Listinsert_order(); //有顺序插入void Listdelete(); //删除2.主函数main()void main(){int select;printf("1、输入斐波那契数列的个数\n");printf("2、全部输出数列\n");printf("3、查找定位数列的元素\n");printf("4、添加数列元素\n");printf("5、插入顺序数列元素\n");printf("6、删除数列元素\n");printf("-------------------------------------\n");while (1){printf("请选择序号\n");scanf("%d", &select);switch (select){case 1: Listcreate(); break; //链表创建case 2: Listprint(); break; //全链表输出case 3: Listlocate(); break; //元素查找case 4: Listinsert_discretion(); break; //任意位置插入case 5: Listinsert_order(); break; //有顺序插入case 6: Listdelete(); break; //删除default: break;}}}3.创建链表函数Listcreate()void Listcreate() //建立链表{head = (number *)malloc(sizeof (number)); //开辟一个大小为number的内存空间给头节点head->next = NULL;head->prior = NULL;int a = 1,b = 1; //a、b为斐波那契数列的前两个元素int i;number *q;number *p = head; //p始终指向最后一个节点printf("输入元素的长度\n");scanf("%d",&i);/*给第一个元素赋值*/q = (number *)malloc(sizeof (number)); //开辟一个大小为number的内存空间给后面节点q->num = a;q->next = NULL; //新开辟的节点指向NULLp->next = q; //前一节点指向新开辟的节点q->prior = p; //开辟的节点前驱指向pp = p->next; //p指向新节点i = i - 1;k = k + 1;/*给第二个元素赋值*/q = (number *)malloc(sizeof (number));q->num = b;q->next = NULL;p->next = q;q->prior = p;p = p->next;i = i - 1;k = k + 1;/*给后续元素赋值*/while (i--)q = (number *)malloc(sizeof (number));q->num = (a+b);q->next = NULL;p->next = q;q->prior = p;p = p->next;a = a +b + b; //b = a - b; //将a+b的值付给b;b的值付给aa = a - b; //k = k + 1;}printf("链表建立成功\n");}4.数据输出函数Listprint()void Listprint() //全体输出{number *p = head->next;while (p != NULL){printf("%d ", p->num);p = p->next;}printf("\n");}5.查找数据函数Listlocate()void Listlocate() //查找{int i;number *p = head;printf("输入您要查询的元素位置\n");scanf("%d", &i);if ((i > k) || (i <= 0)){printf("查询的位置不存在\n");}else{while (i--){p = p->next;}printf("所查找数为%d\n", p->num);}}6.无序插入函数Listinsert_discretion()void Listinsert_discretion() //任意位置插入{int i;number *q;number *p = head;printf("输入您要插入哪个元素的后面\n");scanf("%d", &i);if ((i > k) || (i < 0)){printf("插入的位置不存在\n");}else{while (i--){p = p->next; //p最后指向要插入位置的前一个节点}q = (number *)malloc(sizeof (number));if (p->next == NULL) //插到末尾{q->next = NULL; //B的下一个元素指向空p->next = q; //p的下一个元素指向Bq->prior = p; //B的前驱指向p}else{q->next = p->next; //B的下一个元素指向p的下一个(两个不能反)p->next->prior = q; //p的下一个元素的前驱指向Bp->next = q; //p的下一个元素指向Bq->prior = p; //B的前驱指向p}printf("输入您要插入的数\n");scanf("%d", &(q->num));k = k + 1;}printf("插入成功\n");}7.有序插入函数Listinsert_order ()void Listinsert_order() //有顺序插入{number *q;number *p = head;q = (number *)malloc(sizeof (number));printf("输入您要插入哪个数\n");scanf("%d", &q->num);while (p->next){if (p->next->num >= q->num) //插在第一个比数大或等于的的数前{q->next = p->next;p->next->prior = q;p->next = q;q->prior = p;k = k + 1;break;}else{p = p->next;}}if (p->next == NULL) //插到末尾{q->next = NULL;p->next = q;q->prior = p;k = k + 1;}printf("插入成功\n");}8.删除数据函数Listdelete ()void Listdelete() //删除{int i;number *q;number *p=head;printf("输入您要删除哪个元素\n");scanf("%d", &i);if ((i > k) || (i <= 0)){printf("删除的位置不存在\n");}else{while (--i) //这里是先减再判断{p = p->next; //p指向被删除的元素的前一个元素}q = p->next; //q指向被删除的元素if (q->next == NULL) //删除最后一个元素{p->next = NULL;}else{p->next = q->next; //p的下一个元素指向q的下一个,即跳过被删除元素q->next->prior = p; //q的下一个元素的前驱指向p,也跳过被删除的元素}free(q); //清空删除元素k = k - 1;}printf("删除成功\n");}五、程序源码#include <stdio.h>#include <malloc.h>typedef struct number{struct number *prior;int num;struct number *next;}number;number *head; //定义全局变量头节点int k = 0; //k记录元素个数,防止溢出void Listcreate(); //建立链表void Listprint(); //全体输出void Listlocate(); //查找void Listinsert_discretion(); //任意位置插入void Listinsert_order(); //有顺序插入void Listdelete(); //删除void main(){int select;printf("1、输入斐波那契数列的个数\n");printf("2、全部输出数列\n");printf("3、查找定位数列的元素\n");printf("4、添加数列元素\n");printf("5、插入顺序数列元素\n");printf("6、删除数列元素\n");printf("-------------------------------------\n");while (1){printf("请选择序号\n");scanf("%d", &select);switch (select){case 1: Listcreate(); break;//链表创建case 2: Listprint(); break;//全链表输出case 3: Listlocate(); break; //元素查找case 4: Listinsert_discretion(); break; //任意位置插入case 5: Listinsert_order(); break; //有顺序插入case 6: Listdelete(); break; //删除default: break;}}}void Listcreate() //建立链表{head = (number *)malloc(sizeof (number)); //开辟一个大小为number 的内存空间给头节点head->next = NULL;head->prior = NULL;int a = 1,b = 1; //a、b为斐波那契数列的前两个元素int i;number *q;number *p = head; //p始终指向最后一个节点printf("输入元素的长度\n");scanf("%d",&i);q = (number *)malloc(sizeof (number)); //开辟一个大小为number的内存空间给后面节点q->num = a;q->next = NULL; //新开辟的节点指向NULLp->next = q; //前一节点指向新开辟的节点q->prior = p; //开辟的节点前驱指向pp = p->next; //p指向新节点i = i - 1;k = k + 1;q = (number *)malloc(sizeof (number));q->num = b;q->next = NULL;p->next = q;q->prior = p;p = p->next;i = i - 1;k = k + 1;while (i--){q = (number *)malloc(sizeof (number));q->num = (a+b);q->next = NULL;p->next = q;q->prior = p;p = p->next;a = a +b + b; //b = a - b; //将a+b的值付给b;b的值付给aa = a - b; //k = k + 1;}printf("链表建立成功\n");}void Listprint() //全体输出{number *p = head->next;while (p != NULL){printf("%d ", p->num);p = p->next;}printf("\n");}void Listlocate() //查找{int i;number *p = head;printf("输入您要查询的元素位置\n");scanf("%d", &i);if ((i > k) || (i <= 0)){printf("查询的位置不存在\n");}else{while (i--){p = p->next;}printf("所查找数为%d\n", p->num);}}void Listinsert_discretion() //任意位置插入{int i;number *q;number *p = head;printf("输入您要插入哪个元素的后面\n");scanf("%d", &i);if ((i > k) || (i < 0)){printf("插入的位置不存在\n");}else{while (i--){p = p->next; //p最后指向要插入位置的前一个节点}q = (number *)malloc(sizeof (number));if (p->next == NULL) //插到末尾{q->next = NULL; //B的下一个元素指向空p->next = q; //p的下一个元素指向Bq->prior = p; //B的前驱指向p}else{q->next = p->next; //B的下一个元素指向p的下一个(两个不能反)p->next->prior = q; //p的下一个元素的前驱指向Bp->next = q; //p的下一个元素指向Bq->prior = p; //B的前驱指向p}printf("输入您要插入的数\n");scanf("%d", &(q->num));k = k + 1;}printf("插入成功\n");}void Listinsert_order() //有顺序插入{number *q;number *p = head;q = (number *)malloc(sizeof (number));printf("输入您要插入哪个数\n");scanf("%d", &q->num);while (p->next){if (p->next->num >= q->num) //插在第一个比数大或等于的的数前{q->next = p->next;p->next->prior = q;p->next = q;q->prior = p;k = k + 1;break;}else{p = p->next;}}if (p->next == NULL) //插到末尾{q->next = NULL;p->next = q;q->prior = p;k = k + 1;}printf("插入成功\n");}void Listdelete() //删除{int i;number *q;number *p=head;printf("输入您要删除哪个元素\n");scanf("%d", &i);if ((i > k) || (i <= 0)){printf("删除的位置不存在\n");}else{while (--i) //这里是先减再判断{p = p->next; //p指向被删除的元素的前一个元素}q = p->next; //q指向被删除的元素if (q->next == NULL) //删除最后一个元素{p->next = NULL;}else{p->next = q->next; //p的下一个元素指向q的下一个,即跳过被删除元素q->next->prior = p; //q的下一个元素的前驱指向p,也跳过被删除的元素}free(q); //清空删除元素k = k - 1;}printf("删除成功\n");}六、测试结果1.最初运行程序时,有如下结果:2.在输入1后,创建长度为10的斐波那契数列,结果如下:3.在输入2后,显示数列,结果如下:4.在输入3后,进行查询操作后,结果如下:5.在输入4后,进行无序插入操作后,结果如下:6.在输入5后,进行有序插入操作后,结果如下:7.在输入6后,进行删除操作后,结果如下:8.输入其他数字的结果:七、总结反思刚做这个题目的时候发现自己结构体和链表学的太浅了,以前学得只是也不能很好的运用。
双向链表的算法设计与实现实验报告

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

双向链表的总结报告A.首先是对结点的定义问题。
结点的定义是有两个指针的,这是毫无疑问的。
外加一个实际要的数据变量。
尤其是在书写结点的构造函数的时候,在无参构造函数的书写和以前的单链表的书写是一样的,关键是第二个构造函数的书写,多了一个指针,问题是这两个指针的位置问题,即谁在前,谁在后的问题。
其实这个问题是无足轻重的,即顺序随便。
但是这个顺序会影响后面链表的实现的书写。
请参见链表的实现文件中相关的注释。
B.Error_code中的成员range_error可能与系统的参数有冲突。
经查阅得知确实有冲突,现将系统内的range_error列出如下:range_error ClassThe class serves as the base class for all exceptions thrown to report a range error.class range_error : public runtime_error {public:explicit range_error(const string& message);};The value returned by what is a copy of message.data.处理的方法是:在使用了range_error的地方都加上属于符,这样明确的说明range_error是属于哪一个名字空间了,在本程序中就是Error_code::range_errorC.在用双向链表来实现数据结构的时候时,在涉及到要插入元素的时候以及要删除元素的时候,要特别的注意,因为在这些操作中要考虑很多的临界情况。
D.现分析这个程序中的删除操作和插入操作,分析如下:1.删除操作:首先和其他的函数一样,要对链表是否是空进行判断,因为在空链表中进行删除的时候是非法的。
其次是对输入的删除的位置进行判断,可能用户输入的删除位置也是非法的。
首先考虑一般的情况,即删除的元素位于整个链表的中间,此时可以画图来演示实际的操作。
双向链表报告

数据结构实验报告实验名称:双向链表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)插入时:首先自动的判断所需输入数字的位置然后建立新的节点,然后进行后插入操作。
数据结构实验报告双链表

级数据结构实验报告实验名称:实验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. 总结在这次实验中,我不仅更加深刻的了解了线性表表的结构,关于前驱,后继在表中的作用,与表中元素的联系,插入删除等操作的具体过程与使结构上发生的变化,查找,替换等操作的原理,而且对模板类这个上学期尚未学到的内容有了一个较为初步的认识。
链表实验报告

链表实验报告一、实验目的链表是一种常见的数据结构,本次实验的主要目的是深入理解链表的概念、原理和操作,通过实际编程实现链表的创建、插入、删除、遍历等基本操作,掌握链表在数据存储和处理中的应用,提高对数据结构的理解和编程能力。
二、实验环境本次实验使用的编程语言为 C 语言,开发工具为 Visual Studio Code。
三、实验原理链表是一种动态的数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。
链表的优点是可以灵活地进行插入和删除操作,不需要像数组那样移动大量的数据。
链表分为单向链表、双向链表和循环链表等。
单向链表只有一个指向下一个节点的指针,双向链表有指向前一个节点和后一个节点的指针,循环链表的尾节点指向头节点,形成一个环形结构。
四、实验步骤1、单向链表的创建定义链表节点结构体,包含数据域和指针域。
编写创建链表的函数,通过动态分配内存创建链表节点,并将节点连接起来。
2、单向链表的插入操作实现头部插入、尾部插入和中间插入的函数。
在插入时,需要处理指针的更新,确保链表的连接正确。
3、单向链表的删除操作编写删除指定节点的函数。
删除节点时,要释放被删除节点的内存,并更新相邻节点的指针。
4、单向链表的遍历实现遍历链表并打印节点数据的函数。
5、双向链表的创建与操作类似于单向链表,定义双向链表节点结构体,并实现创建、插入、删除和遍历的函数。
注意双向链表中指针的更新方式与单向链表的不同。
6、循环链表的创建与操作定义循环链表节点结构体,创建循环链表。
实现循环链表的插入、删除和遍历操作,处理好尾节点与头节点的连接。
五、实验结果与分析1、单向链表成功创建了单向链表,并能够正确进行头部、尾部和中间的插入操作。
删除操作也能准确删除指定节点,并释放内存。
遍历输出的结果与预期相符。
2、双向链表双向链表的创建和各种操作都能正常执行,指针的更新没有出现错误。
在双向链表中,插入和删除操作的效率相对单向链表有所提高,因为可以直接通过前向指针进行操作。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
}
DuLinkList GetElemP_DuL(DuLinkList L,int i){ int j; DuLinkList p; p=L->next; j=1; while(p&&j<i){ p=p->next;++j; } if(!p||j>i) return NULL; return p;
}
scanf("%d",&i); p=GetElemP_DuL(L,i); printf("e=%d\n",p->data);
5
scanf("%d%d",&i,&e); ListInsert_DuL(L,i,e); for(p=L->next;p!=L;p=p->next)
printf("%d ",p->data); printf("\n"); scanf("%d",&i); ListDelete_DuL(L,i,e); for(p=L->next;p!=L;p=p->next)
Status ListInsert_DuL(DuLinkList &L,int i,ElemType e){
4
DuLinkList p,s; if(!(p=GetElemP_DuL(L,i)))
return ERROR; if(!(s=(DuLinkList)malloc(sizeof(DuLNode))))return ERROR; s->data=e; s->prior=p->prior;p->prior->next=s; s->next=p; p->prior=s; return OK; }
二、实验内容:
1
【实验方案】 首先利用尾插法建立一个双向链表,然后,分别编写功能为实现入队操作和出队操作的 子函数,
【实验过程】(实验步骤、记录、数据、分析) 1.打开 Visual C++,新建一个源程序 zw.cpp 2.调用初始化建立双向链表算法,查找算法,插入算法和删除算法 3.设计建立结果输出程序 4.操作修改源程序中的错误 5.出现 11 个错误,将 nert 改为 next,还有变量未定义, 定义变量后组建调试后没有错误 6.编辑 main 函数 7.继续修改错误,直到错误为 0 8.打开程序运行窗口,输入输出结果 9.输入 5 再输入 33 34 35 36 37 输出结果
7.实验结论(结果):根据实验过程中得到的结果,做出结论。 8.实验小结:本次实验心得体会、思考和建议。 9.指导教师评语及成绩:指导教师依据学生的实际报告内容,给出本次实验报告的评价。
7
附录 1:源 程 序
#include<stdio.h> #include<stdlib.h> #define OK 1
3
#define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 typedef int Status; typedef int ElemType;
typedef struct DuLNode{ ElemType data; struct DuLNode *prior; struct DuLNode *next;
}DuLNode, *DuLinkList;
void Createlist_DuL(DuLinkList &L,int n){ int i; DuLinkList p; L=(DuLinkList)malloc(sizeof(DuLNode)); L->next=L->prior=L; for(i=n;i>0;--i){ p=(DuLinkList)malloc(sizeof(DuLNode)); scanf("%d",&p->data); p->prior=L; p->next=L->next; L->next->prior=p; L->next=p; }
数学与计算科学学院 实验报告
实验项目名称 双向链表的算法设计与实现
所属课程名称
__数据结构 A
实验类型
设计型
实验日期
__
班级 学号 姓名 成绩
信计 1402 201453100214
俞凯烨
一、实验概述: 【实验目的】 掌握双向链表的存储结构以及基本操作的设计和实现。 【实验原理】 双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别 指向直接后继和直接前驱。 【实验环境】
}
void main() {
DuLinkList p,L; int i,n; ElemType e;
scanf("%d",&n); Createlist_DuL(L,n);
for(p=L->next;p!=L;p=p->next) printf("%d ",p->data);
printf("\n");
对于验证性实验,要写明依据何种原理、操作方法进行实验,要写明需要经过哪几个步 骤来实现其操作。对于设计性和综合性实验,在上述内容基础上还应该画出流程图、设 计思路和设计方法,再配以相应的文字说明。对于创新性实验,还应注明其创新点、特 色。
6
6.实验过程(实验中涉及的记录、数据、分析):写明具体实验方案的具体实施步骤,包 括实验过程中的记录、数据和相应的分析。
【实验结论】(结果)
【实验小结】(收获体会) 学会了如何找到并修改程序中的错误
三、指导教师评语及成绩: 评语
2
评语等级
优良 中
及 格
不及格
1.实验报告按时完成,字迹清楚,文字叙述流畅,逻辑性强 2.实验方案设计合理 3.实验过程(实验步骤详细,记录完整,数据合理,分析透 彻) 4 实验结论正确.
成 绩: 指导教师签名: 批阅日期:
printf("%d ",p->data); printf("\n"); }
附录 2:实验报告填写说明
1.实验项目名称:要求与实验教学大纲一致。 2.实验目的:目的要明确,要抓住重点,符合实验教学大纲要求。 3.实验原理:简要说明本实验项目所涉及的理论知识。 4.实验环境:实验用的软、硬件环境。 5.实验方案(思路、步骤和方法等):这是实验报告极其重要的内容。概括整个实验过程。