单循环链表基本操作

合集下载

单链表的基本操作实验报告

单链表的基本操作实验报告

湖南第一师范学院信息科学与工程系实验报告课程名称:数据结构与算法成绩评定:实验项目名称:单链表的基本操作指导教师:学生姓名:沈丽桃学号: 10403080118 专业班级: 10教育技术实验项目类型:验证实验地点:科B305 实验时间: 2011 年 10 月20 日一、实验目的与要求:实验目的:实现线性链表的创建、查找、插入、删除与输出。

基本原理:单链表的基本操作二、实验环境:(硬件环境、软件环境)1.硬件环境:奔ⅣPC。

2.软件环境:Windows XP 操作系统,TC2.0或VC++。

三、实验内容:(原理、操作步骤、程序代码等)#include<stdio.h>#include<stdlib.h>#include<malloc.h>struct celltype{int element;struct celltype*next;};typedef int position;void main(){struct celltype*head,*p;int x,choice;void INSERT(int x,struct celltype*p);void LOCATE(int x,struct celltype*p);void DELETE(int x,struct celltype*p);p=(struct celltype*)malloc(sizeof(struct celltype));head=p;p->element=0;p->next=NULL;printf(“Please option:1:Insert 2:Locate 3:Delete\n”);printf(“Please choose:”);scanf(“%d”,&choice);switch(choice)case 1:printf(“Please input a node:”);scanf(“%d”,&x);p=head;INSERT(x,p);for(p=head;p!=NULL;p=p->next)printf(“%d”,p->element);printf(“\n”);break;case 2:printf(“Please input the data you want to locate:”); scanf(“%d”,&x);p=head;LOCATE(x,p);break;case 3:printf(“Please input the data you want to delete:”); scanf(“%d”,&x);DELETE(x,p);for(p=head;p!=NULL;p=p->next)printf(“%d”,p->next);printf(“\n”);break;}void INSERT(int x,struct celltype*p){struct celltype*t,*q;q=(struct celltype*)malloc(sizeof(struct celltype)); q->next=x;while((x>p->element)&&(p!=NULL)){t=p;p=p->next;}if((x>p->element)&&(p->next!=NULL)){p->next=q;q->next=NULL;}else{q->next=p;t->next=q;}}void LOCATE(int x,struct celltype*p){while(p->next!=NULL)if(p->next->element==x)printf(“the number %d is in %d\n”,x,p);else printf(“the number not exist!\n”);}void DELETE(int x,struct celltype*p){while((p->element!=x)&&(p->next!=NULL)){t=p;p=p->next;}if(p->element==x)t->next=p->next}error C2018:unknown character ’Oxal’error C2065:’Please’:undeclared identifiererror C4024:’printf’:different types for formal and actual parameter 1error C4047:’function’:’const*differs in levers of indirection from ’int’error C2146:syntaxerror:missing’)’before identifier’option’error C2017:illegal escape sequenceerror C2059:syntax error:’)’error C2143:syntax error:missing’)’before’%’出现了很多错误,主要是因为printf里的一对双引号不是英文状态下的。

单链表的基本操作

单链表的基本操作

10)调用头插法的函数,分别输入10,20,分别回车:
11)调用尾插法的函数,分别输入30,40
12)查找单链表的第四个元素:
13)主函数中传入参数,删除单链表的第一个结点:
14)主函数传入参数,删除第0个未位置的元素,程序报错:
15)最后,输出单链表中的元素:
return 0;
}
6)编译,连接,运行源代码:
7)输入8,回车,并输入8个数,用空格分隔开,根据输出信息,可以看出,链表已经拆分为两个
五、实验总结
1.单链表采用的是数据+指针的表示形式,指针域总是指向下一个结
点(结构体)的地址,因此,在内存中的地址空间可以是不连续的,操作比顺序存储更加的方便
2.单链表使用时,需要用malloc函数申请地址空间,最后,删除元
素时,使用free函数释放空间。

PTA7-4单链表基本操作

PTA7-4单链表基本操作

PTA7-4单链表基本操作7-4 单链表基本操作请编写程序实现单链表插⼊、删除结点等基本算法。

给定⼀个单链表和⼀系列插⼊、删除结点的操作序列,输出实施上述操作后的链表。

单链表数据域值为整数。

输⼊格式:输⼊第1⾏为1个正整数n,表⽰当前单链表长度;第2⾏为n个空格间隔的整数,为该链表n个元素的数据域值。

第3⾏为1个正整数m,表⽰对该链表施加的操作数量;接下来m⾏,每⾏表⽰⼀个操作,为2个或3个整数,格式为0 k d或1 k。

0 k d表⽰在链表第k个结点后插⼊⼀个数据域值为d的结点,若k=0则表⽰表头插⼊。

1 k表⽰删除链表中第k个结点,此时k不能为0。

注:操作序列中若含有不合法的操作(如在长度为5的链表中删除第8个结点、删除第0个结点等),则忽略该操作。

n和m不超过100000。

输出格式:输出为⼀⾏整数,表⽰实施上述m个操作后的链表,每个整数后⼀个空格。

输⼊数据保证结果链表不空。

输⼊样例:51 2 3 4 550 2 80 9 60 0 71 01 6输出样例:7 1 2 8 3 5参照课本的实现#include<iostream>#include<iomanip>#include<stdlib.h>using namespace std;typedef int ElemType;typedef int Status;#define ERROR 0#define OK 1#define OVERFLOW 3typedef struct LNode{ElemType data;struct LNode *next;}LNode ,*LinkList;Status ListInsert(LinkList L,int i,ElemType e){int j=0;LinkList p=L,s;while(p&&j<i-1) // 寻找第i-1个结点{p=p->next;j++;}if(!p||j>i-1) // i⼩于1或者⼤于表长return ERROR;s=(LinkList)malloc(sizeof(LNode)); // ⽣成新结点s->data=e; // 插⼊L中s->next=p->next;p->next=s;return OK;}Status ListDelete(LinkList L,int i){int j=0;LinkList p=L,q;while(p->next&&j<i-1) // 寻找第i个结点,并令p指向其前趋{p=p->next;j++;}if(!p->next||j>i-1) // 删除位置不合理return ERROR;q=p->next; // 删除并释放结点p->next=q->next;free(q);return OK;}int main(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);LinkList L;L=(LinkList)malloc(sizeof(LNode)); // 产⽣头结点,并使L指向此头结点 if(!L) // 存储分配失败exit(OVERFLOW);L->next=NULL;int n=0,m=0;LinkList db=L,da;cin>>n;for(int i=0;i<n;i++){da=(LinkList)malloc(sizeof(LNode));cin>>da->data;da->next=NULL;db->next=da;db = da;}cin>>m;for(int i=0;i<m;i++){int o,x,y;cin>>o;if(o==0){cin>>x>>y;ListInsert(L,x+1,y);}else if(o==1){cin>>x;ListDelete(L,x);}else{exit(ERROR);}}LinkList p=L->next;while(p!=NULL){cout<<p->data<<" ";p = p->next;}return 0;}。

循环单链表

循环单链表

循环单链表循环单链表是一种特殊的单链表,它的最后一个节点的指针指向第一个节点,形成一个环。

它具有单链表独有的优点,同时又克服了单链表存在的缺点。

因此,循环单链表在实际应用中受到了极大的欢迎。

本文介绍了循环单链表的概念,结构特性和实现功能,并分析了其与普通单链表的区别。

1.环单链表的概念循环单链表,也叫循环链表,是一种特殊的单链表,它的最后一个节点的指针指向第一个节点,形成一个环。

循环链表的结构比普通的单链表略有不同,其头结点的next域指向头节点,该结构最显著的特点就是头节点的“上一个”节点和最后一个节点“下一个”节点都是头结点,所以可以利用循环链表来实现双向链表的操作。

2.环单链表的结构特性循环单链表是一种特殊的单链表,其最后一个节点指针指向头结点,从结构上来看,它具有单链表的特点,如指针存储结构、节点为一个结构体成员以及只有单向指针,但又与普通单链表不同,它的结构特征有:(1)头结点的next域指向自身;(2)最后一个节点的next域也指向头结点;(3)整个结构类似一个拥有多叉指针的环形结构体。

3.环单链表的实现功能循环单链表的实现功能包括插入、删除、查找等,这些基本操作的实现和普通单链表的实现方法基本相同,只是有一些细节的不同。

例如,在普通单链表的删除操作中,如果需要删除的节点是链表的最后一个节点,则需要修改链表的尾指针,但是在循环单链表中,只需要修改头结点的next域指向,就可以实现操作。

4.与普通单链表的区别循环单链表有一些独特的结构特点,同时又克服了普通单链表的缺点,因此在实际应用中受到了极大的欢迎。

(1)普通单链表无法实现双向遍历,而循环单链表可以实现双向遍历和遍历,因为它有头结点和最后一个节点,所以可以实现双向遍历,再加上其结构特点,可以实现对双向链表的操作。

(2)普通单链表遍历需要维护一个辅助指针,而循环单链表则不需要,只需要从头结点开始,依次访问每一个节点,直到头结点。

结论:循环单链表是一种特殊的单链表,它的结构特征是头结点的next域指向头结点,最后一个节点的next域也指向头结点,它克服了普通单链表的缺点,可以实现双向遍历,同时又不需要维护辅助指针,因此广泛应用在实际工程中。

单链表基本操作的实现

单链表基本操作的实现

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

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

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

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:插入节点时如何确保正确的位置?对策:在插入节点之前,需要遍历链表以找到正确的位置。

可以使用循环来遍历链表,确保插入的位置是正确的。

另外,可以考虑维护一个指向前一个节点的指针,以便在插入时更容易操作。

问题2:如何删除节点?对策:删除节点时,需要找到待删除节点的前一个节点,并将其指针指向待删除节点的下一个节点,然后释放待删除节点的内存。

确保在删除节点之前释放内存,以避免内存泄漏。

问题3:如何遍历链表?对策:遍历链表通常需要使用循环,从链表的头节点开始,沿着指针依次访问每个节点,直到达到链表的末尾。

可以使用循环结构来实现遍历,或者使用递归方法。

带头节点的循环单链表

带头节点的循环单链表

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

单链表的 基本操作

单链表的 基本操作

单向链表单向链表的基本操作,创建一个由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函数实现问题要求。

单链表的基本运算

单链表的基本运算
{ Node *s; char c; int flag=1; while(flag) /* flag 初值为 1,当输入“$”时,置 flag 为 0,
建表结束*/ { c=getchar(); if(c!=’$’) { s=(Node*)malloc(sizeof(Node)); /*建立新结点 s*/ s->data=c; s->next=L->next; /*将 s 结点插入表头*/ L->next=s; } else flag=0;
3. 结果判断 如找到第 i 个结点,则返回结点 p;
如表查完未找到,则返回空。
【算法描述】
Node * Get (LinkList L, int i) / * 在带头结点的单链表 L 中查找第 i 个结点,若找到(1≤i≤n),则返回 该结点的存储位置; 否则返回 NULL * / { int j;
【算法描述】
int ListLength(LinkList L)
/*求带头结点的单链表 L 的长度*/
{ Node *p;
p=L->next;
j=0; /*用来存放单链表的长度*/
while(p!=NULL)
{
p=p->next;
j ++;
}
return j; /*j 为求得的单链表长度*/
} /* ListLength */
H

s r
(a)初始化的空表
C1 ∧
(b)申请新结点并赋值
s 指向新申请的结点空间;
s->data:=C1
H
c1 ∧
r
(c)插入第一个结点
s
① r->next=s;
c1 H

实验二 单链表基本操作

实验二 单链表基本操作

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

链表(单链表 双向循环)实验报告讲解

链表(单链表 双向循环)实验报告讲解

数据结构实验报告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. 结构示意图在不带头结点但仅有尾结点指针标识的循环单链表中,每个结点由两部分组成:数据域和指针域。

数据域存储结点的数据信息,指针域存储下一个结点的位置区域指针。

而尾结点指针则特殊指向第一个结点,形成循环。

示例:->==>->==>--->二、基本操作和应用场景1. 插入操作在不带头结点但仅有尾结点指针标识的循环单链表中,插入操作需要特殊处理。

因为没有头结点,我们无法很方便地找到链表的起始位置。

为了解决这个问题,我们可以利用尾结点指针来辅助定位新结点的插入位置。

具体步骤如下:a)创建新结点并赋值;b)判断链表是否为空,如果为空则将新结点的指针域指向自身,并将尾结点指针指向新结点;c)如果链表不为空,找到尾结点,将尾结点的指针域指向新结点,并更新尾结点指针为新结点。

2. 删除操作在不带头结点但仅有尾结点指针标识的循环单链表中,删除操作同样需要特殊处理。

为了解决删除操作的问题,我们需要在遍历链表时记录当前结点和上一个结点的信息,以便进行删除操作。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

链表基本操作

链表基本操作

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

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

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

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

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

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

然后通过动态内存分配函数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. 定义单链表结构体: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、理解和掌握单链表的类型定义方法和结点生成方法。

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带回。

单链表的实现及其基本操作

单链表的实现及其基本操作

单链表的实现及其基本操作结点的引⼊链表是⼀种链式存储结构,链式存储结构的特点是⽤⼀组任意的存储单元存储数据元素。

为了能正确表⽰数据元素之间的线性关系,需引⼊结点概念。

⼀个结点表⽰链表中的⼀个数据元素,节点中除了储存数据元素的信息,还必须存放指向下⼀个节点的的指针(单、双链表的最后⼀个节点除外,它们存储的是⼀个空指针NULL)结点的结构如下图所⽰:代码如下:1 typedef struct node{2int data;3struct node* pNext;4 }Node, *PNode;View Code注:这⾥假设结点中储存的是整型 (int) 的数据单链表由多个结点依次连接⽽成,我们不难想象出它结构:我们注意到:在第⼀个结点的前⾯多了⼀个头结点,这是为了处理空表的⽅便⽽引⼊的,它的指针指向链表的第⼀个结点,⽽它的data域不存放任何信息。

单链表的基本操作1.创建链表1 PNode createList()2 {3int len, value;45 PNode pHead = (PNode)(malloc(sizeof(Node)));6 PNode pTail = pHead;7 pTail->pNext = NULL;89 printf("请输⼊你要的节点个数:");10 scanf("%d", &len);11for(int i=1;i<=len;i++){12 printf("请输⼊第%d个节点的值:", i);13 scanf("%d", &value);1415 PNode pNew = (PNode)malloc(sizeof(Node));16 pNew->data = value;17 pTail->pNext = pNew;18 pTail = pNew;19 pTail->pNext = NULL;20 }2122return pHead;23 }View Code2.遍历链表void traverse(PNode pHead){printf("遍历结果为:\n");PNode pTra = pHead;while(pTra->pNext != NULL){printf("%d ", pTra->pNext->data);pTra = pTra->pNext;}printf("\n");}View Code3.判断链表是否为空1bool isEmpty(PNode pHead)2 {3if(pHead->pNext==NULL)4return true;5else6return false;7 }View Code4.链表长度1int length(PNode pHead)2 {3int len = 0;4while(pHead->pNext!=NULL){5 pHead = pHead->pNext;6 len++;7 }8return len;910 }View Code5.插⼊结点1bool insert(PNode pHead, int pos, int val)2 {3if(pos<1 || pos>length(pHead)){4return false;5 }else{6 PNode pInsert = pHead;7for(int i=1;i<pos;i++){8 pInsert = pInsert->pNext;9 }1011 PNode pNew = (PNode)malloc(sizeof(Node));12 pNew->data = val;13 pNew->pNext = pInsert->pNext;14 pInsert->pNext = pNew;1516return true;17 }1819 }View Code6.删除结点1bool del(PNode pHead, int pos)2 {3if(pos<1 || pos>length(pHead)){4return false;5 }else{6 PNode pDel = pHead;7for(int i=1;i<pos;i++){8 pDel = pDel->pNext;9 }1011if(pos==length(pHead)){12free(pDel->pNext);13 pDel->pNext = NULL;14 }else{15 PNode pNext = pDel->pNext->pNext;16free(pDel->pNext);17 pDel->pNext = pNext;18 }1920return true;2122 }232425 }View Code7.查找节点(1)按元素值查找1 PNode locate(PNode pHead, int value)2 {3 PNode p = pHead->pNext;4while(p&&p->data!=value){ //NULL 是 05 p = p->pNext;6 }7return p;8 }View Code(2)按序号查找1 PNode get(PNode pHead, int k)2 {3 PNode p = pHead;4for(int i=1;i<=k;i++){5 p = p->pNext;6 }7return p;89 }View Code完整代码1 #include<stdio.h>2 #include<stdlib.h>3 typedef struct node{4int data;5struct node* pNext;6 }Node, *PNode;78 PNode createList();9void traverse(PNode pHead);10bool isEmpty(PNode pHead);11int length(PNode pHead);12bool insert(PNode pHead, int pos, int val);13bool del(PNode pHead, int pos);14 PNode get(PNode pHead, int k); //按序号查找15 PNode locate(PNode pHead, int value);//按值查找 1617int main(void)18 {19//test2021return0;22 }2324 PNode createList()25 {26int len, value;2728 PNode pHead = (PNode)(malloc(sizeof(Node)));29 PNode pTail = pHead;30 pTail->pNext = NULL;3132 printf("请输⼊你要的节点个数:");33 scanf("%d", &len);34for(int i=1;i<=len;i++){35 printf("请输⼊第%d个节点的值:", i);36 scanf("%d", &value);3738 PNode pNew = (PNode)malloc(sizeof(Node));39 pNew->data = value;40 pTail->pNext = pNew;41 pTail = pNew;42 pTail->pNext = NULL;43 }4445return pHead;46 }474849void traverse(PNode pHead)50 {51 printf("遍历结果为:\n");52 PNode pTra = pHead;53while(pTra->pNext != NULL)54 {55 printf("%d ", pTra->pNext->data);56 pTra = pTra->pNext;57 }58 printf("\n");59 }6061bool isEmpty(PNode pHead)62 {63if(pHead->pNext==NULL)64return true;65else66return false;67 }6869int length(PNode pHead)70 {71int len = 0;72while(pHead->pNext!=NULL){73 pHead = pHead->pNext;74 len++;75 }76return len;7778 }7980bool insert(PNode pHead, int pos, int val)81 {82if(pos<1 || pos>length(pHead)){83return false;84 }else{85 PNode pInsert = pHead;86for(int i=1;i<pos;i++){87 pInsert = pInsert->pNext;88 }8990 PNode pNew = (PNode)malloc(sizeof(Node));91 pNew->data = val;92 pNew->pNext = pInsert->pNext;93 pInsert->pNext = pNew;9495return true;96 }9798 }99100bool del(PNode pHead, int pos)101 {102if(pos<1 || pos>length(pHead)){103return false;104 }else{105 PNode pDel = pHead;106for(int i=1;i<pos;i++){107 pDel = pDel->pNext;108 }109110if(pos==length(pHead)){111free(pDel->pNext);112 pDel->pNext = NULL;113 }else{114 PNode pNext = pDel->pNext->pNext;115free(pDel->pNext);116 pDel->pNext = pNext;117 }118119return true;120121 }122123124 }125126 PNode get(PNode pHead, int k)127 {128 PNode p = pHead;129for(int i=1;i<=k;i++){130 p = p->pNext;131 }132return p;133134 }135 PNode locate(PNode pHead, int value)136 {137 PNode p = pHead->pNext;138while(p&&p->data!=value){ //NULL 是 0 139 p = p->pNext;140 }141return p;142 }View Code。

单链表的类型定义与基本操作

单链表的类型定义与基本操作

• 基本思想
• 找到第i个结点 • 从单链表上摘除该结点(修改某些结点的指针域)
L
a1
… ai-1
× ai
ai+1

a NULL
n
L
a1
… ai-1
ai+1

a NULL
n
12
• 算法
void delete_lklist(lklist &l , int i)
{ lklist p,q;
p=find_lklist(l, i-1);
• C语言类型描述
typedef struct node{
datatype
data; /*数据元素类型*/
struct node *next; /*指针类型*/
} node, * lklist; /*结点类型*/
• node是结点类型 • lklist是指向node类型的指针
1
二、一些基本操作
1. 初始化 initiate_lklist(l)
else printf("不存在第i个结点");
}
13
}
return (j); }
3
3. 按序号查找 find_lklist(l, i) • 定义
• 查找单链表第i个元素,否则返回NULL
• 基本思想
• 从头指针出发,顺链域next逐个往下搜索,直到 找到第i个结点为止
4
• 算法
node *find_lklist(lklist l, int i)
{ lklist p=l;
e
ai

a1n0 NULL
• 算法
void insert_lklist(lklist &l , datatype x, int i)

链表基本操作实验报告

链表基本操作实验报告

实验2链表基本操作实验一、实验目的1. 定义单链表的结点类型。

2. 熟悉对单链表的一些基本操作和具体的函数定义。

3. 通过单链表的定义掌握线性表的链式存储结构的特点。

二、实验内容与要求该程序的功能是实现单链表的定义和主要操作。

女口:单链表建立、输出、插入、删除、查找等操作。

该程序包括单链表结构类型以及对单链表操作的具体的函数定义和主函数。

程序中的单链表(带头结点)结点为结构类型,结点值为整型。

要求:同学们可参考指导书实验2程序、教材算法及其他资料编程实现单链表相关操作。

必须包括单链表创建、输出、插入、删除操作,其他操作根据个人情况增减。

三、算法分析与设计。

1•创建单链表:头结点LA1 A2An A2.单链表插入void LinkedListlnsert(LinkedList L,int i,ElemType x) 链表插入函数(L头指针,i插入位置,x插入兀素)LinkedList p,s;疋义结构体类型指针p,sj=1;p=L;疋义整型j计数,寻找插入位置,p指针指向头结点p=p->next;j++; 满足条件时p指针后移,j自加1while(p&&j<i) 当p为真且j<i时循环j 〜____ p=NULL||j<i一一printf("插入位置不正确\n");s=(LNode *)malloc(sizeof(LNode));使用malloc函数动态分配存储空间,指针s指向新开辟的结点,并将插入元素x存放到新开辟结点s的数据域,将结点s指向i+1 结点位置,第i个结点指向s,实现了链表元素插入。

by1s->data=x; s->n ext=p->n ext; p->n ext=s;3.单链表的删除:p->n ext=p->n ext- >n ext;15 x=表 -俞弹i tl 度 書翁的琴素汕6.从链表中查找元素四、运行结果1.单链表初始化骨选择夷进行的操作、遍历链表 J 从链表中査找元素1.如程輕巴章兰与竽疋匹菇值里同門元素在顺序aw 位置 迥链五Fs 已元壽上也库吏卬删除更10^5^性表 毒他键退出。

使用循环单链表表示队列

使用循环单链表表示队列

使用循环单链表表示队列队列是一种常见的数据结构,它遵循先进先出(FIFO)的原则,即先进入队列的元素将先被取出。

队列通常用于需要按照顺序处理数据的场景,比如任务调度、消息传递等。

在实际应用中,我们可以使用循环单链表来表示队列。

循环单链表是一种链表结构,它与普通的单链表相比,最后一个节点的指针域不为空,而是指向链表的头结点。

这样一来,在遍历链表时可以很方便地回到链表的起始位置。

对于队列来说,使用循环单链表可以更高效地实现入队和出队的操作。

下面我们来具体讨论如何使用循环单链表来表示队列。

我们需要定义一个循环单链表节点的结构。

该结构包含一个数据域和一个指针域,分别指向下一个节点。

代码如下:```cppstruct Node {int data;Node* next;};```接下来,我们定义一个队列类,该类包含队列的基本操作,如入队、出队、判断队列是否为空等。

代码如下:```cppclass Queue {private:Node* front; // 队头指针Node* rear; // 队尾指针public:Queue() {front = rear = nullptr; // 初始化队头和队尾指针为空 }~Queue() {// 释放队列中的所有节点while (!isEmpty()) {dequeue();}}// 入队操作void enqueue(int value) {Node* newNode = new Node;newNode->data = value;newNode->next = nullptr;if (isEmpty()) {front = rear = newNode; // 队列为空,队头和队尾指针指向新节点} else {rear->next = newNode; // 将新节点链接到队尾rear = newNode; // 更新队尾指针}}// 出队操作void dequeue() {if (isEmpty()) {throw "Queue is empty!";}Node* temp = front;front = front->next; // 更新队头指针if (front == nullptr) {rear = nullptr; // 队列只有一个节点,出队后队尾指针为空}delete temp; // 释放出队节点的内存 }// 判断队列是否为空bool isEmpty() {return front == nullptr;}// 获取队头元素int getFront() {if (isEmpty()) {throw "Queue is empty!";}return front->data;}// 获取队列长度int getSize() {int size = 0;Node* current = front;while (current != nullptr) {size++;current = current->next;}return size;}};```使用循环单链表表示队列的好处是,入队和出队的时间复杂度都是O(1),即常数时间。

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

/*1、CreateList( ):创建一个带头结点的空的单循环链表;
2、InsertList( ):输入一组数据,以0表示输入结束, 并依次建立各个元素结点,逐个插入到单循环链表尾
3、DeleteList( ):删除单循环链表的从第i个数据元素开始的m个数据元素,同时释放被删结点空间
4. ListPrint( ):将单向循环链表的数据元素从表头到表尾依次显示
5. DevList( ):将此单循环链表拆分成两个单循环链表,其中一个包含所有的数据元素为偶数的结点,
另一个包含所有的数据元素为奇数的结点.*/
#include<stdio.h>
#include<stdlib.h>
typedef struct node{
int data;
struct node *next;
}LNode,*linklist;
void createlist(linklist &L)
{linklist p=L;
p->next=p;
}
void insertlist(linklist &L)
{int x;
linklist p=L,q;
scanf("%d",&x);
while(x!=0)
{q=(linklist)malloc(sizeof(LNode));
q->data=x;q->next=NULL;
p->next=q;
p=q;
scanf("%d",&x);
}
q->next=L;
}
void printlist(linklist L)
{linklist p=L->next ;
if(p==L)printf("这是一个空表!\n");
while(p!=L){printf("%2d",p->data);p=p->next;}
printf("\n");
}
void deletelist(linklist &L,int i,int m)
{linklist p=L,q;
for(int n=1;n<i;n++)
{p=p->next;
if(p==L)p=p->next;
}
q=p->next;
for(n=0;n<m;n++)
if(q!=L)
{p->next=q->next;
free(q);
q=p->next;
}
else
{q=q->next;
L->next=q->next;
free(q);
q=L->next;
p=L;
}
}
void devlist(linklist L,linklist &La,linklist &Lb) {linklist p=L->next,pa=La,pb=Lb,q;
while(p!=L)
{ if((p->data)%2==0)
{q=(linklist)malloc(sizeof(LNode));
q->data=p->data;
pa->next=q;
pa=q;
}
else
{q=(linklist)malloc(sizeof(LNode));
q->data=p->data;
pb->next=q;
pb=q;
}
p=p->next;
}
pa->next=La;
pb->next=Lb;
}
void main()
{//int i,m;
linklist L,La,Lb;
L=(linklist)malloc(sizeof(LNode));
La=(linklist)malloc(sizeof(LNode));
Lb=(linklist)malloc(sizeof(LNode));
createlist(L);
printf("请输入一组数据, 并以0表示输入结束:\n"); insertlist(L);
printf("单循环链表的数据元素从表头到表尾依次为:\n");
printlist(L);
/*printf("\n请分别输入i、m的值:\n");
scanf("%d%d",&i,&m);
deletelist(L,i,m);
printf("删除操作后的单循环链表的数据元素从表头到表尾依次为:\n"); printlist(L);*/
devlist(L,La,Lb);
printf("拆分后,单循环链表a的数据元素从表头到表尾依次为:\n"); printlist(La);
printf("拆分后,单循环链表b的数据元素从表头到表尾依次为:\n"); printlist(Lb);
}。

相关文档
最新文档