带头结点的单向链表的基本操作

合集下载

北京邮电大学 数据结构 实验一 带头结点的单链表构造

北京邮电大学 数据结构 实验一 带头结点的单链表构造

数据结构实验报告实验名称:实验1——单链表的构造学生姓名:XXXXNB班级:XXXX班内序号:学号:XXXX日期:XXXXX1.实验要求根据线性表的抽象数据类型的定义,完成带头结点的单链表的基本功能。

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

2.程序分编程完成单链表的一般性功能如单链表的构造:使用头插法、尾插法两种方法插入:要求建立的链表按照关键字从小到大有序,删除,查找,获取链表长度,销毁用《数据结构》中的相关思想结合C++语言基本知识编写一个单链表结构。

本程序为使用方便,几乎不用特殊的命令,只需按提示输入即可,适合更多的用户使用。

2.1 存储结构单链表的存储结构:2.2 关键算法分析1.头插法自然语言描述:a.在堆中建立新结点b.将a[i]写入到新结点的数据域c.修改新结点的指针域d.修改头结点的指针域,将新结点加入链表中//在构建之初为了链表的美观性构造,进行了排序代码描述://头插法构造函数template<class T>LinkList<T>::LinkList(T a[], int n){for (int i = n - 1; i >= 1; i--)//冒泡排序,对数组进行从小到大排序{for (int j = 0; j < i; j++){if (a[j]>a[j + 1]){T t = a[j + 1];a[j + 1] = a[j];a[j] = t;}}}front = new Node < T >;//为头指针申请堆空间front->next = NULL;//构造空单链表for (int i = n - 1; i >= 0; i--){Node<T>*s = new Node < T >;//建立新结点s->data = a[i];//将a[i]写入新结点的数据域s->next = front->next;//修改新结点的指针域front->next = s;//修改头结点的指针域,将新结点加入到链表中}}2.尾插法自然语言描述:a.在堆中建立新结点b.将a[i]写入到新结点的数据域c.将新结点加入到链表中d.修改修改尾指针代码描述://尾插法构造函数template<class T>LinkList<T>::LinkList(T a[], int n){front = new Node < T > ;Node<T>*r = front;//命名一个新变量进行转换for (int i = 0; i < n; i++){Node<T>*s = new Node < T > ;s->data = a[i];r->next = s;r = s;}r->next = NULL;}时间复杂度:O(n)3.析构函数自然语言描述:a.新建立一个指针,指向头结点b.移动a中建立的指针c.逐个释放指针代码描述:template<class T>LinkList<T>::~LinkList()//析构函数,销毁链表{Node<T> * p = front;while(p){front = p;p = p->next;delete front;}}4.按位查找函数自然语言描述: a.初始化工作指针p和计数器j,p指向第一个结点,j=1b.循环以下操作,直到p为空或者j等于1b1:p指向下一个结点b2:j加1c.若p为空,说明第i个元素不存在,抛出异常d.否则,说明p指向的元素就是所查找的元素,返回元素地址代码描述:template<class T>Node<T>* LinkList<T>::Get(int i)//按位查找{Node<T> * p = front;int j=0;while(p){if(j<i){p = p->next;j++;}else break;}if(!p) throw"查找位置非法";else return p;}时间复杂度:O(n)5.按值查找函数自然语言描述:a.初始化工作指针p和计数器j,p指向第一个结点,j=1b.循环以下操作,找到这个元素或者p指向最后一个结点b1.判断p指向的结点是不是要查找的值,如果是,返回j;b2.否则p指向下一个结点,并且j的值加一c.如果找到最后一个结点还没有找到要查找的元素,返回查找失败信息代码描述:template<class T>int LinkList<T>::Locate(T x)//按值查找{Node<T> * p = front->next;int j = 1;while(p){if(p->data == x) return j;else{p = p->next;j++;}}return -1;}时间复杂度:O(n)6.插入函数自然语言描述:a.在堆中建立新结点b.将要插入的结点的数据写入到新结点的数据域c.修改新结点的指针域d.修改前一个指针的指针域,使其指向新插入的结点的位置代码描述:template<class T>void LinkList<T>::Insert(int i,T x)//插入函数{Node<T> * p = Get(i-1);if(p){Node<T> * s = new Node<T>;s->data = x;s->next = p->next;p->next = s;}else throw"插入位置非法";}时间复杂度:O(n)7.按位删除函数自然语言描述:a.从第一个结点开始,查找要删除的位数i前一个位置i-1的结点b.设q指向第i个元素c.将q元素从链表中删除d.保存q元素的数据e.释放q元素代码描述:template<class T>T LinkList<T>::Delete(int i)//删除函数{Node<T> *p = Get(i-1);Node<T> *q = p->next;T x=q->data;p->next = q->next;delete q;return x;}8.遍历打印函数自然语言描述: a.判断该链表是否为空链表,如果是,报错b.如果不是空链表,新建立一个temp指针c.将temp指针指向头结点d.打印temp指针的data域e.逐个往后移动temp指针,直到temp指针的指向的指针的next域为空代码描述:template<class T>void LinkList<T>::PrintList()//打印链表{Node<T> * p = front->next;while(p){cout<<p->data<<' ';p = p->next;}cout<<endl;}9.获取链表长度函数自然语言描述:a.判断该链表是否为空链表,如果是,输出长度0b.如果不是空链表,新建立一个temp指针,初始化整形数n为0c.将temp指针指向头结点d.判断temp指针指向的结点的next域是否为空,如果不是,n加一,否则return ne.使temp指针逐个后移,重复d操作,直到temp指针指向的结点的next 域为0,返回n代码描述:template<class T>int LinkList<T>::GetLength()//分析链表长度{Node<T> * p = front;int i=0;while(p){p = p->next;i++;}return i-1;}2.3 其他异常处理采用try catch 函数处理异常如在插入时的异常处理:template<class T>void LinkList<T>::Insert(int i, T x){Node<T>*p = front;if (i != 1) p = Get(i - 1);try{if (p){Node<T>*s = new Node < T > ;s->data = x;s->next = p->next;p->next = s;}else throw i;}catch (int i){cout << "插入到位置 " << i << " 处" << "为错误位置"<<endl;}}3. 程序运行结果主函数流程图:测试截图:初始化链表,菜单创建执行功能:4. 总结.调试时出现了一些问题如:异常抛出的处理,书中并未很好的提及异常处理,通过查阅资料,选择用try catch 函数对解决。

c语言实现--带头结点单链表操作

c语言实现--带头结点单链表操作

c语⾔实现--带头结点单链表操作可能是顺序表研究的细致了⼀点,单链表操作⼀下⼦就实现了。

这⾥先实现带头结点的单链表操作。

⼤概有以下知识点.1;结点:结点就是单链表中研究的数据元素,结点中存储数据的部分称为数据域,存储直接后继地址的部分称为指针域。

2;结点⽰意图:3;头指针:头指针始终指向链表第⼀个元素,当有头结点时头结点就是链表第⼀个元素。

头指针具有标识左右,故头指针命名为链表的名字,这⾥为linklist。

头指针是⼀定存在的。

4;头结点:引⼊头结点的⽬的是,将链表⾸元结点的插⼊和删除操作与其他结点的插⼊和删除操作统⼀起来。

(即头指针地址不在发⽣变化)5;单链表结点结构体表⽰:1struct LNode2 {3int data; //姑且认为其数据为整型4struct LNode * next;5 };67 typedef struct LNode * linklist6;单链表的操作集合,头⽂件 defs.h1 #ifndef _DEFS_H_2#define _DEFS_H_34 #include<stdio.h>5 #include<stdlib.h>6 #include<malloc.h>78struct LNode //单链表结点的定义9 {10int data;11struct LNode * next;12 }13 typedef struct LNode * linklist1415//操作集合16void InitList(linklist *L); //申请头结点,头指针地址改变17void DestroyList(linklist *L); //须释放头结点,头指针地址改变18void ClearList(linklist L); //保留头结点,头指针地址不变19void ListEmpty(linklist L);20int ListLength(linklist L);21int GetElem(linklist L, int i, int *e);22int LocateElem(linklist L, int e);23int PriorElem(linklist L, int cur_e, int *pri_e);24int NextElem(linklist L, int cur_e, int *nex_e);25int ListInsert(linklist L, int i, int e); //插⼊不改变头指针的值26int ListDelete(linklist L, int i, int *e); //删除操作也不改变头指针的值27void TravelList(linklist L);28#endif7;InitList操作实现1 #include"defs.h"23void InitList(linklist *L) //接受头指针的地址值4 {5 *L = (linklist)malloc(sizeof(struct LNode)); //*L表⽰头指针67if (*L == NULL)8 {9 printf("分配结点失败。

计算机软件技术基础_实验指导书

计算机软件技术基础_实验指导书

《计算机软件技术基础》实验指导书编写:XXX适用专业:电器工程与自动化通讯工程电子信息工程安徽建筑工业学院电子与信息工程学院2007年9月实验一:线性链表的建立、查找、插入、删除实验实验学时:2实验类型:验证实验要求:必修一、实验目的通过本实验的学习,要求学生能够通过单链表的存储结构,掌握单链表的基本操作,包括单链表的建立、查找、插入、删除、输出等操作。

通过本实验可以巩固学生所学的线性表知识,提高编程能力,为后继课程的学习奠定基础。

二、实验内容1、为线性表{10,30,20,50,40,70,60,90,80,100}创建一个带头结点的单链表;2、在该链表上查找值为50,65的结点,并返回查找结果(找到:返回在县新链表中的位置);3、在该链表上值为50的结点后,插入一个值为120的结点;4、删除该链表上值为70的结点。

写出各操作的实现函数,并上机验证。

三、实验原理、方法和手段使用带头结点的单链表的表示线性表,通过实验,熟悉链表的创建、查找、插入、删除、输出等是链表的基本操作。

具体如下:(1)首先定义单链表的节点结构;(2)在单链表创建过程中,首先初始化一个带头结点的空链表,对线性表中的各元素依次通过键盘输入、建立该元素结点、插入到单链表中,实现单链表的创建过程;结点的插入有头插入和尾插入两种方法,采用不同方法时应注意元素的输入顺序。

(3)查找过程可以从头结点开始,将待查找的数据依次与每个结点的数据域比较,匹配及查找成功,弱链表访问完未找到匹配的元素,则查找不成功。

为能够返回查找成功的结点位置,在链表的搜索过程中,应设置一个计数器,记录搜索结点的序号;(4)插入结点时,首先要通过查找算法,找到带插入结点的前驱结点,然后为带插入元素建立结点,通过指针的修改,将结点插入。

(5)删除结点时,首先要通过查找算法,找到待删除结点的前驱,然后通过指针的修改,将待删除结点从链表中卸下,释放该结点。

(6)以上操作的正确性,均可以通过链表的输出结果来验证。

单链表基本操作的实现

单链表基本操作的实现

单链表基本操作的实现单链表是一种常见的数据结构,它由多个节点组合而成,每个节点包含一个数据元素和一个指向下一个节点的指针。

通过指针,我们可以方便地在单链表中进行插入、删除和遍历等操作。

以下是关于单链表基本操作的实现。

1. 单链表的创建单链表的创建需要定义一个空的头结点,它的作用是方便在链表的头部进行添加和删除节点操作。

一个空的头节点可以在链表初始化的过程中进行创建。

```typedef struct Node{int data;struct Node *next;}Node;Node *createList(){Node *head = (Node*)malloc(sizeof(Node)); //创建空的头节点head->next = NULL;return head; //返回头节点的地址}```2. 单链表的插入单链表的插入可以分为在链表头部插入、在链表尾部插入和在链表中间插入三种情况。

a. 在链表头部插入节点:```void insertAtHead(Node *head, int data){Node *node = (Node*)malloc(sizeof(Node));node->data = data;node->next = head->next;head->next = node;}```b. 在链表尾部插入节点:```void insertAtTail(Node *head, int data){Node *node = (Node*)malloc(sizeof(Node));node->data = data;node->next = NULL;Node *p = head;while(p->next != NULL){p = p->next;}p->next = node;}```c. 在链表中间插入节点:```void insertAtMid(Node *head, int data, int pos){ Node *node = (Node*)malloc(sizeof(Node)); node->data = data;node->next = NULL;Node *p = head;int count = 0;while(p->next != NULL && count < pos-1){ p = p->next;count++;}if(count == pos-1){node->next = p->next;p->next = node;}else{printf("插入位置错误!");}}```3. 单链表的删除单链表的删除可以分为在链表头部删除、在链表尾部删除和在链表中间删除三种情况。

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

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

单链表实验报告一、实验目的1、帮助读者复习C++语言程序设计中的知识。

2、熟悉线性表的逻辑结构。

3、熟悉线性表的基本运算在两种存储结构上的实现,其中以熟悉链表的操作为侧重点。

二、实验内容[问题描述]实现带头结点的单链表的建立、求长度,取元素、修改元素、插入、删除等单链表的基本操作。

[基本要求](1)依次从键盘读入数据,建立带头结点的单链表;(2)输出单链表中的数据元素(3)求单链表的长度;(4)根据指定条件能够取元素和修改元素;(5)实现在指定位置插入和删除元素的功能。

三、算法设计(1)建立带表头结点的单链表;首先输入结束标志,然后建立循环逐个输入数据,直到输入结束标志。

(2)输出单链表中所有结点的数据域值;首先获得表头结点地址,然后建立循环逐个输出数据,直到地址为空。

(3)输入x,y在第一个数据域值为x的结点之后插入结点y,若无结点x,则在表尾插入结点y;建立两个结构体指针,一个指向当前结点,另一个指向当前结点的上一结点,建立循环扫描链表。

当当前结点指针域不为空且数据域等于x的时候,申请结点并给此结点数据域赋值为y,然后插入当前结点后面,退出函数;当当前结点指针域为空的时候,申请结点并给此结点数据域赋值为y,插入当前结点后面,退出函数。

(4)输入k,删除单链表中所有的结点k,并输出被删除结点的个数。

建立三个结构体指针,一个指向当前结点,另一个指向当前结点的上一结点,最后一个备用;建立整形变量l=0;建立循环扫描链表。

当当前结点指针域为空的时候,如果当前结点数据域等于k,删除此结点,l++,跳出循环,结束操作;如果当前结点数据域不等于k,跳出循环,结束操作。

当当前结点指针域不为空的时候,如果当前结点数据域等于k,删除此结点,l++,继续循环操作;如果当前结点数据域不等于k,指针向后继续扫描。

循环结束后函数返回变量l的值,l便是删除的结点的个数。

四、实验结果1、新建一个链表:2、输出链表的数据:(4)插入数据:在数据为3后面插入一个数据100:(5)删除数据:删除刚刚插入的数据100:五、总结实验之前由于准备不够充分,所以堂上实验时只完成了建立单链表和数据的输出,而后面两个实验要求也是用来很多时间长完成的。

带头节点的循环单链表

带头节点的循环单链表

带头节点的循环单链表带头节点的循环单链表是一种特殊的链表结构,它在普通的循环单链表的基础上增加了一个头节点。

本文将详细介绍带头节点的循环单链表的特点、操作以及应用场景。

一、带头节点的循环单链表的特点带头节点的循环单链表与普通的循环单链表相比,多了一个头节点,头节点不存储任何数据,仅作为链表的标志和辅助作用。

头节点的存在使得链表的插入、删除等操作更加方便,同时也能避免一些特殊情况的处理。

1. 初始化链表:创建一个头节点,并将头节点的指针指向自身,表示链表为空。

2. 判断链表是否为空:通过判断头节点的指针是否指向自身,即可判断链表是否为空。

3. 插入节点:在链表的指定位置插入一个新节点。

首先找到插入位置的前一个节点,然后将新节点的指针指向前一个节点的下一个节点,再将前一个节点的指针指向新节点。

4. 删除节点:删除链表中指定位置的节点。

首先找到要删除节点的前一个节点,然后将前一个节点的指针指向要删除节点的下一个节点,最后释放被删除节点的内存空间。

5. 遍历链表:从头节点开始,按照指针的方向遍历链表,直到回到头节点为止,输出每个节点的数据。

三、带头节点的循环单链表的应用场景带头节点的循环单链表在实际应用中有着广泛的应用场景,以下是几个典型的应用场景:1. 约瑟夫环问题:约瑟夫环是一种数学问题,通过使用带头节点的循环单链表可以很方便地解决该问题。

2. 循环队列:循环队列是一种常见的队列结构,使用带头节点的循环单链表可以实现循环队列的操作。

3. 循环链表:带头节点的循环单链表本身就是一种循环链表,可以用于解决一些需要循环访问的问题。

总结:带头节点的循环单链表是一种特殊的链表结构,通过增加一个头节点,使得链表的操作更加方便,并且能够避免一些特殊情况的处理。

带头节点的循环单链表可以用于解决一些需要循环访问的问题,例如约瑟夫环问题和循环队列等。

掌握带头节点的循环单链表的基本操作,对于理解和应用链表结构具有重要的意义。

单链表的基本操作

单链表的基本操作

实验二:单链表的基本操作编写一个完整的程序,实现单链表的建立、插入、删除、输出等基本操作。

(1)建立一个带头结点的单链表。

(2)计算单链表的长度,然后输出单链表。

(3)查找值为x的直接前驱结点q。

(4)删除值为x的结点。

(5)把单向链表中元素逆置(不允许申请新的结点空间)。

(6)已知单链表中元素递增有序,请写出一个高效的算法,删除表中所有值大于mink且小于maxk的元素(若表中存在这样的元素),同时释放被删结点空间,并分析你的算法的时间复杂度(注意:mink和maxk是给定的两个参变量,他们的值可以和表中的元素相同,也可以不同)。

(7)同(6)的条件,试写一高效的算法,删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同),同时释放被删结点空间,并分析你的算法时间复杂度。

(8)利用(1)建立的链表,实现将其分解成两个链表,其中一个全部为奇数,另一个全部为偶数(尽量利用已知的存储空间)。

(9)在主函数中设计一个简单的菜单,分别测试上述算法。

# include <stdio.h># include <stdlib.h>typedef struct node{int data;struct node * next;}Lnode, * LinkList;int m=sizeof(Lnode);//建立新的链表void Bulid_List(LinkList root){int num;LinkList s,p;s=root->next;int n;printf("请输入新建链表的长度n数据:\n"); scanf("%d",&n);printf("请依次建立链表:");for(int i=0;i<n;i++){scanf("%d",&num);s->data=num;p=(LinkList)malloc(m);s->next=p;s=p;s->next=NULL;}printf("链表已建立!\n");}//对链表的输出,包括长度和元素void OutPut_list(LinkList root) {int len=0;LinkList s;s=root->next;if(s->next==NULL)printf("单链表无数据,请先新建单链表。

实验二 单链表基本操作

实验二 单链表基本操作

实验二单链表基本操作一实验目的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。

带头结点的单链表操作说明

带头结点的单链表操作说明

带头结点的单链表操作说明⼀、单链表简介相对于以数组为代表的“顺序表”⽽⾔,单链表虽然存储密度⽐较低(因为数据域才是我们真正需要的,指针域只是⽤来索引,我们并不真正需要它),但是却具有灵活分配存储空间、⽅便数据元素的删除、⽅便元素插⼊等优点单链表是线性表链式存储的⼀种,其储存不连续。

单链表的数据结构中包含两个变量:数据和指向下⼀结点的指针。

⼀个结点只知道下⼀个结点的地址。

⼀个单链表必须有⼀个头指针,指向单链表中的第⼀个结点。

否则链表会在内存中丢失。

⼀般的链表可以不带头结点,头指针直接指向第⼀个节点,如下图:但是这样的链表有⼀个很⼤的问题,就是元素插⼊与删除操作时,需要考虑是否要改动头指针,⽽改动指针如果反应在函数中,那么形参必须使⽤⼆重指针,既加⼤了编写程序的难度,⽽且还降低了可读性,容易出错,因此“带头结点的单链表”使⽤更⽅便,也就是头指针指向的节点不存放数据,只作为链表的开始,这样⼀来,针对第⼀个节点的操作和针对其他节点的操作就完全⼀样的,⼗分⽅便,如图所⽰:⼆、带头结点的单链表各种操作下⾯我们讨论⼀下带头结点的单链表的各种操作1、链表数据结构的声明1using namespace std;2const int MAXSIZE = 1000;3 template <class T>4struct Node5 {6 T data; //数据域7 Node *next; //指针域8 };2、链表模板类的声明1 template <class T>2class LinkList3 {4public:5 LinkList(){front = new Node<T>;} //the constructor function without arguments6 LinkList( T a[], int n); //the constructor function initialized by array of n elements7 ~LinkList();8int GetLength(); //get the length of the LIST9void PrintList(); //print the element of the list10void Insert(int i,T x);// insert element x in the i-th location11 T Delete(int i); //delete the i-th element and return its value12 Node<T> *Get(int i); //get the address of i-th element13int Locate(T x); //find the element whose value is x and return its index14private:15 Node<T> *front; //head pointer16 };3、⽤头插法建⽴新链表,也就是每次插⼊的新节点都在链表的头部,注释部分给出的是尾插法的实现⽅式1 template <class T>2 LinkList<T>::LinkList(T a[], int n)3 {4// insert element at the first location of the existing link list5 front = new Node<T>;6 front->next = NULL;7for(int i=n-1; i>=0; i--)8 {9 Node<T> *s = new Node<T>;10 s->data = a[i];11 s->next = front->next;12 front->next = s;13 }14// insert element at the tail of the existing link list1516/*17 front = new Node<T>;18 Node<T> *r = front;19 for(int i=0; i<n; i++)20 {21 Node<T> *s = new Node<T>;22 s->data = a[i];23 r->next = s;24 r=s;25 }26 r->next = NULL;27*/28 }4、打印链表1 template <class T>2void LinkList<T>::PrintList()3 {4 Node<T> *p = front;5if(p->next==NULL)6 cout<<"link is enpty"<<endl;7else8 {9 p = p->next;10while(p)11 {12 cout<<p->data<<"";13 p = p->next;14 }15 }16 }5、插⼊节点1 template <class T>2void LinkList<T>::Insert(int i,T x)3 {4 Node<T> *p = front;5if(i!= 1) p=Get(i-1); // if not insert the elelment in the first location 6if(p)7 {8 Node<T> *s = new Node<T>;9 s->data = x;10 s->next = p->next;11 p->next = s;12 }13else14 cout<<"error!"<<endl;15 }6、删除节点1 template <class T>2 T LinkList<T>::Delete(int i)3 {4 Node<T> *p = front;5if(i!=1) p = Get(i-1);6 Node<T> *q = p->next;7 p->next = q->next;8 T x = q->data;9delete q;10return x;11 }7、按位查找节点,返回第i个节点的地址1 template <class T>2 Node<T> *LinkList<T>::Get(int i)3 {4 Node<T> *p = front->next;5int j=1;6while(p&&j!=i)7 {8 p = p->next;9 j++;10 }11return p;12 }8、按值查找,返回给定值对应的节点的序号1 template <class T>2int LinkList<T>::Locate(T x)3 {45 Node<T> *p = front->next;6int j=1;7while(p)8 {9if(p->data==x) return j;10 p = p->next;11 j++;12 }13return -1; //search fail14 }9、获取链表长度1 template <class T>2int LinkList<T>::GetLength()3 {4 Node<T> *p = front->next;5int count=0;6while(p)7 {8 p = p->next;9 count++;10 }11return count; //get the length of linklist12 }10、析构函数1 template <class T>2 LinkList<T>::~LinkList()3 {4 Node<T> *p = front;5while(p)6 {7 front = p;8 p = p->next;9 }10 }11、主函数(由于使⽤模板类实现,以上所有代码建议放⼊ .h头⽂件,主函数则放⼊.cpp⽂件所有代码在dev c++环境中测试通过) 1/*2线性表相关成员函数的实现3*/4 #include <iostream>5 #include <cmath>6 #include <stdlib.h>7 #include "linked_list.h"8using namespace std;9int main()10 {11int a[7] = {1,2,3,4,5,6,7};12 LinkList <int> list(a,7);13 list.PrintList();14 cout<<endl;15 cout<<list.Get(3)<<endl;16 Node<int> temp = *list.Get(3);17 cout<<temp.data<<endl;18//cout<<*(list.Get(3))<<endl;19 cout<<list.GetLength()<<endl;20 list.Insert(3,11);21 cout<<list.GetLength()<<endl;22 list.PrintList();23 cout<<list.Locate(5)<<endl;24int x = list.Delete(4);25 cout<<"删除元素:"<<x<<endl;26 list.PrintList();27//int p = list.Locate(1000);28//cout<<"元素4的位置:"<<p<<endl;29 system("pause");30return0;31 }。

【头歌】单链表的基本操作

【头歌】单链表的基本操作

【头歌】单链表的基本操作
单链表是一种线性数据结构,由一系列节点组成,每个节点包含数据元素和一个指向下一个节点的指针。

以下是单链表的基本操作:
1. 插入操作:在单链表的指定位置插入一个新节点。

具体步骤如下:
找到要插入的位置的前一个节点;
将新节点插入到前一个节点和当前节点之间;
修改新节点的指针,使其指向当前节点;
修改前一个节点的指针,使其指向新节点。

2. 删除操作:删除单链表中的指定节点。

具体步骤如下:
找到要删除的节点的前一个节点;
将前一个节点的指针指向要删除的节点的下一个节点;
释放要删除的节点的内存。

3. 查找操作:在单链表中查找指定元素。

具体步骤如下:
从头节点开始遍历单链表;
找到与指定元素相等的节点;
返回该节点的位置。

4. 遍历操作:从头节点开始,依次访问单链表中的每个节点。

具体步骤如下:创建一个指针指向头节点;
依次访问指针所指向的每个节点,直到指针为空。

5. 打印操作:打印单链表中的所有元素。

具体步骤如下:
创建一个指针指向头节点;
依次打印指针所指向的每个节点的数据元素,直到指针为空。

以上是单链表的基本操作,通过这些操作可以对单链表进行各种操作,如插入元素、删除元素、查找元素等。

带表头结点单链表的初始化

带表头结点单链表的初始化

带表头结点单链表的初始化
带表头结点单链表的初始化是指在链表的头部添加一个额外的
结点,用于表示链表的起始位置。

这个额外的结点不存储实际的数据,只用来表示链表的开始。

初始化带表头结点单链表的步骤如下:
1. 定义一个结构体来表示链表结点,包含两个成员变量:data 表示结点存储的数据,next表示指向下一个结点的指针。

2. 定义一个指向链表头部的指针head,并将它初始化为NULL。

3. 创建一个表头结点,并将head指针指向表头结点。

4. 将表头结点的next指针初始化为NULL,表示链表为空。

初始化带表头结点单链表后,可以向链表中添加结点,并在需要时遍历链表,查找、删除或修改结点的数据。

带表头结点单链表的好处是可以避免在遍历链表时出现head指针为NULL的情况,从而使代码更加简洁易懂。

- 1 -。

链表基本操作

链表基本操作

链表基本操作链表作为一种重要的数据结构,在计算机程序设计中被广泛应用。

链表是一种元素之间通过指针相连接的线性结构,每个元素包含数据和指向下一个元素的指针。

链表能够灵活地增加和删除元素,适用于许多需要频繁插入和删除数据的场景。

在本文中,我们将介绍链表的基本操作,并按照类别进行介绍。

创建链表链表的创建是链表操作的第一步。

首先需要声明链表节点类型的结构体,并定义链表头指针。

然后通过动态内存分配函数malloc为链表节点动态分配内存,建立链表节点之间的关系,直到最后一个节点。

struct Node{int data;Node* next;};Node* createLinkedList(int n){Node* head = NULL;Node* tail = NULL;for(int i = 0; i < n; i++){Node* node = (Node*)malloc(sizeof(Node));node->data = 0;node->next = NULL;if(head == NULL){head = node;}else{tail->next = node;}tail = node;}return head;}插入数据链表的插入操作包括在链表头插入和在链表尾插入两种情况。

在链表头插入时,新节点的指针指向链表头,链表头指针指向新节点。

在链表尾插入时,先找到链表尾节点,然后将新节点插入在尾节点后面。

void insertAtFront(Node** head, int data){Node* node = (Node*)malloc(sizeof(Node));node->data = data;node->next = *head;*head = node;}void insertAtEnd(Node** head, int data){Node* node = (Node*)malloc(sizeof(Node)); node->data = data;node->next = NULL;if(*head == NULL){*head = node;}else{Node* tail = *head;while(tail->next != NULL){tail = tail->next;}tail->next = node;}}删除数据链表的删除操作包括在链表头删除和在链表尾删除两种情况。

链表的基本操作

链表的基本操作

链表的基本操作
链表是一种通用的数据结构,它利用指针对数据元素的每一个节点进行存储,当需要访问任何指定的节点时,受益于指针技术,可以较快的访问指定节点。

在一般的链表中,可以进行如下几种基本操作:
1.插入:链表可以在既有链表中的任何一个位置插入数据元素,通过改变相应指针指向,实现插入操作。

2.删除:链表也可以通过调整相应指针指向,实现删除操作。

3.搜索:在链表中搜索某个元素可以采用顺序搜索的方式,从链表的首元节点开始,逐个比较,直到找到所要查找节点。

4.遍历:链表可以从链表的首元节点开始,按照指针指向,依次访问每一个节点,从而实现对链表的元素的遍历。

5.修改:修改链表可以通过先将要修改的节点找出来,然后调整相应的数据值来实现。

链表的基本操作是一个非常常用的数据结构,可以有效的提高编程效率,更加方便的实现某些算法,广泛应用于很多的计算机程序。

所以在学习更多的数据结构的时候,了解链表的基本操作,也是一个不可忽视的组成部分。

数据结构学习-带头结点的单链表就地逆置

数据结构学习-带头结点的单链表就地逆置

数据结构学习-带头结点的单链表就地逆置所谓“就地是指辅助空间复杂度为O(1)。

解法⼀:将头结点摘下,然后从第⼀结点开始,依次前插⼊到头结点的后⾯(头插法),直到最后⼀个结点为⽌。

代码如下解法⼆:通过若⼲操作将指针反转达到逆置的⽬的。

假设pre、p和r指向3个相邻的结点,如上图。

*pre之前的结点的指针都已经调整完毕,它们的next指针都指向其原前驱结点。

现在令*p结点的next域指向*pre结点,注意到⼀旦调整指针的指向后,*p的后继结点的链就断开了,为此⽤r来指向原*p结点的后继结点。

处理第⼀个结点时,将其next域置为NULL,。

处理最后⼀个结点后,将头结点的指针指向它。

代码:LinkList Reverse (LinkList L){ LNode *p,*r;//p 为⼯作指针,r 为p 的后继以防断链 p=L->next;//从第⼀个元素结点开始 L->next=NULL;//先将头结点L 的next 域置为NULL while (p!=NULL)//依次将元素结点摘下 { r =p->next;//暂存p 的后继 p->next=L->next;//将p 结点插⼊到头结点之后 L->next=p; p =r; } return L;}Linklist reserve(LinkList L){ LNode *pre,*p=L->next,*r=p->next; p ->next=NULL;//处理第⼀个结点 while (r!=NULL)//r 为空,则说明p 为最后⼀个结点 { pre =p;//依次遍历 p=r; r =r->next; p ->next=pre;//指针反转 } L->next=p;//处理最后⼀个结点 return L;}。

数据结构 实验二:单链表的基本操作

数据结构 实验二:单链表的基本操作

数据结构实验二:单链表的基本操作数据结构实验二:单链表的基本操作实验二:单链表的基本操作一、【实验目的】1、理解和掌握单链表的类型定义方法和结点生成方法。

2、掌握建立单链表和显示单链表元素的算法。

3、掌握单链表的查找、插入和删除算法二、【实验内容】1、建立一个整形数的单链表,手动输入10个数,并从屏幕显示单链表元素列表。

2、从键盘输入一个数,查找在以上创建的单链表中是否存在该数;如果存在,显示它的位置;如果不存在,给出相应提示。

3、删除上述单链表中指定位置的元素。

以下就是程序部分代码,恳请调试并补足并使之恰当运转:1.linlist.htypedefstructnode{datatypedata;structnode*next;}slnode;voidlistinitiate(slnode**head)/*初始化*/{/*如果有内存空间,申请头结点空间并使头指针head指向头结点*/if((*head=(slnode*)malloc(sizeof(slnode)))==null)exit(1);(*head)->next=null;/*置链尾标记null*/}intlistlength(slnode*head){slnode*p=head;/*p指向首元结点*/intsize=0;/*size初始为0*/while(p->next!=null)/*循环计数*/{p=p->next;size++;}returnsize;}intlistinsert(slnode*head,inti,datatypex)/*在带头结点的单链表head的数据元素ai(0≤i≤size)结点前*//*填入一个存放数据元素x的结点*/{slnode*p,*q;intj;p=head;/*p指向首元结点*/j=-1;/*j起始为-1*/while(p->next!=null&&j<i-1)/*最终让指针p指向数据元素ai-1结点*/{p=p->next;j++;}if(j!=i-1){printf(\填入边线参数弄错!\return0;}/*生成新结点由指针q指示*/if((q=(slnode*)malloc(sizeof(slnode)))==null)exit(1);q->data=x;q->next=p->next;/*给指针q->next赋值*/p->next=q;/*给指针p->next重新赋值*/return1;}intlistdelete(slnode*head,inti,datatype*x)/*删除带头结点的单链表head的数据元素ai(0≤i≤size-1)结点*//*删除结点的数据元素域值由x带回。

数据结构带头节点的单向链表.ppt

数据结构带头节点的单向链表.ppt

ListMerge
2、pa和pb分别指向La和Lb的第一个元素
La
a1
a2
a3
pa
Lb
b1
b2
pb
pa=La->next, pb=Lb->next;
ListMerge
3、如果pa和pb都不为空,则: 选择pa和pb所指结点中数据较小的 那个结点,
调整pa或者pb,使之指向下一个结点 if(pa->data<pb->data) { tmp=pa;pa=pa->next;} else {tmp=pb;pb=pb->next;}
node->next==node; }
插入Lc的表尾
ListMerge
if (!pa) tmp=pb; else
tmp=pa; while(tmp){
node=(LNode *)malloc(sizeof(LNode)); if(!node) return(OVERFLOW); node->data=tmp->data; node->next=NULL; pc->next=node; pc=node; tmp=tmp->next; }
L 链式存储的结构
顺序存储的结构
讨论
head length
链式存储的结构
typedef struct { LNode *head //头指针 int length//元素个数
} LinkList
讨论
Status InitList(LinkList &L){ L.length=0; L.head=(LNode *)malloc(sizeof(LNode)); if(!L.head) return(OVERFLOW); L.head->next=NULL; return(OK);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

单链表的 基本操作

单链表的 基本操作

单向链表单向链表的基本操作,创建一个由6个节点组成的单向链表,显示链表中每个节点的数据,并且做增加、删除、查找节点以及计算单链表的长度等处理。

➢需求分析:1.功能(1)用尾插法创建一带头结点的由6个节点组成的单向链表:从键盘读入一组整数,作为单链表中的元素,输入完第6个结点后结束;将创建好的单链表元素依次输出到屏幕上。

(2)显示链表中每个节点的数据(3)从键盘输入一个数,查找在以上创建的单链表中是否存在该数;如果存在,显示它的位置,即第几个元素;如果不存在,给出相应提示如“No found node!”。

(4)在上述的单链表中的指定位置插入指定数据,并输出单链表中所有数据.(5)删除上述单链表中指定位置的结点,并输出单链表中所有数据.(6)求单链表的长度并输出。

2.输入要求先输入单链表中结点个数n,再输入单链表中所有数据,在单链表中需查找的数据,需插入的数据元素的位置、值,要删除的数据元素的位置。

3。

测试数据单链表中所有数据:12,23,56,21,8,10在单链表中需查找的数据:56;24插入的数据元素的位置、值:1,28;7,28;0,28要删除的数据元素的位置:6➢概要设计:1.算法思想:由于在操作过程中要进行插入、删除等操作,为运算方便,选用带头结点的单链表作数据元素的存储结构。

对每个数据元素,由一个数据域和一个指针域组成,数据域放输入的数据值,指针域指向下一个结点。

2.数据结构:单链表结点类型:typedef struct Liistnode {int data;struct Listnode *next;} NODE;3.模块划分:a)用尾插法建立带头结点的单链表*CreateList函数;b)显示链表中每个结点的数据PrintList函数;c)从键盘输入一个数,查找单链表中是否存在该数FoundList函数;d)在单链表中指定位置插入指定数据并输出单链表中所有数据InsertList函数;e)删除单链表中指定位置的结点并输出单链表中所有数据DeleteList函数;f)计算单链表的长度并在屏幕上输出LengthList函数;g)主函数main(),功能是给出测试数据值,建立测试数据值的带头结点的单链表,调用PrintList函数、FoundList函数、InsertList函数、DeleteList函数、LengthList函数实现问题要求.四、实验要求1.用C完成算法设计和程序设计并上机调试通过。

第85讲尾插法建带头结点的单链表

第85讲尾插法建带头结点的单链表

第85讲 尾插法建带头结点的单链表链表及结点的描述如下:typedef char DataType; //定义结点的数据域类型typedef struct node{ //结点类型定义DataType data; //结点的数据域struct node *next;//结点的指针域}ListNode; //结构体类型标识符typedef ListNode *LinkList; ListNode *p; //定义一个指向结点的指针LinkList head;//定义指向链表的头指针 尾插法建带头结点的单链表①头结点:是在链表的开始结点之前附加一个结点。

②算法思路先建立一个头结点,使头指针指向头结点,产生一个带头结点的空表。

从这一空表开始,重复读入数据,生成新结点,将读入数据存放在新结点的数据域中,然后将新结点插入到当前链表的表尾上,直到读入结束标志为止。

算法步骤如下:第1步:建立一个头结点,将头指针head 和指向尾结点的指针r 指向头结点,如图5-21。

第2步:生成一个新结点s (即由s 指向),并向结点的数据域写数据,如图5-22。

第3步:将新结点插入表尾,如图5-23。

第4步:使尾指针指向新表尾,如图5-24。

重复以上第2步到第4步,建立含有多个结点的链表,但此时尾结点的指针域还没有写数据。

图5-22 值写入新结点sa 图5-21head 指向头结点 图5-23 新结点s 插入表尾a 图5-24 尾指针r 指向新表尾a第5步:将尾结点的指针域写入NULL 。

这样,便可建立一个含有多个结点的带头结点的单链表如图5-25。

③尾插法建立带头结点的单链表算法的实现LinkList CreatListRH(void ){ //用尾插法建立带头结点的单链表DataType ch;LinkList head;ListNode *s,*r; //工作指针if ((head=(ListNode *)malloc(sizeof (ListNode)))==NULL){printf("不能分配内存空间!");exit(0);}r=head; //尾指针初值也指向头结点printf("请输入链表各结点的数据(字符型):\n");while ((ch=getchar())!='\n'){if ((s=(ListNode *)malloc(sizeof (ListNode )))==NULL){printf("不能分配内存空间!");exit(0);}s->data=ch;r->next=s;//将新结点插到链表尾r=s;//尾指针指向新表尾 }r->next=NULL;return head; }④头结点的作用在单链表中加入头结点,有两个优点:图5-25 尾插法建带头结点单链表a b ^c由于开始结点的位置被存放在头结点的指针域中,所以插入第一个结点的操作就和插入其他结点的操作一致(否则第3步要考虑两种不同的情况),无须进行特殊处理;无论链表是否为空,其头指针都是指向头结点的非空指针(空表中头结点的指针域空),因此空表和非空表的处理也就统一了(否则第5步要考虑两种不同的情况)。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第3页/共22页
初始化操作
功能:创建一个空链表(只有一个头结点) 已知条件:已知头指针变量(没有确定的值) 操作结果:头指针变量存放头结点的地址,头指针变
量发生了改变
操作前: L ? 操作后: L
^
第4页/共22页
初始化函数
操作前: L ? 操作后: L
int initLink(LINK &L) { ^ L=new NODE;
Li 18
He 20 ^
p=L; k=0;
while(p!=NULL && k<i-1){k++; p=p->next;}
第8页/共22页
插入操作
例:在i=2位置上插入学生数据x(liu,19)
操作前:L
0
1 Li 18
2 He 20 ^
步骤2:判断能否进行插入。如果i<1,会出现k>i-1,不能
插入;如果i>3,会出现p为空,不能插入。
L
p K=0 p K=1
Li 18
He 20 ^
if(p==NULL || k>i-1)
printf(“位置非法,不能插入\n”);
第9页/共22页
插入操作
例:在i=2位置上插入学生数据x(liu,19)
操作前:L
0
1 Li 18
2 He 20 ^
步骤3:生成新结点,将数据放入结点,插入到链表中。
p=L; k=0;
while(k<i-1 && p!=NULL){k++; p=p->next;}
if(k>i-1 || p==NULL) { printf(“位置非法,不能插入\n”);
return 0;
}
s=new NODE; s->data=x;
s->next=p->next; p->next=s;
操作前:L
1 Li 18
2 He 20 ^
操作后:L
1 Li 18
2 He 20 ^
liu 19
第7页/共22页
插入操作
例:在i=2的位置上插入学生数据x(liu,19)
操作前:L
0
1 Li 18
2 He 20 ^
步骤1: 用工作指针p记住第i-1个结点的地址 用k记p指向的结点序号
L
p K=0 p K=1
删除函数(1)
int deleteLink(LINK L, int i)
{ LINK p,q; int k; if(L->next==NULL)return 0;
p=L; k=0;
while(p->next!=NULL && k<i-1)
{k++; p=p->next;}
if(p->next==NULL || k>i-1)
if(L==NULL)return 0; L->next=NULL; return 1; }
第5页/共22页
插入操作
功能:在指定位置插入一个新的结点
已知条件: 链表的头指针,插入的位置,插入的数据 操作的结果: 链表上多了一个结点,链表的头指针没有改 变。
第6页/共22页
插入操作
例:在i=2的位置上插入学生数据x(liu,19)
第13页/共22页
删除操作
例:删除在i=1的位置上的学生
操作前:L
0
1 Li 18
2 He 20 ^
步骤1: 用工作指针p记住第i-1个结点的地址
用k记p指向的结点序号
L
p K=0
Li 18
He 20 ^
p=L; k=0; while(p->next!=NULL && k<i-1 )
{ k++; p=p->next; } 第14页/共22页
{ printf(“位置非法,不能删除\n”);
return 0; } q= p->next; p->next =q->next; delete q;
return 1;
}
第17页/共22页
删除函数(2)
int deleteLink(LINK L, int i, STU &x)
{ LINK p,q; int k; if(L->next==NULL)return 0;
p=L; k=0;
while(p->next!=NULL && k<i-1) 用引用变量x
{k++; p=p->next;} 带出被删除学
if(p->next==NULL || k>i-1)
删除操作
例:删除i=1位置上的结点
操作前:L
0
1 Li 18
2 He 20 ^
பைடு நூலகம்
步骤2: 判断能否进行删除。如果i<1,会出现k>i-1,不能
删除;如果i>=3,会出现p->next为空,不能删除
L
p K=0
Li 18
He 20 ^
if(p->next==NULL || k>i-1)
printf(“位置非法,不能删除\0”);
带头结点的单向链表的基本操作
初始化
插入 一个基本操作对应一个函数
删除 遍历 假定链表上存放的是学生的数据(姓名,年龄)
L
Li 18
He 20 ^
第1页/共22页
链表操作所需自定义的数据类型
学生数据(姓名,年龄)
typedef struct
{
char name[20]; //存放姓名
int age;
//存放年龄
}STU;
注意:上面省略了结构体名
第2页/共22页
链表操作所需自定义的数据类型
结点类型(学生数据类型,指针类型)
指向结点的指针类型
typedef struct node
{
STU data;
//存放学生数据
struct node *next; //存放下一个结点地址
}NODE, *LINK;
第15页/共22页
删除操作
例:删除i=1位置的学生
操作前:L
0
1 Li 18
2 He 20 ^
步骤3:删 点除 空p间L指向结p点的K=下0 一个结q 点①q,回收q指向的结
Li 18
He 20 ^

q= p->next; //①
p->next =q->next; //②
delete q;
第16页/共22页
L
p K=0 p K=1
Li 18
He 20 ^


s=new NODE; s->data=x;
s liu 19
s->next=p->next;//①
p->next=s;//②
第10页/共22页
插入函数
int insertLink(LINK L, int i, STU x)
{ LINK p,s; int k;
return 1; }
第11页/共22页
删除操作
功能:将指定位置上的结点删除 已知条件: 链表的头指针,删除的位置 操作的结果: 链表上少了一个结点,链表的头指针没有 改变。
第12页/共22页
删除操作
例:删除位置为i=1的结点
操作前:L
1 Li 18
操作后:L
1 He 20 ^
2 He 20 ^
相关文档
最新文档