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

湖南第一师范学院信息科学与工程系实验报告课程名称:数据结构与算法成绩评定:实验项目名称:单链表的基本操作指导教师:学生姓名:沈丽桃学号: 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单链表基本操作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函数实现问题要求。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 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);
}。