数据结构与算法单链表的实现演示教学
- 格式:docx
- 大小:11.05 KB
- 文档页数:8
数据结构与算法——单链表的实现及原理1. 单链表的原理 链表是线性表的链式存储⽅式,逻辑上相邻的数据在计算机内的存储位置不必须相邻,那么怎么表⽰逻辑上的相邻关系呢?可以给每个元素附加⼀个指针域,指向下⼀个元素的存储位置。
如图所⽰: 从图中可以看出,每个结点包含两个域:数据域和指针域,指针域存储下⼀个结点的地址,因此指针指向的类型也是结点类型链表的核⼼要素:Ø 每个节点由数据域和指针域组成 Ø 指针域指向下⼀个节点的内存地址。
1.1 结构体定义1 Typedef struct LinkNode2 {3 ElemType data; //节点中存放数据的类型4struct LinkNode* next; //节点中存放下⼀节点的指针5 }LinkList, LinkNode;2. 单链表初始化链表的节点均单向指向下⼀个节点,形成⼀条单向访问的数据链1//单链表的初始化2 typedef struct _LinkNode3 {4int data; //结点的数据域5struct _LinkNode* next; //结点的指针域6 }LinkNode, LinkList; //链表节点、链表78bool InitList(LinkList*& L) //构造⼀个空的单链表 L9 {10 L = new LinkNode; //⽣成新结点作为头结点,⽤头指针 L 指向头结点11if(!L)return false; //⽣成结点失败12 L->next=NULL; //头结点的指针域置空13return true;14 }3. 单链表增加元素 - 单链表前插法插⼊节点的要素就是要找到要插⼊位置的前⼀个节点,将这个节点的Next赋值给新节点,然后将新节点的地址赋值给前⼀个节点的Next便可,任意位置插⼊和前插法均是如此。
1//前插法2bool ListInsert_front(LinkList * &L, LinkNode * node) //参数1 链表指针参数2 要插⼊的节点元素3 {4if (!L || !node) return false; //如果列表或节点为空返回 false5 node->next = L->next; //将头节点指向节点1的地址赋值给要插⼊节点的指针域,使要插⼊的节点先与后部相连6 L->next = node; //将插⼊节点的地址赋值给头结点的指针域,使要插⼊节点与头结点相连78return true;9 }4. 单链表增加元素 - 单链表尾插法1//尾插法2bool ListInsert_back(LinkList*& L, LinkNode* node)3 {4 LinkNode* last = NULL; //创建空指针,5if (!L || !node) return false; //如果列表或节点为空返回 false67 last = L;8while (last->next) last = last->next; //使⽤ last 找到最后⼀个节点910 node->next = NULL; //要插⼊节点由于在尾部,指针域置为 NULL11 last->next = node; //将要插⼊节点的地址赋值给之前的尾部节点的指针域,将要插⼊节点放置到尾部12return true;13 }5. 单链表增加元素 - 单链表任意位置插⼊插⼊节点的要素就是要找到要插⼊位置的前⼀个节点,将这个节点的Next赋值给新节点,然后将新节点的地址赋值给前⼀个节点的Next便可,任意位置插⼊和前插法均是如此。
数据结构-单链表基本操作实现(含全部代码)今天是单链表的实现,主要实现函数如下:InitList(LinkList &L) 参数:单链表L 功能:初始化时间复杂度 O(1)ListLength(LinkList L) 参数:单链表L 功能:获得单链表长度时间复杂度O(n)ListInsert(LinkList &L,int i,ElemType e) 参数:单链表L,位置i,元素e 功能:位置i后插时间复杂度O(n)[加⼊了查找]若已知指针p指向的后插 O(1)ListDelete(LinkList &L,int i) 参数:单链表L,位置i 功能:删除位置i元素时间复杂度O(n)[加⼊了查找]若已知p指针指向的删除最好是O(1),因为可以与后继结点交换数据域,然后删除后继结点。
最坏是O(n),即从头查找p之前的结点,然后删除p所指结点LocateElem(LinkList L,ElemType e) 参数:单链表L,元素e 功能:查找第⼀个等于e的元素,返回指针时间复杂度O(n)代码:/*Project: single linkeed list (数据结构单链表)Date: 2018/09/14Author: Frank YuInitList(LinkList &L) 参数:单链表L 功能:初始化时间复杂度 O(1)ListLength(LinkList L) 参数:单链表L 功能:获得单链表长度时间复杂度O(n)ListInsert(LinkList &L,int i,ElemType e) 参数:单链表L,位置i,元素e 功能:位置i后插时间复杂度O(n)[加⼊了查找]若已知指针p指向的后插 O(1)ListDelete(LinkList &L,int i) 参数:单链表L,位置i 功能:删除位置i元素时间复杂度O(n)[加⼊了查找]若已知p指针指向的删除最好是O(1),因为可以与后继结点交换数据域,然后删除后继结点。
实验截图(1)void InitList(LinkNode *&L)//初始化线性表{L=(LinkNode *)malloc(sizeof(LinkNode)); //创建头结点L->next=NULL;//单链表置为空表}void DestroyList(LinkNode *&L)//销毁线性表{LinkNode *pre=L,*p=pre->next;实验截图(2)bool GetElem(LinkNode *L,int i,ElemType &e) //求线性表中第i个元素值{ int j=0;if (i<=0) return false;//i错误返回假LinkNode *p=L;//p指向头结点,j置为0(即头结点的序号为0) while (j<i && p!=NULL)//找第i个结点p{ j++;p=p->next;}if (p==NULL)//存在值为e的结点,返回其逻辑序号ireturn(i);}实验截图(3)bool ListInsert(LinkNode *&L,int i,ElemType e) //插入第i个元素{ int j=0;if (i<=0) return false;//i错误返回假LinkNode *p=L,*s;//p指向头结点,j置为0(即头结点的序号为0) while (j<i-1 && p!=NULL)//查找第i-1个结点p{ j++;p=p->next;}}实验截图(4)编写exp2-2.cpp程序包含有关代码//文件名:exp2-2.cpp#include "linklist.cpp"int main(){LinkNode *h;ElemType e;printf("单链表的基本运算如下:\n");printf(" (1)初始化单链表h\n");InitList(h);printf(" (2)依次采用尾插法插入a,b,c,d,e元素\n");return 1;}实验截图(5)运行得到结果实验截图(6)。
#include 〈stdio.h>#include <malloc。
h>#include 〈stdlib.h>/*数据结构C语言版线性表的单链表存储结构表示和实现P28—31编译环境:Dev-C++ 4。
9。
9。
2日期:2011年2月10日*/typedef int ElemType;// 线性表的单链表存储结构typedef struct LNode{ElemType data; //数据域struct LNode *next;//指针域}LNode, *LinkList;// typedef struct LNode *LinkList;// 另一种定义LinkList的方法// 构造一个空的线性表Lint InitList(LinkList *L){/*产生头结点L,并使L指向此头结点,头节点的数据域为空,不放数据的。
void *malloc(size_t)这里对返回值进行强制类型转换了,返回值是指向空类型的指针类型.*/(*L)= (LinkList)malloc(sizeof(struct LNode) );if( !(*L))exit(0);// 存储分配失败(*L)-〉next = NULL;// 指针域为空return 1;}// 销毁线性表L,将包括头结点在内的所有元素释放其存储空间。
int DestroyList(LinkList *L){LinkList q;// 由于单链表的每一个元素是单独分配的,所以要一个一个的进行释放while(*L ){q = (*L)—〉next;free(*L );//释放*L = q;}return 1;}/*将L重置为空表,即将链表中除头结点外的所有元素释放其存储空间,但是将头结点指针域置空,这和销毁有区别哦。
不改变L,所以不需要用指针。
*/int ClearList( LinkList L ){LinkList p,q;p = L—〉next;// p指向第一个结点while( p ) // 没到表尾则继续循环{q = p—>next;free( p );//释放空间p = q;}L—>next = NULL; // 头结点指针域为空,链表成了一个空表return 1;}// 若L为空表(根据头结点L—〉next来判断,为空则是空表),则返回1,// 否则返回0.int ListEmpty(LinkList L){if(L—>next ) // 非空return 0;elsereturn 1;}// 返回L中数据元素个数。
- 1 -实验一:实现单链表各种基本运算的算法一、 实验目的1、 掌握单链表存储结构的类型定义;2、 实现单链表各种基本运算的算法。
二、 实验环境1、 Windows 操作系统;2、 Visual C++ 6.0三、 实验内容实现单链表各种基本运算的算法。
四、 概要设计1.存储结构的类型定义:Typedef struct LNode{ElemType data;Struct LNode *next;}LinkList;2.单链表示意图:3.项目组成图:4.algo2_2.cpp 的程序文件包含的函数原型及功能:InitList(LinkList *&L) 初始化单链表LDestroyList(LinkList *&L) 释放单链表LListEmpty(LinkList *L)判断单链表L 是否为空表ListLength(LinkList *L)返回单链表L 的元素个数DispList(LinkList *L)输出单链表LGetElem(LinkList *L,int i,ElemType &e)获取单链表L 的第i 个元素LocateElem(LinkList *L,ElemType e)在单链表L 中查找元素eListInsert(LinkList *&L,int i,ElemType e)在单链表L 中的第i 个位置上插入元素e…… head a 1 a 2 a 3 a n ∧ListDelete(LinkList *&L,int i,ElemType &e)在单链表L中删除第i个元素5.exp2_2.cpp程序文件简介:InitList(LinkList *&L) 初始化单链表LDestroyList(LinkList *&L) 释放单链表LListEmpty(LinkList *L) 判断单链表L是否为空表ListLength(LinkList *L) 返回单链表L的元素个数DispList(LinkList *L) 输出单链表LGetElem(LinkList *L,int i,ElemType &e) 获取单链表L的第i个元素LocateElem(LinkList *L,ElemType e) 在单链表L中查找元素eListInsert(LinkList *&L,int i,ElemType e) 在单链表L中的第i个位置上插入元素e ListDelete(LinkList *&L,int i,ElemType &e) 在单链表L中删除第i个元素6.proj2-2的项目的模块结构:在文件algo2-2中,(1)定义单链表结构类型;(2)初始化单链表(3)定义释放单链表的函数(4)定义判断单链表是否为空的函数(5)定义返回单链表元素个数的函数(6)定义输出单链表的函数(7)定义获取第i个元素的函数(8)定义查找元素的函数(9)定义插入元素的函数(10)定义删除元素的函数在文件exp2-2中分别调用algo2-2中所定义的函数7.函数调用关系图:五、详细设计源代码清单见附录。
数据结构与算法严蔚敏第二版教案课程名称:数据结构与算法教材版本:严蔚敏第二版课程目标:1.理解数据结构的概念和基本操作;2.掌握常用数据结构的实现和应用;3.了解常用算法的设计和分析方法;4.能够灵活运用所学的数据结构和算法解决实际问题。
教学内容和方法:第一阶段:数据结构概述1.数据结构的定义和分类;2.数据结构的基本操作和性质;3.数据结构的存储表示和实现方法。
第二阶段:线性表和链表1.线性表的概念和实现方法;2.顺序表和链表的比较与应用;3.单链表、双链表和循环链表的实现。
第三阶段:栈和队列1.栈的定义和基本操作;2.队列的定义和基本操作;3.栈和队列的应用和实现。
第四阶段:树和二叉树1.树的基本概念和性质;2.树的存储结构和实现方法;3.二叉树的基本性质和遍历方法。
第五阶段:图1.图的概念和分类;2.图的存储结构和实现方法;3.图的遍历和最短路径算法。
第六阶段:查找和排序1.查找的基本概念和方法;2.顺序查找和二分查找的实现;3.排序的基本概念和方法;4.插入排序、冒泡排序和快速排序的实现。
教学方法:1.授课结合实例,注重理论与实践相结合;2.鼓励学生自主学习和思考,提出问题并进行解答;3.运用教学辅助工具,如PPT、代码演示等。
教学过程:第一课时:1.数据结构的概述-引入数据结构的概念和重要性;-分类介绍常用的数据结构;-讲解数据结构的基本操作和性质。
2.数据结构的存储表示和实现方法-简单介绍数据结构的存储方式,如顺序存储和链式存储;-分别讲解顺序表和链表的实现方法;-结合具体例子演示存储表示和实现过程。
第二课时:1.线性表和链表-介绍线性表的概念和特点;-对比顺序表和链表的利弊;-分别讲解单链表、双链表和循环链表的实现方法。
2.应用实例演示-演示线性表和链表在实际问题中的应用;-提供具体例子,让学生动手实现相应的线性表和链表。
第三课时:1.栈和队列-引入栈和队列的概念和基本操作;-讲解栈和队列的应用场景和实现方法。
数据结构实验报告T1223-3-21余帅实验一实验题目:仅仅做链表部分难度从上到下1.双向链表,带表头,线性表常规操作。
2.循环表,带表头,线性表常规操作。
3.单链表,带表头,线性表常规操作。
实验目的:了解和掌握线性表的逻辑结构和链式存储结构,掌握单链表的基本算法及相关的时间性能分析。
实验要求:常规操作至少有:1.数据输入或建立2.遍历3.插入4.删除必须能多次反复运行实验主要步骤:1、分析、理解给出的示例程序。
2、调试程序,并设计输入数据,测试程序的如下功能:1.数据输入或建立2.遍历3.插入4.删除单链表示意图:headhead head 创建删除双向循环链表示意图:创建程序代码://单链表#include<iostream.h>#include<windows.h>const MAX=5;enum returninfo{success,fail,overflow,underflow,range_error}; int defaultdata[MAX]={11,22,33,44,55};class node{public:int data;node *next;};class linklist{private:node *headp;protected:int count;public:linklist();~linklist();bool empty();void clearlist();returninfo create(void);returninfo insert(int position,const int &item);returninfo remove(int position) ;returninfo traverse(void);};linklist::linklist(){headp = new node;headp->next = NULL;count=0;}linklist::~linklist(){clearlist();delete headp;}bool linklist::empty(){if(headp->next==NULL)return true;elsereturn false;}void linklist::clearlist(){node *searchp=headp->next,*followp=headp;while(searchp->next!=NULL){followp=searchp;searchp=searchp->next;delete followp;}headp->next = NULL;count = 0;}returninfo linklist::create(){node *searchp=headp,*newnodep;for(int i=0;i<MAX;i++){newnodep = new node;newnodep->data = defaultdata[i];newnodep->next = NULL;searchp->next = newnodep;searchp = searchp->next;count++;}searchp->next = NULL;traverse();return success;}returninfo linklist::insert(int position,const int &item) //插入一个结点{if(position<=0 || position>=count)return range_error;node *newnodep=new node,*searchp=headp->next,*followp=headp;for(int i=1; i<position && searchp!=NULL;i++){followp=searchp;searchp=searchp->next;}newnodep->data=item; //给数据赋值newnodep->next=followp->next; //注意此处的次序相关性followp->next=newnodep;count++; //计数器加一return success;}returninfo linklist::remove(int position) //删除一个结点{if(empty())return underflow;if(position<=0||position>=count+1)return range_error;node *searchp=headp->next,*followp=headp; //这里两个指针的初始值设计一前一后for(int i=1; i<position && searchp!=NULL;i++){followp=searchp;searchp=searchp->next;}followp->next=searchp->next; //删除结点的实际语句delete searchp; //释放该结点count--; //计数器减一return success;}returninfo linklist::traverse(void){node *searchp;if(empty())return underflow;searchp = headp->next;cout<<"连表中的数据为:"<<endl;while(searchp!=NULL){cout<<searchp->data<<" ";searchp = searchp->next;}cout<<endl;return success;}class interfacebase{public:linklist listface; //定义一个对象Cskillstudyonfacevoid clearscreen(void);void showmenu(void);void processmenu(void);};void interfacebase::clearscreen(void){system("cls");}void interfacebase::showmenu(void){cout<<"================================"<<endl;cout<<" 功能菜单 "<<endl;cout<<" 1.创建链表 "<<endl;cout<<" 2.增加结点 "<<endl;cout<<" 3.删除结点 "<<endl;cout<<" 4.遍历链表 "<<endl;cout<<" 0.结束程序 "<<endl;cout<<"======================================"<<endl;cout<<"请输入您的选择:";}void interfacebase::processmenu(void){int returnvalue,item,position;char menuchoice;cin >>menuchoice;switch(menuchoice) //根据用户的选择进行相应的操作{case '1':returnvalue=listface.create();if(returnvalue==success)cout<<"链表创建已完成"<<endl;break;case '2':cout<<"请输入插入位置:"<<endl;cin>>position;cout<<"请输入插入数据:"<<endl;cin>>item;returnvalue = listface.insert(position,item);if(returnvalue==range_error)cout<<"数据个数超出范围"<<endl;elsecout<<"操作成功!!!"<<endl;break;case '3':cout<<"输入你要删除的位置:"<<endl;cin>>position;returnvalue = listface.remove(position);if(returnvalue==underflow)cout<<"链表已空"<<endl;else if(returnvalue==range_error)cout<<"删除的数据位置超区范围"<<endl;elsecout<<"操作成功!!!"<<endl;break;case '4':listface.traverse();break;case '0':cout<<endl<<endl<<"您已经成功退出本系统,欢迎再次使用!!!"<<endl;system("pause");exit(1);default:cout<<"对不起,您输入的功能编号有错!请重新输入!!!"<<endl;break;}}void main(){interfacebase interfacenow;linklist listnow;system("color f0");interfacenow.clearscreen();while(1){interfacenow.showmenu();interfacenow.processmenu();system("pause");interfacenow.clearscreen();}}/* 功能:用双向循环链表存储数据1.创建链表2.增加结点3.删除结点4.遍历链表制作人:余帅内容:239行*/#include<iostream.h>#include<windows.h>const MAX=5;enum returninfo{success,fail,overflow,underflow,range_error}; int defaultdata[MAX]={11,22,33,44,55};class node{public:int data;node * next; //指向后续节点node * pre; //指向前面的节点};class linklist{private:node *headp;protected:int count;public:linklist();~linklist();bool empty();void clearlist();returninfo create(void);returninfo insert(int position,const int &item);returninfo remove(int position) ;returninfo traverse(void);};linklist::linklist(){headp = new node;headp->next = NULL;headp->pre = NULL;count=0;}linklist::~linklist(){clearlist();delete headp;}bool linklist::empty(){if(headp->next==NULL)return true;elsereturn false;}void linklist::clearlist(){node *searchp=headp->next,*followp=headp;while(searchp->next!=NULL){followp=searchp;searchp=searchp->next;delete followp;}headp->next = NULL;headp->pre = NULL;count = 0;}returninfo linklist::create(){node *searchp=headp,*newnodep;for(int i=0;i<MAX;i++){newnodep = new node;newnodep->data = defaultdata[i];newnodep->next = NULL;searchp->next = newnodep;newnodep->pre = searchp;searchp = searchp->next;count++;}searchp->next = headp;headp->pre = searchp;traverse();return success;}returninfo linklist::insert(int position,const int &item) //插入一个结点{if(position<=0 || position>count+1)return range_error;node *newnodep=new node;node *searchp=headp->next,*followp=headp;for(int i=1; i<position && searchp!=NULL;i++){followp=searchp;searchp=searchp->next;}newnodep->data=item; //给数据赋值newnodep->next = searchp;searchp->pre = newnodep;followp->next = newnodep;newnodep->pre = followp;count++; //计数器加一return success;}returninfo linklist::remove(int position) //删除一个结点{if(empty())return underflow;if(position<=0||position>=count+1)return range_error;node *searchp=headp->next,*followp=headp; //这里两个指针的初始值设计一前一后for(int i=1; i<position && searchp!=NULL;i++){followp=searchp;searchp=searchp->next;}followp->next=searchp->next; //删除结点的实际语句searchp->next->pre = followp;delete searchp; //释放该结点count--; //计数器减一return success;}returninfo linklist::traverse(void){node *searchp1,*searchp2;if(empty())return underflow;searchp1 = headp;searchp2 = headp;cout<<"连表中的数据为:"<<endl;cout<<"从左至右读取:";while (searchp1->next!=headp ) {searchp1 = searchp1 ->next;cout << searchp1->data<<" ";}cout<<endl;cout<<"从右至左读取:";while (searchp2->pre!=headp ) {searchp2 = searchp2 ->pre;cout << searchp2->data<<" ";}cout<<endl;return success;}class interfacebase{public:linklist listface; //定义一个对象Cskillstudyonface void clearscreen(void);void showmenu(void);void processmenu(void);};void interfacebase::clearscreen(void){system("cls");}void interfacebase::showmenu(void){cout<<"================================"<<endl;cout<<" 功能菜单 "<<endl;cout<<" 1.创建链表 "<<endl;cout<<" 2.增加结点 "<<endl;cout<<" 3.删除结点 "<<endl;cout<<" 4.遍历链表 "<<endl;cout<<" 0.结束程序 "<<endl;cout<<"======================================"<<endl;cout<<"请输入您的选择:";}void interfacebase::processmenu(void){int returnvalue,item,position;char menuchoice;cin >>menuchoice;switch(menuchoice) //根据用户的选择进行相应的操作{case '1':returnvalue=listface.create();if(returnvalue==success)cout<<"链表创建已完成"<<endl;break;case '2':cout<<"请输入插入位置:"<<endl;cin>>position;cout<<"请输入插入数据:"<<endl;cin>>item;returnvalue = listface.insert(position,item);if(returnvalue==range_error)cout<<"数据个数超出范围"<<endl;elsecout<<"操作成功!!!"<<endl;break;case '3':cout<<"输入你要删除的位置:"<<endl;cin>>position;returnvalue = listface.remove(position);if(returnvalue==underflow)cout<<"链表已空"<<endl;else if(returnvalue==range_error)cout<<"删除的数据位置超区范围"<<endl;elsecout<<"操作成功!!!"<<endl;break;case '4':listface.traverse();break;case '0':cout<<endl<<endl<<"您已经成功退出本系统,欢迎再次使用!!!"<<endl;system("pause");exit(1);default:cout<<"对不起,您输入的功能编号有错!请重新输入!!!"<<endl;break;}}void main(){interfacebase interfacenow;linklist listnow;system("color f0");interfacenow.clearscreen();while(1){interfacenow.showmenu();interfacenow.processmenu();system("pause");interfacenow.clearscreen();}}运行结果:1.创建链表:2.增加结点3.删除结点心得体会:本次实验使我们对链表的实质了解更加明确了,对链表的一些基本操作也更加熟练了。
单链表的建立、增加元素、删除元素、查找元素算法
单链表是一种常用的数据结构,由一个个节点构成,每个节点包含一个数据域和一个指向下一个节点的指针。
本文将介绍单链表的建立、增加元素、删除元素、查找元素算法。
一、单链表的建立
单链表的建立需要创建一个头结点,它不存储数据,只有一个指针域指向第一个节点。
接下来,我们用一个循环语句不断读入数据,创建新节点并将其插入到链表中。
二、单链表的增加元素
单链表的增加元素有两种情况,一种是在链表头插入新节点,另一种是在链表尾插入新节点。
在头部插入新节点时,需要先创建新节点,将它的指针域指向原来的头结点,再让头结点指向新节点;在尾部插入新节点时,需要先遍历整个链表找到最后一个节点,再将新节点插入到最后一个节点的后面。
三、单链表的删除元素
单链表的删除元素也有两种情况,一种是删除链表头的节点,另一种是删除链表中指定位置的节点。
在删除头结点时,需要先找到头结点的下一个节点,将其指针域赋给头结点,然后释放原来的头结点;在删除指定位置的节点时,需要先找到该节点的前一个节点,将前一个节点的指针域指向该节点的下一个节点,然后释放要删除的节点。
四、单链表的查找元素
单链表的查找元素有两种情况,一种是查找指定位置的节点,另
一种是查找指定数据域的节点。
在查找指定位置的节点时,需要遍历整个链表找到该位置的节点;在查找指定数据域的节点时,需要遍历整个链表找到数据域与目标值相等的节点。
单链表的实现实现单链表的基本操作,必须包括初始化链表( 元素为空) 、销毁链表、求表长、查找、插入、删除、遍历(打印)等操作。
请编写程序,实现上述单链表的基本操作。
注意: 1. 元素类型可以自定义2. 可以是带头结点的单链表或不带头结点的单链表#include<stdio.h>#include<stdlib.h> #include<string.h>typedef int datatype;typedef struct node{datatype data;struct node *next; }LNode,*LinkList;/*//创建不带头结点的单链表Linklist Create_LinkList(){return NULL;}*///创建带头结点的单链表LinkList Create_LinkList(){LinkList L=NULL;L=(LinkList)malloc(sizeof(LNode));if(L)L->next=NULL;return L;}//打印单链表void Print_LinkList(LinkList H){if(H == NULL){printf("?????????\n");}else{printf("head-->");LinkList p=H->next;while(p!=NULL){printf("%d",p->data);printf("-->"); p=p->next;}printf("\n");}}//销毁单链表void Destroy_LinkList(LinkList *H){LinkList p, q; p = *H;while(p){q = p;p = p->next; free(q);} *H = NULL;if(*H==NULL)printf(" 销毁成功,请退出\n"); elseprintf(" 销毁失败\n");}//求表长int Length_LinkList(LinkList L){LNode *p=L;int j=0;while(p->next){p=p->next;j++;}return j;}//表长功能实现void length(LinkList L){int i=0;i=Length_LinkList(L);printf(" 表长:%d\n",i);}//查找操作//1)按序号查找LNode * Get_LinkList1(LinkList L,int i) {LNode *p=L;int j=0;while(p->next!=NULL&&j<i){p=p->next;j++;}if(j==i)return p;elsereturn NULL;}//2)按值查找即定位int Locate_LinkList2(LinkList L,datatype x) {LNode *p=L;int i=0;while(p->data!=x){p=p->next;i++;}return i;}//查找功能实现void find(LinkList L){int i,n;LNode *p,*s;datatype x;printf(" 选择下列功能\n");printf("\t1) 按序号查找\n");printf("\t2) 按值查找即定位\n");scanf("%d",&i);switch(i){case 1:printf(" 请输入第几个元素:"); scanf("%d",&n); p=Get_LinkList1(L,n);if(p==NULL)printf(" 查找失败\n");elseprintf(" 您所查找的元素为:%d\n",p->data);break;case 2:printf(" 请输入元素值:"); scanf("%d",&x); i=Locate_LinkList2(L,x);if(i!=0)printf(" 第%d 个元素\n",i); elseprintf(" 查找失败\n");break;}}//插入int Insert_LinkList(LinkList L,int i,datatype x) {LNode *p,*s;p=Get_LinkList1(L,i-1);if(p= =NULL){printf(" 参数i 错\n"); return 0;}else{s=(LNode *)malloc(sizeof(LNode));s->data=x;s->next=p->next;p->next=s;}return 1;}//插入功能实现void Insert(LinkList L) {LNode *p=L; datatype x;int i,a=1;printf(" 请输入要插入的数:"); scanf("%d",&x);printf(" 请输入要插入的位置:"); scanf("%d",&i);a=Insert_LinkList(L,i,x);if(a==1)printf(" 插入成功\n");elseprintf(" 插入失败\n");}//删除int Del_LinkList(LinkList L,int i){LinkList p,s; p=Get_LinkList1(L,i-1);if(p==NULL){printf(" 第i-1 个结点不存在\n");return -1;}else{if(p->next==NULL){printf(" 第i 个结点不存在\n"); return 0;}else{s=p->next; p->next=s->next; free(s);return 1;}}}//删除功能实现void del(LinkList L){ datatype x; int i,j,n,k; LNode *p;printf(" 选择下列功能\n"); printf("\t1) 按序号删除\n");printf("\t2) 按元素值删除\n");scanf("%d",&i);switch(i) { case 1:printf(" 请输入第几个元素:"); scanf("%d",&n); k=Del_LinkList(L,n);if(k!=1) printf(" 删除失败\n");else printf(" 删除成功\n");break;case 2: printf(" 请输入元素值:"); scanf("%d",&x); i=Locate_LinkList2(L,x);j=Del_LinkList(L,i);if(j!=1) printf(" 删除失败\n");else printf(" 删除成功\n");break; }}//初始化链表(元素为空)、销毁链表、求表长、查找、插入、删除、遍历(打印)等操作//main 函数void printChoice(){printf("\n 请选择功能:\n"); printf("\t1. 表长\n"); printf("\t2. 查找\n"); printf("\t3. 插入\n");printf("\t4. 删除\n"); printf("\t5. 打印\n"); printf("\t6. 销毁链表\n");}int main(){LinkList L=Create_LinkList();int choice=-1;while(1){ printChoice(); scanf("%d",&choice);switch(choice){case 1:length(L);break;case 2:find(L);break;case 3:Insert(L);break;case 4:del(L);break;case 5:Print_LinkList(L);break;Destroy_LinkList(&L); break; printf(" 输入错误 ");break;case 6:default:。