顺序表及链表的应用
- 格式:doc
- 大小:131.50 KB
- 文档页数:16
数据结构中顺序表与链表的性能⽅⾯⽐较
⼀,时间性能的⽐较
顺序表由数组实现,是⼀种随机存取结构,对表中任意节点存取操作时间复杂度为O(1)。
⽽查找链表的节点,须从头指针开始沿链扫描,平均时间复杂度为O(N).因此,若线性表的操作主要是查找,很少进⾏插⼊或删除操作,采⽤顺序⽐较合适。
对于链表,对某个节点进⾏插⼊删除操作只需修改指针,⽆需⼤量移动元素,平均时间复杂度为O(1)。
⽽顺序表在插⼊或删除时,需要⼤量移动数据元素,平均移动元素的数⽬为表长的⼀般,时间复杂度为O(N)。
因此,对线性表频繁的进⾏插⼊删除操作时,应采⽤链表。
当插⼊和删除主要在表头或表尾时,应采⽤循环链表。
表1:时间性能⽐较
时间复杂度查找插⼊或删
除
顺序表O(1)O(N)
链表O(N)O(1)
⼆,空间性能的⽐较
1,顺序表的存储空间是静态分配的,必须提前确定其内存⼤⼩。
常⽤于存储规模容易确定的线性表。
2,动态链表的存储空间是动态分配的,只要其内存空间有空闲就不会出现溢出。
常⽤于长度变化较⼤或长度难以估计的线性表。
3,定义:存储密度=(节点中数据域占⽤的空间)/(节点结构占⽤的存储空间)
有时需考虑存储密度。
综上,在选取线性表时,应综合考虑时间和空间因素,选择⼀中最适合的。
⼀般⽽⾔,顺序表适⽤于查询,⽽链表则更便于插⼊删除管理。
算法与及数据结构实验报告算法与数据结构实验报告一、实验目的本次算法与数据结构实验的主要目的是通过实际操作和编程实现,深入理解和掌握常见算法和数据结构的基本原理、特性和应用,提高我们解决实际问题的能力和编程技巧。
二、实验环境本次实验使用的编程语言为 Python,开发环境为 PyCharm。
同时,为了进行算法性能的分析和比较,使用了 Python 的 time 模块来计算程序的运行时间。
三、实验内容1、线性表的实现与操作顺序表的实现:使用数组来实现顺序表,并实现了插入、删除、查找等基本操作。
链表的实现:通过创建节点类来实现链表,包括单向链表和双向链表,并完成了相应的操作。
2、栈和队列的应用栈的实现与应用:用数组或链表实现栈结构,解决了表达式求值、括号匹配等问题。
队列的实现与应用:实现了顺序队列和循环队列,用于模拟排队系统等场景。
3、树结构的探索二叉树的创建与遍历:实现了二叉树的先序、中序和后序遍历算法,并对其时间复杂度进行了分析。
二叉搜索树的操作:构建二叉搜索树,实现了插入、删除、查找等操作。
4、图的表示与遍历邻接矩阵和邻接表表示图:分别用邻接矩阵和邻接表来存储图的结构,并对两种表示方法的优缺点进行了比较。
图的深度优先遍历和广度优先遍历:实现了两种遍历算法,并应用于解决路径查找等问题。
5、排序算法的比较插入排序、冒泡排序、选择排序:实现了这三种简单排序算法,并对不同规模的数据进行排序,比较它们的性能。
快速排序、归并排序:深入理解并实现了这两种高效的排序算法,通过实验分析其在不同情况下的表现。
6、查找算法的实践顺序查找、二分查找:实现了这两种基本的查找算法,并比较它们在有序和无序数据中的查找效率。
四、实验步骤及结果分析1、线性表的实现与操作顺序表:在实现顺序表的插入操作时,如果插入位置在表的末尾或中间,需要移动后续元素以腾出空间。
删除操作同理,需要移动被删除元素后面的元素。
在查找操作中,通过遍历数组即可完成。
约瑟夫环实验报告总结【篇一:约瑟夫环实验报告】实验报告课程名称:数据结构实验名称:顺序表和链表的应用实验编号:实验一指导教师:一、实验目的(1)掌握线性表的基本操作(插入、删除、查找)以及线性表合并等运算在顺序存储结构、链式存储结构上的实现。
重点掌握链式存储结构实现的各种操作。
(2)掌握线性表的链式存储结构的应用。
二、实验内容与实验步骤(1)实验内容:实现约瑟夫环,约瑟夫环(joseph)问题的一种描述是:编号为1、2、3……n的n个人按照顺时针方向围坐一圈,每人持有一个密码(正整数)。
一开始任选一个正整数作为报数的上限值m,从第一个人开始按照顺时针的方向自1开始顺序报数,报到m时停止报数。
报m的人出列,将他的密码作为新的m值,从他的顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。
设计一个程序求出出列顺序。
(2)抽象数据类型和设计的函数描述,说明解决设想。
首先定义一个链表,用其中的data项存储每个人的编号,用password项存储每个人所持有的密码,并且声明一个指针。
之后使用creatlist_cl函数来创建一个循环链表,在其中的data和password中存入编号和密码,最后使最后一个节点的next指向l,使其能够形成循环队列。
定义了函数display来显示链表当中的内容,以确定存储的数据没有错误。
定义了函数delete_l来实现约瑟夫环中依次删除的功能,依次比较,如果某个人所持的密码和m值相等,则删除这个结点,并且输出此时该结点的编号和密码,实现出列的功能。
(3)简短明确地写出实验所采用的存储结构,并加以说明。
该实验我主要采用的是线性表的链式存储结构,首先定义了链表的结构,其中包括data项和password项,分别存储每个人的编号和所持密码,还声明了指向下一个结点的指针,该指针可以连接各个结点,并且将最后一个结点的指针指向第一个结点使之成为一个循环链表。
三、实验环境操作系统:windows 7调试软件名称:vc++版本号:6.0上机地点:综合楼311四、实验过程与分析(1)主要的函数或操作内部的主要算法,分析这个算法的时、空复杂度,并说明设计的巧班级:学号:姓名:组号:实验成绩:批阅教师签字:实验日期:实验时间:妙之处。
实验一顺序表的应用一.实验目的1、掌握线性表的顺序存储结构的基本操作的实现。
2、设计并实现顺序表的应用程序,提高编程能力。
二.实验内容编写程序实现:1、在原来的顺序表中将顺序表实现逆置。
2、要求顺序表的内容由用户输入,并分别显示出逆置前和逆置后的顺序表。
三.实验设备及实验环境实验设备:微机一台实验环境:C语言运行环境实验二单链表的应用三.实验目的1、掌握线性表的链式存储结构的基本操作的实现。
2、设计并实现单链表的应用程序,提高编程能力。
四.实验内容编写程序实现:1、在原有的单链表中,将单链表实现逆置。
(即不增加新的结点)2、程序要求单链表的内容由用户输入,并分别显示出逆置前和逆置后的单链表。
三.实验设备及实验环境实验设备:微机一台实验环境:C语言运行环境实验三栈和队列的应用一.实验目的1、掌握栈和队列的基本操作的实现。
2、利用栈和队列的特点解决实际问题,提高编程能力。
二.实验内容(1是必做题目,2和3可选其一)编写两个程序分别实现:1、进制之间的转换:如将10进制转换为2进制,10进制数n和要转换的进制d通过键盘输入。
2、利用栈解决火车调度问题,将本来杂乱无章的车厢排成软席(S)在前,硬席(H)在后。
车厢序列通过键盘输入,如HSHSHSSSH,输出SSSSSHHHH。
3、利用队列模拟医院排队系统。
三.实验设备及实验环境实验设备:微机一台实验环境:C语言运行环境实验四二叉树的操作(一)一、实验目的1、熟悉二叉树的概念和存储结构。
2、掌握二叉树的基本操作和实现方法。
二.实验内容1、利用栈并且采用非递归先序算法建立二叉树。
2、要求通过键盘输入二叉树的先序遍历顺序从而建立一棵二叉树。
三.实验设备及实验环境实验设备:微机一台实验环境:C语言运行环境实验五二叉树的基本操作(二)一、实验目的1.熟悉二叉树的遍历方法。
2.掌握非递归中序遍历、先序遍历和后序遍历算法的实现。
二.实验内容(中序非递归遍历必做、先序和后序可选其一)1、在前一实验的基础上,利用栈实现一棵二叉树的非递归遍历。
顺序表与链表的比较一、顺序表的特点是逻辑上相邻的数据元素,物理存储位置也相邻,并且,顺序表的存储空间需要预先分配。
它的优点是:(1)方法简单,各种高级语言中都有数组,容易实现。
(2)不用为表示节点间的逻辑关系而增加额外的存储开销。
(3)顺序表具有按元素序号随机访问的特点。
缺点:(1)在顺序表中做插入、删除操作时,平均移动表中的一半元素,因此对n较大的顺序表效率低。
(2)需要预先分配足够大的存储空间,估计过大,可能会导致顺序表后部大量闲置;预先分配过小,又会造成溢出。
二、在链表中逻辑上相邻的数据元素,物理存储位置不一定相邻,它使用指针实现元素之间的逻辑关系。
并且,链表的存储空间是动态分配的。
链表的最大特点是:插入、删除运算方便。
缺点:(1)要占用额外的存储空间存储元素之间的关系,存储密度降低。
存储密度是指一个节点中数据元素所占的存储单元和整个节点所占的存储单元之比。
(2)链表不是一种随机存储结构,不能随机存取元素。
三、顺序表与链表的优缺点切好相反,那么在实践应用中怎样选取存储结构呢?通常有以下几点考虑:(1)顺序表的存储空间是静态分配的,在程序执行之前必须明确规定它的存储规模,也就是说事先对“MaxSize”要有合适的设定,设定过大会造成存储空间的浪费,过小造成溢出。
因此,当对线性表的长度或存储规模难以估计时,不宜采用顺序表。
然而,链表的动态分配则可以克服这个缺点。
链表不需要预留存储空间,也不需要知道表长如何变化,只要内存空间尚有空闲,就可以再程序运行时随时地动态分配空间,不需要时还可以动态回收。
因此,当线性表的长度变化较大或者难以估计其存储规模时,宜采用动态链表作为存储结构。
但在链表中,除数据域外海需要在每个节点上附加指针。
如果节点的数据占据的空间小,则链表的结构性开销就占去了整个存储空间的大部分。
当顺序表被填满时,则没有结构开销。
在这种情况下,顺序表的空间效率更高。
由于设置指针域额外地开销了一定的存储空间,从存储密度的角度来讲,链表的存储密度小于1.因此,当线性表的长度变化不大而且事先容易确定其大小时,为节省存储空间,则采用顺序表作为存储结构比较适宜。
数据结构舞伴问题课程设计一、课程目标知识目标:1. 理解舞伴问题在数据结构中的背景及应用,掌握其基本概念与算法原理;2. 学会运用顺序表和链表两种数据结构解决舞伴问题,并掌握其优缺点;3. 能够运用所学知识,解决类似舞伴问题的其他实际应用问题。
技能目标:1. 培养学生运用数据结构解决实际问题的能力,提高编程技能;2. 培养学生分析问题、设计算法、编写程序及调试程序的能力;3. 培养学生通过合作、交流、分享等方式,提高团队协作能力。
情感态度价值观目标:1. 培养学生对数据结构的兴趣,激发学生学习算法的积极性;2. 培养学生勇于面对问题、克服困难的信心和决心,形成良好的学习习惯;3. 培养学生具备解决问题的责任心和使命感,认识到数据结构在信息技术领域的重要作用。
分析课程性质、学生特点和教学要求,本课程目标旨在让学生掌握舞伴问题及相关数据结构知识,培养其编程技能和团队协作能力。
通过本课程的学习,学生能够运用所学知识解决实际问题,提高自身综合素质,为未来的学习和发展打下坚实基础。
二、教学内容本课程以《数据结构》教材中舞伴问题相关章节为基础,组织以下教学内容:1. 舞伴问题背景介绍:阐述舞伴问题的实际应用场景,使学生了解其在信息技术领域的意义。
2. 数据结构基本概念:回顾线性表、顺序表和链表等基本数据结构,为解决舞伴问题打下基础。
3. 舞伴问题算法原理:介绍舞伴问题的算法原理,包括配对过程、算法步骤等。
4. 顺序表和链表的应用:详细讲解如何使用顺序表和链表解决舞伴问题,分析两种方法的优缺点。
5. 编程实践:引导学生运用所学知识编写程序,解决舞伴问题,并调试优化。
6. 实例分析:分析舞伴问题在其他领域的应用,提高学生运用知识解决实际问题的能力。
教学大纲安排如下:1. 第一周:舞伴问题背景介绍,数据结构基本概念回顾;2. 第二周:舞伴问题算法原理,顺序表和链表的应用;3. 第三周:编程实践,分组讨论与交流;4. 第四周:实例分析,总结与拓展。
第12讲顺序与链表综合比较顺序表和链表这两种存储表示方法各有优缺点。
在实际应用中究竟选用哪一种存储结构呢?这要根据具体的要求和性质决定。
顺序表和链表的比较1.基于空间的考虑顺序表的存储空间是静态分配的,在程序执行之前必须明确规定它的存储规模。
若线性表的长度n变化较大,则存储规模难于预先确定。
估计过大将造成空间浪费,估计太小又将使空间溢出的机会增多。
在静态链表中,初始存储池虽然也是静态分配的,但若同时存在若干个结点类型相同的链表,则它们可以共享空间,使各链表之间能够相互调节余缺,减少溢出机会。
动态链表的存储空间是动态分配的,只要内存空间尚有空闲,就不会产生溢出。
因此,当线性表的长度变化较大,难以估计其存储规模时,采用动态链表作为存储结构较好。
存储密度(Storage Density)是指结点数据本身所占的存储量和整个结点结构所占的存储量之比,即:存储密度=结点数据本身所占的存储量/结点结构所占的存储总量链表中的每个结点,除了数据域外,还要额外设置指针(或游标)域,从存储密度来讲,这是不经济的。
一般地,存储密度越大,存储空间的利用率就高。
显然,顺序表的存储密度为1,而链表的存储密度小于1。
例如单链表的结点的数据均为整数,指针所占空间和整型量相同,则单链表的存储密度为50%。
因此若不考虑顺序表中的备用结点空间,则顺序表的存储空间利用率为100%,而单链表的存储空间利用率为50%。
由此可知,当线性表的长度变化不大,易于事先确定其大小时,为了节约存储空间,宜采用顺序表作为存储结构。
2.基于时间的考虑顺序表是由向量实现的,它是一种随机存取结构,对表中任一结点都可以在O(1) 时间内直接地存取,而链表中的结点,需从头指针起顺着链找才能取得。
因此,若线性表的操作主要是进行查找,很少做插入和删除时,宜采用顺序表做存储结构。
在链表中的任何位置上进行插入和删除,都只需要修改指针。
而在顺序表中进行插入和删除,平均要移动表中近一半的结点,尤其是当每个结点的信息量较大时,移动结点的时间开销就相当可观。
设计一顺序表的应用代码Head.h#define LIST_INIT_SIZE 100//线性表存储空间的初始分配量#define LISTINCREMENT 10//线性表存储空间的分配增量#define STACK_INIT_SIZE 100//栈存储空间初始分配量#define STACKINCREMENT 10//栈存储空间分配增量#define MAXQSIZE 10//最大队列长度typedef int ElemType;typedef char SElemType;typedef int QElemType;typedef struct{int *elem;//存储空间基址int length;//当前长度int listsize;//当前分配的存储容量}SqList;typedef struct{SElemType *base;//在栈构造之前和销毁之后,base的值为null SElemType *top;//栈顶指针int stacksize;//当前已分配的存储空间,以元素为单位}SqStack;typedef struct{QElemType *base;//初始化的动态分配存储空间int front;//头指针,若队列不空,指向队列头元素int rear;//尾指针,若队列不空,指向队列尾元素的下一个位置}SqQueue;void Check1();void Check2();void Check3();void Check4();int InitList_Sq(SqList *L);int CreateList(SqList *L);int DeleteElem_Sq(SqList *L);int PrintElem(SqList L);int DeleteElem_1(SqList *L);int DevideList_Sq(SqList L,SqList *La,SqList *Lb);int InitStack(SqStack *L);int Push(SqStack *S,SElemType e);int StackEmpty(SqStack S);int GetTop(SqStack S,SElemType *e);int Pop(SqStack *S,SElemType *e);int Correct(char exp[], int n);int InitQueue(SqQueue *Q);int CreateQueue(SqQueue *Q);int PrintQueue(SqQueue Q);int EnQueue(SqQueue *Q,QElemType e);int DeQueue(SqQueue *Q,QElemType *e); ………………………………………………………………………………………………………. main.cpp#include<stdio.h>#include "head.h"#include"stdlib.h"#include <string.h>void main(){int choice;do{printf("\n 顺序表的应用\n");printf("\n ------------主菜单-------------- \n");printf(" (1) 删除线性表中值为item的元素\n");printf(" (2) 将一个顺序表分拆成两个顺序表 \n");printf(" (3) 判断括弧是否匹对 \n");printf(" (4) 循环队列中插入和取出节点\n");printf(" (0) 退出系统 \n");printf("\n请选择操作步骤:");scanf("%d",&choice);if(choice<0 && choice>4) continue;switch(choice){case 1:Check1();break;case 2:Check2();break;case 3:Check3();break;case 4:Check4();break;case 0:exit(0);default:break;}}while(1);} ………………………………………………………………………………………………………. Check1.cpp#include "head.h"#include <stdio.h>void Check1(){SqList L1;printf("实现删除线性表中值为item的元素的算法:\n");CreateList(&L1);//实现第一个算法PrintElem(L1);DeleteElem_1(&L1);PrintElem(L1);}CreateList.cpp#include"head.h"#include"stdio.h"#include"stdlib.h"//创建顺序表,在顺序表中输入数据元素。
int CreateList(SqList *L){int i,n;if(!InitList_Sq(L))exit(-1);printf("请输入顺序表的长度:");scanf("%d",&n);(*L).length=n;ElemType *p=(*L).elem;printf("请输入顺序表的数据元素:");for(i=0;i<n;i++){scanf("%d",p);p++;}return 1;}PrintElem.cpp#include "head.h"#include <stdio.h>int PrintElem(SqList L){if(L.length==0)printf("Empty!\n");int i;for(i=0;i<L.length;i++)printf("%4d",L.elem[i]);printf("\n");return 1;}DeleteElem_1.cpp#include "head.h"#include<stdio.h>int DeleteElem_1(SqList *L){int *p,*q,item;printf("请输入要删去的元素:");scanf("%d",&item);p=(*L).elem;q=(*L).elem+(*L).length-1;while(p<q){if(*p==item){*p=*q;q--;(*L).length--;}else p++;}if(*p==item)(*L).length--;return 1;}………………………………………………………………………………………………………. Check2().cpp#include "head.h"#include <stdio.h>void Check2(){SqList L2,La,Lb;printf("实现将一个顺序表分拆成两个顺序表的算法:\n");CreateList(&L2);//实现第二个算法PrintElem(L2);DevideList_Sq(L2,&La,&Lb);PrintElem(La);PrintElem(Lb);}DevideList_Sq.cpp#include "head.h"int DevideList_Sq(SqList L,SqList *La,SqList *Lb){InitList_Sq(La);InitList_Sq(Lb);(*La).length=(*La).length=0;int *p,*q;p=L.elem;q=L.elem+L.length-1;for(;p<=q;p++){if((*p)>0)(*La).elem[(*La).length++]=*p;else (*Lb).elem[(*Lb).length++]=*p;}return 1;}InitList_Sq.cpp#include "head.h"#include <stdlib.h>//构造一个空的线性表int InitList_Sq(SqList *L){(*L).elem=(ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));if(!((*L).elem))exit(-1);//存储分配失败(*L).length=0;//空表长度为0(*L).listsize=LIST_INIT_SIZE;//初始存储容量return 1;}………………………………………………………………………………………………………. Check3().cpp#include "head.h"#include <stdio.h>#include<string.h>void Check3(){printf("实现判断括弧是否匹对的算法:\n");char a[20];//实现第三个算法int tag;printf("Input String:");scanf("%s",a);tag=Correct(a,strlen(a));if(tag) printf("correct!\n");else printf("wrong!\n");}Correct.cpp#include "head.h"int Correct(char exp[], int n){SqStack S; InitStack(&S);char *p=exp,e,x;int i;for(i=0;i<n;i++,p++){if(*p=='('||*p=='['||*p=='{')Push(&S,*p);else if(*p==')'||*p==']'||*p=='}'){GetTop(S,&e);switch(*p){case ')':if(e=='(')Pop(&S,&x);else return 0;break;case ']':if(e=='[')Pop(&S,&x);else return 0;break;case '}':if(e=='{')Pop(&S,&x);else return 0;break;}}}if(!StackEmpty(S))return 0;else return 1;}GetTop.cpp#include "head.h"int GetTop(SqStack S,SElemType *e){//若栈不空,则用e返回S的栈顶元素,并返回1,否则返回0 if(S.top==S.base)return 0;else *e=*(S.top-1);return 1;}InitStack.cpp#include<stdlib.h>#include "head.h"//构造一个空栈int InitStack(SqStack *S){(*S).base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));if(!(*S).base)exit(-1);//存储分配失败(*S).top=(*S).base;(*S).stacksize=STACK_INIT_SIZE;return 1;}Pop.cpp#include "head.h"int Pop(SqStack *S,SElemType *e){//若栈不空,则删除S的栈顶元素,用e返回其值,并返回1,否则返回0 if(StackEmpty(*S))return 0;*e=*(--(*S).top);return 1;}Push.cpp#include<stdlib.h>#include "head.h"int Push(SqStack *S,SElemType e){//插入元素e为新的栈顶元素if((*S).top-(*S).base>=(*S).stacksize)//栈满,追加存储空间{(*S).base=(SElemType*)realloc((*S).base,((*S).stacksize+STACKINCREMENT)*sizeof(SElemType));if(!(*S).base)exit(-1);//存储分配失败(*S).stacksize+=STACKINCREMENT;}*((*S).top++)=e;return 1;}StackEmpty.cpp#include "head.h"int StackEmpty(SqStack S){if(S.top==S.base)return 1;else return 0;}………………………………………………………………………………………………………. Check4().cpp#include "head.h"#include <stdio.h>void Check4(){printf("实现循环队列中插入和取出节点的算法:\n");SqQueue Q;//实现第四个算法QElemType e;CreateQueue(&Q);printf("请输入插入的节点:");scanf("%d",&e);PrintQueue(Q);EnQueue(&Q,e);PrintQueue(Q);DeQueue(&Q,&e);PrintQueue(Q);}CreateQueue.cpp#include<stdio.h>#include "head.h"//创建一个队列int (SqQueue *Q){int n,i;InitQueue(Q);printf("输入队列的长度:");scanf("%d",&n);if(n>MAXQSIZE){printf("overflow!\n");return 0;}for(i=0;i<n-1;i++)scanf("%d",((*Q).base)+i);(*Q).rear=n-1;return 1;}DeQueue.cpp#include "head.h"#include<stdio.h>int DeQueue(SqQueue *Q,QElemType *e){//若队列不空,则删除Q的队头元素,用e返回其值,并返回1,否则返回0 if((*Q).front==(*Q).rear){printf("The Queue is empty!");return 0;}*e=(*Q).base[(*Q).front];(*Q).front=((*Q).front+1)%MAXQSIZE;return 1;}EnQueue.cpp#include<stdio.h>#include "head.h"int EnQueue(SqQueue *Q,QElemType e){//插入元素e为新的队尾元素if(((*Q).rear+1)%MAXQSIZE==(*Q).front){printf("overflow!\n");return 0;}//队列满((*Q).base)[(*Q).rear]=e;(*Q).rear=((*Q).rear+1)%MAXQSIZE;return 1;}InitQueue.cpp#include "head.h"#include <stdlib.h>//构造一个空队列int InitQueue(SqQueue *Q){(*Q).base=(QElemType *)malloc(MAXQSIZE*sizeof(QElemType));if(!((*Q).base))exit(-1);//存储空间分配失败(*Q).front=(*Q).rear=0;return 1;}PrintQueue.cpp#include "head.h"#include<stdio.h>int PrintQueue(SqQueue Q){if(Q.front==Q.rear){printf("empty!");return 0;}int i,n;QElemType *p;n=(Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;p=&((Q.base))[Q.front];for(i=0;i<n;i++){printf("%4d",*p);if(p==&Q.base[MAXQSIZE-1])p=Q.base;else p++;}printf("\n");return 1;} ……………………………………………………………………………………………………….设计二链表的应用代码Head.htypedef int ElemType;typedef struct LNode{//线性表的单链表存储结构ElemType data;struct LNode *next;}LNode,*LinkList;typedef struct DuLNode{//线性表的双向链表存储结构ElemType data;struct DuLNode *prior;struct DuLNode *next;int freq;}DulNode,*DuLinkList;void CreateList_L(LinkList *L,int n);int PrintLinkList(LinkList L);int EqualLinkList(LinkList *La,LinkList *Lb);void CreatCircularLinkList(LinkList *L,int n);int MonkeyKing(LinkList L,int n);int LinkListLength_Dul(DuLinkList L);int CreateLinkList_Dul(DuLinkList *L,int n);int PrintLinkList_Dul(DuLinkList L);int Locate(DuLinkList *L,ElemType e);//int InterSection(LinkList La,LinkList Lb,LinkList *Lc);void Check_1();void Check_2();void Check_3();…………………………………………………………………………………………………….... main.cpp#include<stdio.h>#include "head.h"#include<stdlib.h>void main(){int choice;do{printf("\n 链表的应用\n");printf("\n ------------主菜单-------------- \n");printf(" (1) 删除两个递增链表中不同的元素 \n");printf(" (2) 猴子选大王\n");printf(" (3) 实现locate函数\n");printf(" (0) 退出系统... \n");printf("\n请选择操作步骤:");scanf("%d",&choice);if(choice<0 && choice>3) continue;switch(choice){case 1:Check_1();break;case 2:Check_2();break;case 3:Check_3();break;case 0:exit(0);default:break;}}while(1);} …………………………………………………………………………………………………….... Check_1.cpp#include "head.h"#include <stdio.h>void Check_1(){LinkList La,Lb;int n1,n2;printf("请输入单链表La的长度:");scanf("%d",&n1);printf("请按逆位序输入:\n");CreateList_L(&La,n1);printf("La:");PrintLinkList(La);printf("请输入单链表Lb的长度::");scanf("%d",&n2);printf("请按逆位序输入:\n");CreateList_L(&Lb,n2);printf("Lb:");PrintLinkList(Lb);EqualLinkList(&La,&Lb);printf("删除元素以后\n");printf("La:");PrintLinkList(La);printf("Lb:");PrintLinkList(Lb);}CreateList_L.cpp#include<stdio.h>#include "head.h"#include<stdlib.h>void CreateList_L(LinkList *L,int n){//逆位序输入n个元素的值,建立带表头结点的单性线性表L int i;LinkList p;*L=(LinkList)malloc(sizeof(LNode));(*L)->next=NULL;//先建立一个带头结点的单链表for(i=n;i>0;--i){p=(LinkList)malloc(sizeof(LNode));//生成新结点scanf("%d",&(p->data));//输入元素值p->next=(*L)->next;(*L)->next=p;//插入到表头}}EqualLinkList.cpp#include "head.h"#include<stdlib.h>int EqualLinkList(LinkList *La,LinkList *Lb){//删除两单链表中不同的元素LinkList ha,hb,pa,pb;ha=*La;hb=*Lb;pa=ha->next;pb=hb->next;while(pa&&pb){if(pa->data<pb->data){ha->next=pa->next;free(pa);pa=ha->next;}else if(pa->data>pb->data){hb->next=pb->next;free(pb);pb=hb->next;}else {ha=pa;pa=pa->next;hb=pb;pb=pb->next;}}if(pa){ha->next=NULL;free(pa);}else {hb->next=NULL;free(pb);}return 1;}PrintLinkList.cpp#include "head.h"#include<stdio.h>int PrintLinkList(LinkList L){//输出单链表LinkList p=L->next;if(!p)printf("Empty!\n");while(p){printf("%4d",p->data);p=p->next;}printf("\n");return 1;}…………………………………………………………………………………………………….... Check_2.cpp#include "head.h"#include<stdio.h>void Check_2(){int n;LinkList L;printf("请输入猴子的个数:");scanf("%d",&n);CreatCircularLinkList(&L,n);MonkeyKing(L,n);}MonkeyKing.cpp#include "head.h"#include <stdio.h>int MonkeyKing(LinkList L,int n){int m;printf("输入m:");scanf("%d",&m);LinkList p=L,p1=L;while(p1->next!=L)p1=p1->next;int k=n,i=0,j=0;while(i<n-1){j++;if(j==m){p1->next=p->next;j=0;i++;}else p1=p;p=p->next;}printf("%d is the King\n",p1->data);return 1;}CreatCircularLinkList.cpp#include "head.h"#include<stdlib.h>#include<stdio.h>void (LinkList *L,int n){//建一个不带头结点的循环链表,L为头指针int i;LinkList p;*L=(LinkList)malloc(sizeof(LNode));(*L)->next=*L;(*L)->data=1;//printf("input the number of elements of LNode:");//scanf("%d",&n);for(i=n;i>1;--i){p=(LinkList)malloc(sizeof(LNode));//scanf("%d",&(p->data));p->data=i;p->next=(*L)->next;(*L)->next=p;}} ……………………………………………………………………………………………………....#include<stdio.h>#include "head.h"void Check_3(){DuLinkList D;int e,i,choice;printf("请输入非循环双链表的元素的个数:");scanf("%d",&i);CreateLinkList_Dul(&D,i);printf("执行Locate运算前:\n");PrintLinkList_Dul(D);do{printf("请输入要访问元素的值:");scanf("%d",&e);Locate(&D,e);printf("执行Locate运算后:\n");PrintLinkList_Dul(D);printf("输入choice的值,输入1代表继续执行locate,输入0代表退出:\n");scanf("%d",&choice);}while(choice);printf("OK!\n");}Locate.cpp#include "head.h"#include<stdio.h>int Locate(DuLinkList *L,ElemType e){DuLinkList s,t,p=(*L)->next;if(!p) {printf("Error!");return 0;}int i=0,n=LinkListLength_Dul(*L);while(p!=NULL){if(p->data==e){i++;(p->freq)++;printf("频度为%d\n",p->freq);s=p;if(p->next==NULL)p->prior->next=NULL;elsep->next->prior=p->prior;p->prior->next=p->next;}//p=s->next;t=s->prior;while(((t->freq)<(s->freq))&&t!=(*L))t=t->prior;if((t->freq)>=(s->freq)){s->next=t->next;t->next->prior=s;s->prior=t;t->next=s;}else{s->next=(*L)->next;(*L)->next->prior=s;s->prior=(*L);(*L)->next=s;}}p=p->next;}if(i==0){printf("Not found!\n");return 0;}return 1;}CreateLinkList_Dul.cpp#include "head.h"#include<stdlib.h>#include<stdio.h>int (DuLinkList *L,int n){DuLinkList p1,p2;int i;*L=(DuLinkList)malloc(sizeof(DuLNode));(*L)->prior=NULL;(*L)->next=NULL;//(*L)->freq=0;p1=*L;printf("输入元素:\n");for(i=1;i<=n;i++){p2=(DuLinkList)malloc(sizeof(DuLNode));scanf("%d",&(p2->data));p1->next=p2;p2->prior=p1;p2->freq=0;p1=p2;}p2->next=NULL;return 1;}LinkListLength_Dul.cpp#include "head.h"int LinkListLength_Dul(DuLinkList L){DuLinkList p=L->next;int i=0;while(p){i++;p=p->next;}return i;}PrintLinkList_Dul.cpp#include "head.h"#include <stdio.h>int PrintLinkList_Dul(DuLinkList L){DuLinkList p=L->next;if(!p){printf("Empty!");return 0;}while(p){printf("%4d",p->data);p=p->next;}printf("\n");return 1;} ……………………………………………………………………………………………………....。