单链表的构造、插入和删除完整程序

合集下载

数据结构单链表插入、删除和修改实验报告

数据结构单链表插入、删除和修改实验报告

计算机学院实验报告课程名称:数据结构实验名称:单链表学生姓名:***学生学号:***********实验日期: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为第一个元素地址,可返回头结点进行重新遍历和查找。

线性表的存储结构定义及基本操作

线性表的存储结构定义及基本操作

一、实验目的:. 掌握线性表的逻辑特征. 掌握线性表顺序存储结构的特点,熟练掌握顺序表的基本运算. 熟练掌握线性表的链式存储结构定义及基本操作. 理解循环链表和双链表的特点和基本运算. 加深对顺序存储数据结构的理解和链式存储数据结构的理解,逐步培养解决实际问题的编程能力二、实验内容:(一)基本实验内容(顺序表):建立顺序表,完成顺序表的基本操作:初始化、插入、删除、逆转、输出、销毁, 置空表、求表长、查找元素、判线性表是否为空;1.问题描述:利用顺序表,设计一组输入数据(假定为一组整数),能够对顺序表进行如下操作:. 创建一个新的顺序表,实现动态空间分配的初始化;. 根据顺序表结点的位置插入一个新结点(位置插入),也可以根据给定的值进行插入(值插入),形成有序顺序表;. 根据顺序表结点的位置删除一个结点(位置删除),也可以根据给定的值删除对应的第一个结点,或者删除指定值的所有结点(值删除);. 利用最少的空间实现顺序表元素的逆转;. 实现顺序表的各个元素的输出;. 彻底销毁顺序线性表,回收所分配的空间;. 对顺序线性表的所有元素删除,置为空表;. 返回其数据元素个数;. 按序号查找,根据顺序表的特点,可以随机存取,直接可以定位于第i 个结点,查找该元素的值,对查找结果进行返回;. 按值查找,根据给定数据元素的值,只能顺序比较,查找该元素的位置,对查找结果进行返回;. 判断顺序表中是否有元素存在,对判断结果进行返回;. 编写主程序,实现对各不同的算法调用。

2.实现要求:对顺序表的各项操作一定要编写成为C(C++)语言函数,组合成模块化的形式,每个算法的实现要从时间复杂度和空间复杂度上进行评价;. “初始化算法”的操作结果:构造一个空的顺序线性表。

对顺序表的空间进行动态管理,实现动态分配、回收和增加存储空间;. “位置插入算法”的初始条件:顺序线性表L 已存在,给定的元素位置为i,且1≤i≤ListLength(L)+1 ;操作结果:在L 中第i 个位置之前插入新的数据元素e,L 的长度加1;. “位置删除算法”的初始条件:顺序线性表L 已存在,1≤i≤ListLength(L) ;操作结果:删除L 的第i 个数据元素,并用e 返回其值,L 的长度减1 ;. “逆转算法”的初始条件:顺序线性表L 已存在;操作结果:依次对L 的每个数据元素进行交换,为了使用最少的额外空间,对顺序表的元素进行交换;. “输出算法”的初始条件:顺序线性表L 已存在;操作结果:依次对L 的每个数据元素进行输出;. “销毁算法”初始条件:顺序线性表L 已存在;操作结果:销毁顺序线性表L;. “置空表算法”初始条件:顺序线性表L 已存在;操作结果:将L 重置为空表;. “求表长算法”初始条件:顺序线性表L 已存在;操作结果:返回L 中数据元素个数;. “按序号查找算法”初始条件:顺序线性表L 已存在,元素位置为i,且1≤i≤ListLength(L)操作结果:返回L 中第i 个数据元素的值. “按值查找算法”初始条件:顺序线性表L 已存在,元素值为e;操作结果:返回L 中数据元素值为e 的元素位置;. “判表空算法”初始条件:顺序线性表L 已存在;操作结果:若L 为空表,则返回TRUE,否则返回FALSE;分析: 修改输入数据,预期输出并验证输出的结果,加深对有关算法的理解。

JAVA数据结构——单链表的操作

JAVA数据结构——单链表的操作

单链表的操作方法一:package ch02;(1)建立结点类Node.javapublic class Node {public Object data;//存放结点数据值public Node next;//存放后继结点//无参构造函数public Node(){ this(null,null);}//只有结点值的构造函数public Node(Object data){ this(data,null);}//带有节点值和后继结点的构造函数public Node(Object data,Node next){ this.data=data;this.next=next;}}(2)建立链表及操作LinkList.javapackage ch02;import java.util.Scanner;public class LinkList implements IList{public Node head;//单链表的头指针//构造函数初始化头结点public LinkList(){head=new Node();}//构造函数构造长度为n的单链表public LinkList(int n,boolean Order) throws Exception{ this();if(Order)create1(n); //头插法顺序建立单链表elsecreate2(n); //尾插法逆序建立单链表}//头插法顺序建立单链表public void create1(int n) throws Exception{Scanner sc=new Scanner(System.in);System.out.println("请输入结点的数据(头插法):”);for(int i=0;i<n;i++){insert(0,sc.next());}}//尾插法逆序建立单链表public void create2(int n) throws Exception{Scanner sc=new Scanner(System.in);System. out.println("请输入结点的数据(尾插法):");for(int i=0;i<n;i++){insert(length(),sc.next());}}//将链表置空public void clear(){head.data=null;head.next=null;}//判断链表是否为空public boolean isEmpty(){return head.next==null;}//返回链表长度public int length(){Node p=head.next;int length=0;while(p!=null){p=p.next;length++;//返回P不空长度length加1}return length;}//读取并返回第i个位置的数据元素public Object get(int i) throws Exception {Node p=head.next;int j;//从首结点开始向后查找,直到9指向第i个结点或者p为nullfor(j=0;j<i&&p!=null;j++){ p=p.next;}if(j>i||p==null)//i不合法时抛出异常throw new Exception("第"+i+”个数据元素不存在”);return p.data;}//插入乂作为第i个元素public void insert(int i, Object x) throws Exception{ Node p=head;int j=-1;//寻找第i个结点的前驱i-1while(p!=null&&j<i-1){p=p.next;j++;}if(j>i-l||p==null)//i不合法时抛出异常throw new Exception("插入位置不合法”);Node s=new Node(x);s.next=p.next;p.next=s;}//删除第i个元素public void remove(int i) throws Exception{ Node p=head;int j=-1;while(p!=null&&j<i-1){//寻找第i-1 个节点p=p.next;j++;}if(j>i-1||p.next==null)throw new Exception("删除位置不合法”);p.next=p.next.next;}//返回元素x首次出现的位序号public int indexOf(Object x) {Node p=head.next;int j=0;while(p!=null&&!p.data.equals(x)){p=p.next;j++;if(p!=null)return j;elsereturn -1;}public void display(){Node p=head.next;while(p!=null){if(p.next==null)System.out.print(p.data);elseSystem.out.print(p.data+"f );p=p.next;}}}(3)建立测试类Test.javappublic class test {public static void main(String[] args) throws Exception { // TODO Auto-generated method stubScanner sc=new Scanner(System.in);boolean or;int xz,xx;System.out.println("请选择插入的方法:0、头插法,1、尾插法");xz=sc.nextInt();if(xz!=0)or=true;elseor=false;System. out.println("请插入的结点的个数:”);xx=sc.nextInt();LinkList L=new LinkList(xx,or);System.out.println("建立的链表为:");L.display();System.out.println();System.out.println("链表的长度:"+L.length());System. out.println(”请输入查找的结点的数据:”);Object x=sc.next();int position=L.indexOf(x);System.out.println("结点的数据为:"+x+"的位置为:"+position); System. out.println("请输入删除的结点的位置:”);int sr=sc.nextInt();L.remove(sr);L.display();System.out.println();System.out.println("链表的长度:"+L.length()); }品P rob I em & J a vs d oc / Declaration Q Error Log 里Con sole-M、、■=:termin8ted> test [3] [Java Application] C U &ert\Ad im i n i st rat o r\Ap p Data\L o cs I请选择插入.的方法:0、头插法,lv星插法请插入的特点的个数:请愉入结点的颓据(尾插法):A B C E D F建立的旌表为;A+B T C+E T D+F链表的长度:6请输入查找的结点的数据:结点的数据为:E的位置为:3请输入删除的结点的位置,R+B T E+DW道表的长度:S方法二(引入get和set方法)Package sy;import java.util.Scanner;//单链表的结点类public class Node {private Object data; //存放结点值private Node next; //后继结点的引用public Node() { //无参数时的构造函数this(null, null);}public Node(Object data) { // 构造值为data 的结点this(data, null);}public Node(Object data, Node next) {//构造值为data 和next 的结点构造函数this.data = data;this.next = next;}public Object getData() { return data;}public void setData(Object data) {this.data = data;}public Node getNext() { return next;public void setNext(Node next) { this.next = next;}}//实现链表的基本操作类public class LinkList {Node head=new Node();//生成一个带头结点的空链表//根据输入的一系列整数,以0标志结束,用头插法建立单链表public void creat() throws Exception {Scanner sc = new Scanner(System.in); //构造用于输入的对象for (int x=sc.nextInt(); x!=0; x=sc.nextInt()) //输入若干个数据元素的值(以0结束) insert(0, x);//生成新结点,插入到表头}//返回带头结点的单链表中第i个结点的数据域的值。

数据库 线性表题库

数据库 线性表题库

一、单项选择题1、线性表的静态链表存储结构与顺序存储结构相比优点是()A、所有的操作算法实现简单 B 便于随机存取B、C便于插入和删除 D便于利用零散的存储器空间2、将下图所示的s所指结点加到p所指结点之后,其语句应为:()A s->next=p+1;p->next=s;B (*p).next=s;(*s).next=(*p).next;C s->next=p->next;p->next=s->next;D s->next=p->next;p->next=s;3、不带头结点的单链表head为空的判定条件是()A head= =NULLB head->next= =NULLC head->next= =headD head!=NULL4、带头结点的单链表head为空的判定条件是()A head= =NULLB head->next= =NULLC head->next= =headD head!=NULL5、在一个单链表中,已知q所指结点是p所指结点的前驱结点,若在q和p之间插入s结点,则执行语句()A s->next=p->next;p->next=s;B p->next=s->next;s->next=p;C q->next=s;s->next=p;D p->next=s;s->next=q;6、在一个单链表中,若p所指结点不是最后结点,在p之后插入s结点,则应执行语句()A s->next=p:p->next=s;B s->next=p->next;p->next=s;C s->next=p->next;p=s;D p->next=s;s->next=p;7、在一个单链表中,若删除p所指结点的后续结点,则应执行语句()A p->next=p->next->next;B p=p->next;p->next=p->next->next;C p->next=p->next;D p=p->next->next;8、从一个具有n个结点的单链表中查找其值等于x结点时,在查找成功的情况下,需平均比较__个结点()A nB n/2C (n-1)/2D (n+1)/29、数据在计算机存储器内表示时,物理地址与逻辑地址相同并且是连续的,称之为:(A)存储结构(B)逻辑结构(C)顺序存储结构(D)链式存储结构10、一个向量第一个元素的存储地址是100,每个元素的长度为2,则第5个元素的地址是(A)110 (B)108 (C)100 (D)12011、在n个结点的顺序表中,算法的时间复杂度是O(1)的操作是:(A)访问第i个结点(1≤i≤n)和求第i个结点的直接前驱(2≤i≤n)(B)在第i个结点后插入一个新结点(1≤i≤n)(C)删除第i个结点(1≤i≤n)(D)将n个结点从小到大排序12、向一个有127个元素的顺序表中插入一个新元素并保持原来顺序不变,平均要移动个元素(A)8 (B)63.5 (C)63 (D)713、链接存储的存储结构所占存储空间:(A)分两部分,一部分存放结点值,另一部分存放表示结点间关系的指针(B)只有一部分,存放结点值(C)只有一部分,存储表示结点间关系的指针(D)分两部分,一部分存放结点值,另一部分存放结点所占单元数14、链表是一种采用存储结构存储的线性表;(A)顺序(B)链式(C)星式(D)网状15、线性表若采用链式存储结构时,要求内存中可用存储单元的地址:(A)必须是连续的(B)部分地址必须是连续的(C)一定是不连续的(D)连续或不连续都可以16、线性表L在情况下适用于使用链式结构实现。

数据结构C语言版 线性表的单链表存储结构表示和实现

数据结构C语言版 线性表的单链表存储结构表示和实现

#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. 数据是__信息__的载体,它能够被计算机程序识别、存储和加工处理。

2. 数据结构包括逻辑结构、__存储结构__和数据的运算三个方面。

3. 数据结构的逻辑结构包括线性结构和__非线性__结构两大类。

4. 数据结构的存储结构包括顺序、__链接___、索引和散列等四种。

5. 基本数据类型是计算机已经实现了的_数据结构__。

6. 抽象数据类型的特点是__数据封装__、信息隐蔽、使用与实现分离。

7. 算法的一个特性是__有穷性__,即算法必须执行有限步就结束。

8. 面向对象的特征应包括对象、类、__继承__、消息通信。

9. 属性与服务相同的对象构成类,类中的每个对象称为该类的__实例__。

10. 对象的私有状态只能通过该对象的__操作(或服务)_才能改变。

11. 模板类是一种数据抽象,它把__数据类型_当作参数,可以实现类的复用。

12. 在类的继承结构中,位于上层的类叫做基类,其下层的类则叫做__派生(或子)__类。

13. 一维数组所占用的空间是连续的。

但数组元素不一定顺序存取,通常是按元素的__下标(或顺序号)__存取的。

14. 在程序运行过程中不能扩充的数组是__静态__分配的数组。

这种数组在声明它时必须指定它的大小。

15. 在程序运行过程中可以扩充的数组是__动态___分配的数组。

这种数组在声明它时需要使用数组指针。

16. 二维数组是一种非线性结构,其中的每一个数组元素最多有__两个__个直接前驱(或直接后继)。

17. 若设一个n n的矩阵A的开始存储地址LOC(0, 0) 及元素所占存储单元数d已知,按行存储时其任意一个矩阵元素a[i][j]的存储地址为__ LOC(0,0)+(i*n+j)*d__。

18. 对称矩阵的行数与列数__相等_且以主对角线为对称轴,a ij = a ji,因此只存储它的上三角部分或下三角部分即可。

19. 将一个n阶对称矩阵的上三角部分或下三角部分压缩存放于一个一维数组中,则一维数组需要存储__n(n+1)/2 _个矩阵元素。

实验二 单链表基本操作

实验二 单链表基本操作

实验二单链表基本操作一实验目的1.学会定义单链表的结点类型,实现对单链表的一些基本操作和具体的函数定义,了解并掌握单链表的类定义以及成员函数的定义与调用。

2.掌握单链表基本操作及两个有序表归并、单链表逆置等操作的实现。

二实验要求1.预习C语言中结构体的定义与基本操作方法。

2.对单链表的每个基本操作用单独的函数实现。

3.编写完整程序完成下面的实验内容并上机运行。

4.整理并上交实验报告。

三实验内容1.编写程序完成单链表的下列基本操作:(1)初始化单链表La。

(2)在La中第i个元素之前插入一个新结点。

(3)删除La中的第i个元素结点。

(4)在La中查找某结点并返回其位置。

(5)打印输出La中的结点元素值。

2 .构造两个带有表头结点的有序单链表La、Lb,编写程序实现将La、Lb合并成一个有序单链表Lc。

合并思想是:程序需要3个指针:pa、pb、pc,其中pa,pb分别指向La表与Lb表中当前待比较插入的结点,pc 指向Lc表中当前最后一个结点。

依次扫描La和Lb中的元素,比较当前元素的值,将较小者链接到*pc 之后,如此重复直到La或Lb结束为止,再将另一个链表余下的内容链接到pc所指的结点之后。

3.构造一个单链表L,其头结点指针为head,编写程序实现将L逆置。

(即最后一个结点变成第一个结点,原来倒数第二个结点变成第二个结点,如此等等。

)四思考与提高1.如果上面实验内容2中合并的表内不允许有重复的数据该如何操作?2.如何将一个带头结点的单链表La分解成两个同样结构的单链表Lb,Lc,使得Lb中只含La表中奇数结点,Lc中含有La表的偶数结点?1.编写程序完成单链表的下列基本操作:(1)初始化单链表La。

(2)在La中第i个元素之前插入一个新结点。

(3)删除La中的第i个元素结点。

(4)在La中查找某结点并返回其位置。

(5)打印输出La中的结点元素值。

#include<stdio.h>#include<stdlib.h>#include <malloc.h>#define OK 1#define ERROR 0typedef int Status;typedef int ElemType;//定义存储结构typedef struct Lnode{int data; /*每个元素数据信息*/struct Lnode *next; /*存放后继元素的地址*/} LNode,*LinkList;int main(){void Create_L(LinkList &L,int n);void Print_L(LinkList L);Status ListInsert_L(LinkList &L,int i,ElemType e);Status ListDelete_L(LinkList &L,int i,ElemType &e);Status Find_L(LinkList L,int e);LinkList La;//创建单链表Laint n;printf("请输入链表La中的元素个数:\n");scanf("%d",&n);Create_L(La,n);//初始化单链表printf("现在La中的元素为:\n");Print_L(La);printf("-------------------------------------\n\n");printf("现在准备插入元素,请输入插入位置及所插入元素的值\n");int i,e;scanf("%d %d",&i,&e);ListInsert_L(La,i,e);printf("插入后La中的元素为:\n");Print_L(La);printf("-------------------------------------\n\n");printf("现在准备删除元素,请输入删除位置\n");scanf("%d",&i);ListDelete_L(La,i,e);printf("删除后La中的元素为:\n");Print_L(La);printf("-------------------------------------\n\n");printf("请输入所要查找元素的值:\n");scanf("%d",&e);Find_L(La,e);printf("所要查找元素的位置为:%d\n",Find_L(La,e)); }void Create_L(LinkList &L,int n){int j=1;L=(LinkList)malloc(sizeof(Lnode));L->next =NULL;//先建立一个带头结点的单链线性表L for(int i=n;i>0;--i){LinkList p=(LinkList)malloc(sizeof(Lnode));printf("请输入链表La中的第%d个元素:\n",j++);scanf("%d",&p->data);p->next=L->next;L->next =p;}//(逆序实现)/*LinkList q=L;for(int i=1;i<=n;i++){LinkList p=(LinkList)malloc (sizeof(Lnode));q->next=p;p->next=NULL;q=q->next ;printf("请输入链表La中的第%d个元素:\n",i);scanf("%d",&p->data);}//(正序实现)*/}//初始化单链表//输出单链表void Print_L(LinkList L){LinkList p;p=L->next;while(p){printf("%d ",p->data );p=p->next;}printf("\n");}//在单链表L的第i个位置前插入元素eStatus ListInsert_L(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=(LinkList)malloc(sizeof(LNode));s->data=e; s->next=p->next;p->next=s;return OK;} //ListInsert_L//删除单链表L中第i个位置上的元素Status ListDelete_L(LinkList &L,int i,ElemType &e) {LinkList p=L;int j=0;while( p->next && j<i-1){p=p->next; ++j;}if(!p->next||j>i-1) return ERROR;LinkList q=p->next; p->next=q->next;e=q->data;free(q);return OK;}//LinkDelete_L/*查找元素并返回位置*/Status Find_L(LinkList L,int e){LinkList p=L->next;int j=1;while(p->data!=e&&p->next){p=p->next;j++;}if(p->data==e) return j;else{printf("无当前元素\n");return ERROR;}if(!p){printf("无当前元素\n");return ERROR;}}//定位2 .构造两个带有表头结点的有序单链表La、Lb,编写程序实现将La、Lb合并成一个有序单链表Lc。

链表

链表

ListNode<Type> *GetNode ( const Type& item, ListNode<Type> *next ); //创建数据为item,指针为next的新结点 void InsertAfter ( ListNode<Type> *p ); //在当前结点后插入结点p ListNode<Type> *RemoveAfter ( ); //摘下当前结点的下一结点 };
单链表的存储映像
单链表的类定义
• 多个类表达一个概念(单链表)。
– 链表结点(ListNode)类 – 链表(List)类 – 链表游标(Iterator)类
链表类定义(复合方式)
class List; class ListNode { //链表结点类 friend class List; //链表类为其友元类 private: int data; //结点数据, 整型 ListNode *link; //结点指针 }; class List { //链表类 public: //链表公共操作 ……… private: ListNode *first, *last; //表头和表尾指针 };
单链表中的插入与删除 • 插入

第一种情况:在第一个结点前插入
newnode→link = first ; first = newnode;
newnode first newnode first
(插入前)
(插入后)
– 第二种情况:在链表中间插入
newnode→link = p→link;
p→link = newnode;
}
• 删除
– 第一种情况: 删除表中第一个元素 – 第二种情况: 删除表中或表尾元素

单链表的建立、插入和删除

单链表的建立、插入和删除

单链表的建立、插入和删除单链表的建立插入删除#include<stdio.h>#include<stdlib.h>/*线性表*/struct TLink {int data;struct TLink * next;};/*end struct TLink*//*生成新元素*/struct TLink * new_item(int number){struct TLink * r = 0;r = (struct TLink *)malloc(sizeof(struct TLink));r->data = number;r->next = 0;return r;}/*end new_item*//*在线性表中查询数据*/struct TLink * lookup(struct TLink * root, int number) {struct TLink * h = root;while(h) {if (h->data == number) return h;h = h->next ;}/*end lookup*/return 0;}/*在线性表中追加一个数据*/void append(struct TLink * * root, int number){struct TLink * r = 0, * n = 0;if (!root) return ;/*不记录重复元素*/if (lookup(*root, number)) return;/*如果表为空则新建表*/r = *root;if (!r) {*root = new_item(number);return ;}/*end if*//*为保证为有序线性表,如果数据比表头还小则作为表头*/ if (number < r->data ) {n = new_item(number);n->next = r;*root = n;return ;}/*end if*//*在有序线性表中查找位置插入元素*/while(r) {n = r->next ;/*如果已经是表尾则直接追加*/if (!n) {n = new_item(number);r->next = n;return ;}/*end if*//*在中央某处插入*/if (number < n->data ) {r->next = new_item(number);r->next->next = n;return ;}/*end if*/r = n;}/*end while*/}/*end append*//*打印有序线性表*/void print(struct TLink * root){struct TLink * r = root;printf("【");while(r) {printf("%d ", r->data );r = r->next ;}/*end while*/printf("\b】\n");}/*end print*//*将有序线性表h1合并至有序线性表h0,并销毁线性表h1*/ void merge(struct TLink ** h0, struct TLink ** h1){struct TLink * h = 0, * k = 0;if (!h0 || !h1) return ;h = *h1;while(h) {append(h0, h->data );k = h;h = h->next ;free(k);}/*end h*/h1 = 0;}int main(void){int i = 0; struct TLink * x=0, *y = 0;int a[] = {8,4,3,9,5,1};int b[] = {7,2,1,5,6,0};printf("原数据为:\n数组A:【");for(i = 0; i < 6; i++) {printf("%d ", a[i]);append(&x, a[i]);}/*next*/printf("\b】\n数组B:【");for(i = 0; i < 6; i++) {printf("%d ", b[i]);append(&y, b[i]);}/*next*/printf("\b】\n转换为有序线性表\nA:");print(x);printf("B:");print(y);printf("AB合并后为:");merge(&x, &y);print(x);return 0;}。

数据结构实验,线性表的插入和删除,单链表操作,Huffman编码树

数据结构实验,线性表的插入和删除,单链表操作,Huffman编码树
2.上机输入、调试实验程序;
{ int i,j,k,x1,x2,m1,m2;
for(i=1;i<(2*n);i++)
{ t[i].pa=t[i].lc=t[i].rc=0;
if(i<=n)
t[i].data=w[i];
else
t[i].data=0;
}
for(i=1;i<n;i++)
{ m1=m2=MAX;
x1=x2=0;
for(j=1;j<(n+i);j++)
ListCount=0;
int nOperateState;
while(TRUE)
{
printf( "选择你要操作的方法,1为插入,2为删除,3为查询!4为退出\r\n ");
scanf("%d",&nOperateState);
switch(nOperateState)
{
case 1:
InsertInfo();
{
printf("请不要重复插入相同学号的信息\r\n");
LocalFree(Info);
return;
}
ptemp=ptemp->pNext;
}
}
if (ListHead)
{
if (ListCount==1)
{
ListTail=Info;
ListTail->pNext=NULL;
ListHead->pNext=ListTail;
temp->stu_num,temp->stu_age,temp->stu_english_grade);

链表的常见操作

链表的常见操作

链表的常见操作
链表是一种常见的数据结构,其存储元素的个数是不受限定的,当要添加更多元素时,存储的个数会随之增加。

链表的操作包括但不限于以下几种:
1. 创建:链表的创建包括初始化链表、分配内存空间等操作。

2. 插入:在链表的指定位置插入一个元素。

3. 删除:删除链表中的指定元素或删除链表的指定位置的元素。

4. 查找:查找链表中是否存在指定的元素,并返回该元素的位置或指针。

5. 修改:修改链表中指定位置的元素的值。

6. 遍历:按照某种顺序遍历链表,并对每个元素进行操作。

7. 排序:按照某种规则对链表中的元素进行排序。

8. 合并:将两个已排序的链表合并成一个新的已排序链表。

9. 反转:将链表中的元素顺序反转。

10. 判断:判断链表是否为空、是否为循环链表等。

以上是链表的一些常见操作,具体实现方式会因编程语言和具体需求而有所不同。

数据结构实验报告-单链表

数据结构实验报告-单链表

2016级数据结构实验报告实验名称:实验一线性表——题目1学生姓名:李文超班级:2015661131班内序号:15学号:2015522147日期:2016年11月13日1.实验要求实验目的:根据线性表的抽象数据类型的定义,选择下面任一种链式结构实现线性表,并完成线性表的基本功能。

线性表存储结构(五选一):1、带头结点的单链表2、不带头结点的单链表3、循环链表4、双链表5、静态链表线性表的基本功能:1、构造:使用头插法、尾插法两种方法2、插入:要求建立的链表按照关键字从小到大有序3、删除4、查找5、获取链表长度6、销毁7、其他:可自行定义编写测试main()函数测试线性表的正确性。

2.程序分析2.1 存储结构单链表的存储:(1)链表用一组任意的存储单元来存放线性表的结点。

这组存储单元既可以是连续的,也可以是不连续的,甚至零散地分布在内存的某些位置。

(2)链表中结点的逻辑次序和物理次序不一定相同。

为了能正确表示结点间的逻辑关系,在存储每个元素值的同时,还要存储该元素的直接后继元素的位置信息,这个信息称为指针或链。

结点结构┌──┬──┐ data 域---存放结点值的数据域│data │next │ next 域---存放结点的直接后继的地址的指针域└──┴──┘单链表在内存中的存储示意地址 内存单元1000H头指针 1020H1080H10C0H2.2 关键算法分析1、关键算法:(1)头插法自然语言描述:a:在堆中建立新结点b:将a[i]写入到新结点的数据域c:修改新结点的指针域d:修改头结点的指针域。

将新结点加入链表中伪代码描述a:Node <T> * s=new Node <T>b:s->data=a[i]c:s->next=front->next;d:front->next=s(2)尾插法自然语言描述:a:在堆中建立新结点:b:将a[i]写入到新结点的数据域:c:将新结点加入到链表中d:修改修改尾指针伪代码描述a:Node <T> * s=new Node <T>b:s->data=a[i]c:r->next=s;d:r=s(3)遍历打印函数自然语言描述:a:判断该链表是否为空链表,如果是,报错b:如果不是空链表,新建立一个temp指针c:将temp指针指向头结点d:打印temp指针的data域e:逐个往后移动temp指针,直到temp指针的指向的指针的next域为空伪代码描述a: If front->next==NULL①Throw ”an empty list ”②Node<T>* temp=front->next;b:while(temp->next)c:cout<<temp->data<<" ";d:temp=temp->next;(4) 获取链表长度函数自然语言描述:a:判断该链表是否为空链表,如果是,输出长度0b:如果不是空链表,新建立一个temp指针,初始化整形数n为0c:将temp指针指向头结点d:判断temp指针指向的结点的next域是否为空,如果不是,n加一,否则return ne: 使temp指针逐个后移,重复d操作,直到temp指针指向的结点的next域为0,返回n伪代码描述a:if ront->next==NULLb:Node<T>* temp=front->next;c:while(temp->next)d:temp=temp->next;(5)析构/删除函数自然语言描述:a:新建立一个指针,指向头结点b:判断要释放的结点是否存在,c:暂时保存要释放的结点d:移动a中建立的指针e:释放要释放的指针伪代码描述a:Node <T> * p=frontb:while(p)c:front=pd:p=p->nexte:delete front(6)按位查找函数自然语言描述:a:初始化工作指针p和计数器j,p指向第一个结点,j=1b:循环以下操作,直到p为空或者j等于1①:p指向下一个结点②:j加1c:若p为空,说明第i个元素不存在,抛出异常d:否则,说明p指向的元素就是所查找的元素,返回元素地址伪代码描述a:Node <T> * p=front->next;j=1;b:while(p&&j!=1)①:p=p->next②:j++c:if(!p) throw ”error”d:return p(7)按位查找函数自然语言描述:a:初始化工作指针p和计数器j,p指向第一个结点,j=1b:循环以下操作,找到这个元素或者p指向最后一个结点①:判断p指向的结点是不是要查找的值,如果是,返回j,否则p指向下一个结点,并且j的值加一c:如果找到最后一个结点还没有找到要查找的元素,返回查找失败信息伪代码描述a:Node <T> * p=front->next;j=1;b:while(p)①: if(p->next==x) return jp=p->nextj++c:return “error”(8)插入函数自然语言描述:a:在堆中建立新结点b:将要插入的结点的数据写入到新结点的数据域c:修改新结点的指针域d:修改前一个指针的指针域,使其指向新插入的结点的位置伪代码描述a:Node <T> * s=new Node <T>;b:s-data=p->datac:s->next=p->nextd:p->next=se:p->data=x(9)删除函数自然语言描述:a:从第一个结点开始,查找要删除的位数i前一个位置i-1的结点b:设q指向第i个元素c:将q元素从链表中删除d:保存q元素的数据e:释放q元素伪代码描述a:q=p->nextb:p->next=q->nextc:x=q->datad:delete q2、代码详细分析(插入):(1)从第一个结点开始,查找节点,使它的数据比x大,设p指向该结点:while (x>p->data) { p=p->next;}(2)新建一个节点s,把p的数据赋给s:s->data=p->data;(3)把s加到p后面:s->next=p->next; p->next=s;(4)p节点的数据用x替换:p->data=x;示意图如图所示xp->datas3、关键算法的时间复杂度:O(1)3.程序运行结果1. 流程图:2、结果截图3.测试结论:可以正确的对链表进行插入,删除,取长度,输出操作。

数据结构复习题

数据结构复习题

数据结构复习题第一章抽象数据类型数据结构基本要素数据逻辑结构------集合、线性、树型、图数据存储结构------- 顺序、链接、散列、索引算法及其分析----时间复杂度,空间复杂度,O()练习题1 数据结构形式地定义为(D,R),其中D是_________的有限集合,R是D上的_________ 有限集合。

2 数据结构包括数据的____________、数据的_______________和数据的___________三个方面的内容。

3 计算机算法指的是()A. 计算方法B. 排序方法C. 解决问题的有限运算序列D. 调度方法4 在数据结构中,从逻辑上可以把数据结构分为()A. 动态结构和静态结构B. 紧凑结构和非紧凑结构C. 线性结构和非线性结构D. 内部结构和外部结构5 数据结构在计算机内存中的表示是()A. 数据的存储结构B. 数据结构C. 数据的逻辑结构D. 数据元素之间的关系第二章线性表----(直接)前驱、(直接)后继抽象数据类型-----插入操作、删除操作顺序表-----数据元素存储地址的计算链接表(插入+删除)----结点结构:数据域+ 指针域,单链表,双向链表,循环链表链表中头结点的用途习题1设有一线性表e=(e1, e2, …, en),其逆线性表定义为e’=(en, en-1, …, e2,e1)。

请设计一个算法,将用顺序表表示的线性表逆置,要求逆线性表仍占用原线性表的存储空间。

2写一个算法,在带头结点的单链表list中,删除p所指的结点,并返回成功与否的标志。

3一个长度为n的线性表,在其第i个元素(1≤i≤n)之前插入一个元素时,需向后移动____________个元素;删除第i个元素时,需要向前移动____________个元素。

4链表不具备的特点是()A. 可随机访问任一结点B. 插入删除不需要移动元素C. 不必事先估计存储空间D. 所需空间与其长度成正比5 如果最常用的操作是取第i个结点及其前驱,则采用()存储方式最节省时间。

链表的操作(3)

链表的操作(3)

●循环链表判断空循环表的条件:Head == Head->next;NULL==head->next;//判断单链表是否为空仅设尾指针的单循环表(1)保存ha的位置(2)B表的第一个元素连到A表的最后一个元素之后(3)释放hb(4)B表的最后一个元素指向ha(5)返回新循环表尾指针LinkList ConnectList_L(LinkList A, LinkList B){LinkList p=A->next;A->next=B->next->next;free(B->next);B->next=p;Return B;}●双向链表1.定义typedef struct Lnode{int data;Struct Lnode *next;Struct Lnode *prior;}Lnode, *LinkList;2.插入结点(1)生成一个新结点s(2)把p->prior赋给s->prior(3) 使p->->next指向s(4)s->next指向p(5)p->prior 指向sStatus DulListInsert(DulLinklist L, int i, ElemType e){…//寻址If(!(s=(DulLinkList)malloc(sizeof(DulNode))))Return ERROR;s->data=e;s->prior=p->prior;p->prior->next=s;s->next=p;p->prior=s;return ok;}3.删除e=p->data;p->prior->next=p->next;p->next->prior=p->prior;free(p);作业双链表的创建并打印Input:1020 30 40 50Output10 20 30 40 50 50 40 30 20 10链表的初始化用法:#include <malloc.h>或#include<stdlib.h>功能:用于向内存申请空间,分配长度为num_bytes字节的内存块说明:如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。

数据结构c++顺序表、单链表的基本操作,查找、排序代码

数据结构c++顺序表、单链表的基本操作,查找、排序代码

} return 0; }
实验三 查找
实验名称: 实验3 查找 实验目的:掌握顺序表和有序表的查找方法及算法实现;掌握二叉排序 树和哈希表的构造和查找方法。通过上机操作,理解如何科学地组织信 息存储,并选择高效的查找算法。 实验内容:(2选1)内容1: 基本查找算法;内容2: 哈希表设计。 实验要求:1)在C++系统中编程实现;2)选择合适的数据结构实现查 找算法;3)写出算法设计的基本原理或画出流程图;4)算法实现代码 简洁明了;关键语句要有注释;5)给出调试和测试结果;6)完成实验 报告。 实验步骤: (1)算法设计 a.构造哈希函数的方法很多,常用的有(1)直接定址法(2)数字分析法;(3) 平方取中法;(4)折叠法;( 5)除留余数法;(6)随机数法;本实验采用的是除 留余数法:取关键字被某个不大于哈希表表长m的数p除后所得余数为哈 希地址 (2)算法实现 hash hashlist[n]; void listname(){ char *f; int s0,r,i; NameList[0].py="baojie"; NameList[1].py="chengቤተ መጻሕፍቲ ባይዱoyang"; ……………………………… NameList[29].py="wurenke"; for(i=0;i<q;i++){s0=0;f=NameList[i].py; for(r=0;*(f+r)!='\0';r++) s0+=*(f+r);NameList[i].k=s0; }} void creathash(){int i;
v[k-1]=v[k]; nn=nn-1; return ; } int main() {sq_LList<double>s1(100); cout<<"第一次输出顺序表对象s1:"<<endl; s1.prt_sq_LList(); s1.ins_sq_LList(0,1.5); s1.ins_sq_LList(1,2.5); s1.ins_sq_LList(4,3.5); cout<<"第二次输出顺序表对象s1:"<<endl; s1.prt_sq_LList(); s1.del_sq_LList(0); s1.del_sq_LList(2); cout<<"第三次输出顺序表对象s1:"<<endl; s1.prt_sq_LList(); return 0; } 运行及结果:

实验二 单链表的插入和删除

实验二   单链表的插入和删除

实验二 单链表的插入和删除1.实验目的:了解单链表的基本概念、结构的定义及在单链表上的基本操作(插入、删除、查找以及线性表合并),通过在VC 实现以上操作更好的了解书本上的内容并体会线性表的两种存储结构的区别。

2.实验预备知识:⑴ 复习C 语言中指针的用法,特别是结构体的指针的用法;⑵ 了解单链表的概念,单链表的定义方法;单链表是线性表的链式存储表示,是用一组任意的存储单元依次存储线性表的数据元素。

因此,为了表示每个数据元素a i 与其直接后继元素a i+1之间的逻辑关系,对数据元素ai 来说,,除了存储其本身的信息之外,还需存储一个指示其直接后继的信息(即直接后继的存储位置),而这部分就是用指针来完成的。

⑶ 掌握线性表在链式存储结构上实现基本操作:查找、插入、删除的算法; 在实现这些算法的时候,要注意判断输入数据的合法性,除此之外还要要注意以下内容:在实现查找的时候,首先要判断该顺序表是否为空,其次要判断查找后的结果(查到时输出查到的数据,未查到时给出错误提示)。

在实现插入的时候,由于是链式存储,它可以随机产生和回收存储空间,所以它不要判断线性表是否为满,但仍需判断要插入的位置是否合法,原因同实验一,其次要注意插入的时候语句的顺序不可颠倒,否则出错。

例如:s 所指向结点要插入在p 所指向的结点之后,则:正确形式:s->next=p->nextp->next=s错误形式:p->next=ss->next=p->next(因为此时p->next 已经指向s 了)在实现删除的时候,首先要判断线性表是否为空,为空则不能删除; 其次在删除后要回收空间。

例如:删除如上图所示s 所指向的结点p->next=p->next->nextfree s3.实验内容:⑴ 单链表的插入算法⑵ 单链表的删除算法⑶循环链表的插入和删除算法4.部分实验代码:⑴单链表的结构定义:#include <stdio.h>typedef int elemtype;typedef struct lnode{ elemtype data;struct lnode *next;}*linklist;⑵建立单链表的算法int n; /*n作为整个程序的全局变量*/linklist *creat(void){ linklist *head, *p1, *p2;n=0;p1=p2=(linklist *)malloc(sizeof(linklist));scanf(“%d”,&p1->data);head=null;while(p1->data!=0){ n=n+1;if(n==1) head=p1;else p2->next=p1;p2=p1;p1=(linklist *)malloc(sizeof(linklist));scanf(“%d”,&p1->data);}p2->next=null;return(head);}⑶单链表的插入算法int insert(linklist *head, int i,elemtype e) { linklist *p, *s;int j;p=head; j=0;while(p && j<i-1){ p=p->next;++j;}if(!p||j>i-1){ printf(“无法插入”);return 0;}s=(linklist *)malloc(sizeof(lnode));s->data=e;s->next=p->next;p->next=s;return 1;}⑷单链表的删除算法int deltree(linklist *head,int i,elemtype e){ linklist *p, *q;int j;lp=head; j=0;while(p->next && j<i-1){ p=p->next;++j;}if(!(p->next)||j>i-1){ printf(“无法删除”);return 0;}q=p->next;p->next=q->next;e=q->data;free(q);return 1;}。

单链表的基本操作代码

单链表的基本操作代码

单链表的基本操作代码单链表是一种常用的数据结构,它具有优秀的插入和删除性能,在数据存储和处理方面具有广泛的应用。

单链表的基本操作包含创建链表、插入节点、删除节点、查找节点等,下面是单链表的基本操作代码:1. 定义单链表结构体:typedef struct ListNode {int val;struct ListNode *next;} ListNode;2. 创建单链表:ListNode *createList(int arr[], int n) {ListNode *head = NULL, *tail = NULL, *p = NULL;for(int i = 0; i < n; i++) {p = (ListNode *)malloc(sizeof(ListNode));p->val = arr[i];p->next = NULL;if(head == NULL) {head = tail = p;} else {tail->next = p;tail = p;}}return head;}3. 插入节点:void insertNode(ListNode **head, int val, int pos) {ListNode *p = (ListNode *)malloc(sizeof(ListNode)); p->val = val;p->next = NULL;if(*head == NULL) {if(pos != 0) {printf("Invalid position\n");return;} else {*head = p;return;}}if(pos == 0) {p->next = *head;*head = p;} else {int i = 0;ListNode *q = *head;while(q != NULL && i < pos - 1) {q = q->next;i++;}if(q == NULL || i != pos - 1) {printf("Invalid position\n");return;}p->next = q->next;q->next = p;}}4. 删除节点:void deleteNode(ListNode **head, int pos) {if(*head == NULL) {printf("List is empty\n");return;}if(pos == 0) {ListNode *p = *head;*head = (*head)->next;free(p);} else {int i = 0;ListNode *p = *head, *q = NULL; while(p != NULL && i < pos) { q = p;p = p->next;i++;}if(p == NULL || i != pos) {printf("Invalid position\n");return;}q->next = p->next;free(p);}}5. 查找节点:ListNode *findNode(ListNode *head, int val) {ListNode *p = head;while(p != NULL) {if(p->val == val) {return p;}p = p->next;}return NULL;}单链表的基本操作是数据结构中最基础的部分,掌握好这些代码对于往后的学习和应用都会有很大的帮助。

数据结构中链表及常见操作

数据结构中链表及常见操作

链表1 定义链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer)。

由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而顺序表相应的时间复杂度分别是O(logn)和O(1)。

使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。

但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。

在计算机科学中,链表作为一种基础的数据结构可以用来生成其它类型的数据结构。

链表通常由一连串节点组成,每个节点包含任意的实例数据(data fields)和一或两个用来指向明上一个或下一个节点的位置的链接("links")。

链表最明显的好处就是,常规数组排列关联项目的方式可能不同于这些数据项目在记忆体或磁盘上顺序,数据的访问往往要在不同的排列顺序中转换。

而链表是一种自我指示数据类型,因为它包含指向另一个相同类型的数据的指针(链接)。

链表允许插入和移除表上任意位置上的节点,但是不允许随机存取。

链表有很多种不同的类型:单向链表,双向链表以及循环链表。

2 结构2.1 单向链表链表中最简单的一种是单向链表,它包含两个域,一个信息域和一个指针域。

这个链接指向列表中的下一个节点,而最后一个节点则指向一个空值。

一个单向链表的节点被分成两个部分。

第一个部分保存或者显示关于节点的信息,第二个部分存储下一个节点的地址。

单向链表只可向一个方向遍历。

链表最基本的结构是在每个节点保存数据和到下一个节点的地址,在最后一个节点保存一个特殊的结束标记,另外在一个固定的位置保存指向第一个节点的指针,有的时候也会同时储存指向最后一个节点的指针。

一般查找一个节点的时候需要从第一个节点开始每次访问下一个节点,一直访问到需要的位置。

单链表类型定义

单链表类型定义

单链表类型定义一、什么是单链表?你有没有想过,程序中的“链表”到底是啥?它就像是一串珍珠项链。

每颗珠子代表一个元素,而每颗珠子都用一根线(我们叫它“指针”)连接到下一颗珠子。

单链表也差不多,不过它是单向的。

换句话说,你只能从一头走到另一头,一旦错过了某颗珠子,就没得回头的机会,像是迷失在迷宫里。

你看,这条链就像一条路,每一站都连接着下一站,但如果你没记住每一站,想绕回来,你就得重新从头来。

这个单链表的特点就是“单向”。

你能从头走到尾,但从尾巴往回走可就不行了。

所以,一旦你走到尾巴那儿,后面就没啥可以链接的了。

你知道吗,单链表的设计其实就像我们人生中的一些关系。

比如你有个朋友,你们天天聊天,分享彼此的心事,互相关照,结果某天一转身,你发现她又去和另一个朋友聊八卦,留下你一个人孤零零地站在原地。

是的,就是这种“单向”特性。

每个元素都只记得下一个元素,它们不过是彼此相互牵挂的“朋友”,却没有能力再去回顾过去的联系。

二、单链表的结构单链表的结构其实就是很简单的:一个个节点。

每个节点都包含两个东西,第一个是“数据”,也就是你要存储的东西,第二个是“指针”,也就是指向下一个节点的“标志”。

它们相当于是一个“装了东西的盒子”,而指针就像是一个箭头,指向下一个盒子。

是不是很简单?不过也正是因为这种设计,单链表可以灵活地增减节点,特别适合用在一些我们不事先知道数据大小的场景。

想想看,如果你提前知道了自己要装多少数据,数组当然是最好的选择。

但一旦你不知道呢?那单链表就是最好的选择,因为你可以随时增加新的节点,甚至随时删掉一个不想要的节点,不需要移动其他数据。

想象一下,单链表就像一个班级里的座位安排。

每个座位上有一个同学,学生们之间有个座位号来提醒自己下一个座位是哪个。

某一天,你突然觉得,某个同学不适合坐这个位置了,你可以直接把他的座位号换成下一个同学的座位号,他的朋友根本不会受到影响。

很酷吧?而且最妙的地方就是,你根本不用担心整个班级重排,单纯的“移座”就好了。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
q=p->next;p->next=q->next;
e=q->data;free(q);
return 1;
}
int menu(struct LNode *p){
int i,m,c,y,w;
struct LNode *q;
printf(" \n------1:插入元素2:删除元素3:显示链表4:退出链表------\n请输入指令:");
p->next=s;
return 1;
}
int ListDelete_L(LNode *h,int i){
struct LNode *p,*q;
int j,e;
p=h;j=0;
while(p->next&&j<i-1){
p=p->next;++j;
}
if(!(p->next)||j>i-1)return 0;
struct LNode *p,*s;
int j;
p=h;j=0;
while(p&&j<i-1){
p=p->next;++j;
}
if(!p||j>i-1)return 0;
s=(struct LNode*)malloc(sizeof(struct LNode));
s->data=e;s->next=p->next;
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
struct LNode
{int data;
struct LNode *next;
};
int n;
void print(struct LNode *h){
printf("链表中的元素有\n");
print(p);
}
if(m==4){
exit(0);
}
menu(p);
}
main(){
struct LNode *p;
printf("请先建立链表\n");
printf("请输入要输入的元素个数\n");
scanf("%d",&n);
p=MadeList_L(n);
menu(p);
}
}
else printf("错误!/n");
}
if(m==2){
printf("请输入要删除的元素位置\n");
scanf("%d",&w);
if(ListDelete_L(p,w)==1){
printf("删除成功!\n");
print(p);
}
else printf("删除失败\n");
}
if(m==3){
scanf("%d",&m);
if(m==1){
printf("请输入插入元素的位置\n");
scanf("%d",&c);
printf("请输入插入的元素\n");
scanf("%d",&y);
if(ListInsert_L(p,c,y)==1){
printf("插入成功\n");
print(p);
printf("请输入第%d个元素\n",i+1);
scanf("%d",&j);
p->data=j;
p->next = NULL;
if(i==0){
head->next=p;
}
else{
q->next=p;
}
q=p;
}
return head;
}
intListInsert_L(LNode *h,int i,int e){
struct LNode *head,*p,*q;
head=(struct LNode*)malloc(sizeof(struct LNode));
head->next = NULL;
for(i=0;i<n;i++){
p=(struct LNode*)malloc(sizeof(struct LNode));
struct LNode *c;
c=h->next;
if(c!=NULL)
{
while(c!=NULL)
{
printf("%d ",c->data);
c=next;
}
}
else printf("这是一个空表\n");
}
struct LNode* MadeList_L(int n){
int i,j;
相关文档
最新文档