单链表的建立及插入删除操作-c语言
- 格式:doc
- 大小:14.50 KB
- 文档页数:3
单链表的删除与插入源程序如下:#include<stdio.h>#include<malloc.h>#include<windows.h>typedef int elemtype;typedef struct LNode //定义单链表存储类型{elemtype data;struct LNode *next;}linklist;void creatlistf(linklist *&L ) //建立链表{linklist *s;int i;elemtype a[10];printf("请输入10个数:\n");for(i=0;i<10;i++)scanf("%d",&a[i]);L=(linklist *)malloc(sizeof(linklist));L->next=NULL;for(i=0;i<10;i++){s=(linklist *)malloc(sizeof(linklist));s->data=a[i];s->next=L->next;L->next=s;}}void displist(linklist *L) //输出单链表{linklist *s;s=L->next;while(s!=NULL){printf(" %d",s->data);s=s->next;}printf("\n");}void listinsert(linklist *L) //插入元素{int i=0,j,m;linklist *s,*p;printf("请输入插入位置:");scanf("%d",&j);printf("请输入需插入元素:");scanf("%d",&m);s=L;while(i<j-1 && s!=NULL){s=s->next;i++;}if(s==NULL)printf("输入错误!\n");else{p=(linklist *)malloc(sizeof(linklist)); p->data=m;p->next=s->next;s->next=p;}}void listdelete(linklist *&L)//删除元素{int i,j=0,e;printf("请输入需删除第几个元素:"); scanf("%d",&i);linklist *s;s=L;while(j<i-1&&s!=NULL){s=s->next;j++;}if(s->next==NULL)printf("输入错误!\n");else{if(s->next->next!=NULL){e=s->next->data;s->next->data=s->next->next->data;s->next->next=s->next->next->next;printf("成功删除元素%d\n",e);}else if(s->next!=NULL&&s->next->next==NULL){printf("成功删除元素%d\n",s->next->data);free(s->next);s->next=NULL;}else{printf("&&&&&&&&&");printf("输入错误!\n");}}}void main(){printf(" ***************欢迎使用单链表基本运算系统********************\n"); linklist *p;int m;creatlistf(p); //建立链表printf("单链表已建立完毕\n");while(1){printf("请选择:");printf(" 1.输出链表\n");printf(" 2.插入元素\n");printf(" 3.删除元素\n");printf(" 4.退出\n");scanf("%d",&m);switch(m){case 1:displist(p);break;case 2:listinsert(p);break;case 3:listdelete(p);break;case 4:exit(0);default:printf("输入错误\n");}}}运行效果如下:。
单链表基本操作的实现单链表是一种常见的数据结构,它由多个节点组合而成,每个节点包含一个数据元素和一个指向下一个节点的指针。
通过指针,我们可以方便地在单链表中进行插入、删除和遍历等操作。
以下是关于单链表基本操作的实现。
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. 单链表的删除单链表的删除可以分为在链表头部删除、在链表尾部删除和在链表中间删除三种情况。
c语⾔数据结构之单链表的插⼊和删除操作1,定义⼀个单链表基础定义先了解⼀下:struct LNode{ //定义单链表结点类型ElemType data; //每个节点存放⼀个数据元素struct LNode *next; //指针指向下⼀个节点}LNode,*LinkList;/*struct LNode *p=(struct LNode*)malloc(sizeof(struct LNode)); //增加⼀个新的结点,在内存中申请⼀个结点所需的空间,并⽤指针p 指向这个结点*/LNode *GetElem(LinkList L,int i){int j=1;LNode *p=L->next;if(i==0)return L;if(i<1)return NULL;while(p!=NULL&&j<i){p=p->next;j++;}return p;}上述代码*LNode GetElem(LinkList L,int i)中需要注意的是:若强调这是⼀个单链表,使⽤ LinkList;若强调这是⼀个结点,则使⽤LNode *。
1,不带头结点的单链表struct LNode{ //定义单链表结点类型ElemType data; //每个节点存放⼀个数据元素struct LNode *next; //指针指向下⼀个节点}LNode,*LinkList;bool InitList(LinkList &L){ //初始化⼀个单链表L=NULL; //空表,防⽌脏数据return true;}void test(){LinkList L; //声明⼀个指向单链表的指针//初始化⼀个空表InitList(L);//.....}2,带头结点的单链表struct LNode{ //定义单链表结点类型ElemType data; //每个节点存放⼀个数据元素struct LNode *next; //指针指向下⼀个节点}LNode,*LinkList;//初始化⼀个单链表bool InitList(LinkList &L){L=(LNode *)malloc(sizeof(LNode)); //分配⼀个头结点if(L==NULL) //内存不⾜,分配失败return false;L->next=NULL; //头结点之后暂时还没有结点return true;}//判断单链表是否为空(带头结点)bool Empty(LinkList L){if(L-next==NULL)return true;elsereturn false;}void test(){LinkList L; //声明⼀个指向单链表的指针//初始化⼀个空表InitList(L);//.....2,单链表的基本操作1,插⼊1,按位序插⼊(ListInsert(&L,i,e))在第i 个位置插⼊元素e (带头结点)bool ListInsert(LinkList &L,int i,ElemType e){if(i<1)return false;LNode *p; //指针p 指向当前扫描到的节点int j=0; //当前p指向的是第⼏个结点p=L; //L指向头结点,头结点是第0 个结点(不存数据)while(p!=NULL&&j<i-1){ //循环找到第i-1个结点p=p->next;j++;}if(p==NULL) //i 值不合法return false;LNode *s=(LNode *)malloc(sizeof(LNode));s->data=e;s->next=p->next;p->next=s; //将结点s 连到p 之后return true; //插⼊成功}不带头结点的:(不存在 “第0个“ 结点)实现代码如下:bool ListInsert(LinkList &L,int i,ElemType e){if(i<1)return false;if(i==1){ //插⼊第1个结点的操作与其他结点操作不同LNode *s=(LNode *)malloc(sizeof(LNode));s->data=e;s->next=L;L=s; //头指针指向新结点return true;}LNode *p; //指针p指向当前扫描到的节点int j=1; //当前p 指向的是第⼏个结点p=L; //p指向第1个结点(注意:不是头结点)while(p!=NULL&&j<i-1){ //循环找到第i-1个结点p=p->next;j++;}if(p==NULL) //i 值不合法return false;LNode *s=(LNode *)malloc(sizeof(LNode));s->data=e;s->next=p->next;p->next=s; //将结点s 连到p 之后return true; //插⼊成功}2,指定结点的后插操作(InsertNextNode(LNode *p,ElemType e)在p 结点之后插⼊元素e :bool InsertNextNode(LNode *p,ElemType e){if(p==NULL)return false;LNode *s=(LNode *)malloc(sizeof(LNode));if(s==NULL) //内存分配失败return false;s->data=e; //⽤结点s保存数据元素es->next=p->next;p->next=s;}3,指定结点的前插操作在p 结点之前插⼊**元素e **:bool InsertPrioNode(LNode *p,ElemType e){if(p==NULL)return false;LNode *s=(LNode *)malloc(sizeof(LNode));if(s==NULL) //内存分配失败return false;s->next=p->next;p->next=s; //新结点s 连接到p 之后s->data=p->data; //将p 中元素复制到s 中p->data=e; //p 中元素覆盖为ereturn true;}结合下图在体会⼀下:下⾯再看⼀下在p 结点之前插⼊**结点s **:bool InsertPrioNode(LNode *p,ElemType e){if(p==NULL||s==NULL)return false;s->next=p->next;p->next=s; //s 连接到p 之后ElemType temp=p->data; //交换数据域部分p->data=s->data;s->data=temp;return true;}这招偷天换⽇结合下图好好体会⼀下:2,删除1,按位序删除(带头结点)删除表L 中第i 个位置的元素,并⽤e 返回删除元素的值。
单链表的基本操作(C语言)什么是单链表单链表(Singly Linked List)是一种常见的数据结构,它由一系列节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。
每个节点只能访问其后继节点,而无法直接访问前驱节点。
单链表的特点是可以动态地插入和删除节点,相比于数组,具有更好的灵活性和扩展性。
在C语言中,我们可以使用指针来实现单链表。
单链表的基本操作1. 定义单链表结构体在C语言中,我们首先需要定义一个表示单链表的结构体。
结构体包含两个成员:数据元素和指向下一个节点的指针。
typedef struct Node {int data; // 数据元素struct Node *next; // 指向下一个节点的指针} Node;2. 创建单链表创建一个空的单链表需要进行以下步骤:•定义头节点,并初始化为NULL。
•向链表中插入新的节点。
Node* createLinkedList() {Node *head = NULL; // 头节点初始化为NULLint n; // 节点数量printf("请输入要创建的节点数量:");scanf("%d", &n);for (int i = 0; i < n; i++) {int data;printf("请输入第%d个节点的值:", i + 1);scanf("%d", &data);Node *newNode = (Node*)malloc(sizeof(Node)); // 创建新节点newNode->data = data;newNode->next = NULL;if (head == NULL) {head = newNode; // 如果是第一个节点,将其设置为头节点 } else {Node *temp = head;while (temp->next != NULL) {temp = temp->next; // 移动到链表末尾}temp->next = newNode; // 将新节点插入到链表末尾}}return head;}3. 插入节点在单链表中插入一个新的节点需要进行以下步骤:•创建一个新的节点。
数据结构单链表实验报告一、实验目的1、深入理解单链表的数据结构及其基本操作。
2、掌握单链表的创建、插入、删除、查找等操作的实现方法。
3、通过实际编程,提高对数据结构和算法的理解和应用能力。
二、实验环境1、操作系统:Windows 102、编程语言:C 语言3、开发工具:Visual Studio 2019三、实验原理单链表是一种常见的数据结构,它由一系列节点组成,每个节点包含数据域和指针域。
指针域用于指向下一个节点,从而形成链表的链式结构。
单链表的基本操作包括:1、创建链表:通过动态分配内存创建链表的头节点,并初始化链表为空。
2、插入节点:可以在链表的头部、尾部或指定位置插入新的节点。
3、删除节点:根据给定的条件删除链表中的节点。
4、查找节点:在链表中查找满足特定条件的节点。
四、实验内容(一)单链表的创建```cinclude <stdioh>include <stdlibh>//定义链表节点结构体typedef struct Node {int data;struct Node next;} Node;//创建单链表Node createList(){Node head =(Node)malloc(sizeof(Node));if (head == NULL) {printf("内存分配失败!\n");return NULL;}head>data = 0;head>next = NULL;return head;}int main(){Node list = createList();//后续操作return 0;}```在创建单链表时,首先为头节点分配内存空间。
若内存分配失败,则提示错误信息并返回`NULL`。
成功分配内存后,初始化头节点的数据域和指针域。
(二)单链表的插入操作插入操作分为三种情况:头部插入、尾部插入和指定位置插入。
1、头部插入```cvoid insertAtHead(Node head, int data) {Node newNode =(Node)malloc(sizeof(Node));if (newNode == NULL) {printf("内存分配失败!\n");return;}newNode>data = data;newNode>next = head>next;head>next = newNode;}```头部插入时,创建新节点,将新节点的数据域赋值,并将其指针域指向原头节点的下一个节点,然后更新头节点的指针域指向新节点。
单链表的插入、删除、合并等基本操作一、实验目的1、理解数据结构中单链表的定义和建立。
2、掌握单链表中结点结构的C语言描述。
3、熟练掌握单链表的插入、删除和修改等算法的设计与C语言实现。
4、将理论与实际相结合,切实提高自己的逻辑能力和动手能力。
二、设计内容1、输入单链表长度,创建一个单链表。
2、对建立好的单链表进行插入操作。
3、对建立好的单链表进行删除操作。
4、对建立好的单链表进行合并操作。
三、概要设计抽象数据类型线性表的定义如下:ADTA List{数据对象:D={ai I ai∈ElemSet , i=1 ,2 , … , n n>=0 }数据关系:R1={<ai-1 , ai> I ai-1 , ai∈D , i=2 , … , n }基本操作:Creates( &L )操作结果:构建一个空的线性表L。
Insertsl( &L , k ,i)初始条件:线性表L已存在。
操作结果:在带有头结点单链表的第k个元素之前插入元素i。
Deletesl( &L , i, j )初始条件:线性表L已存在。
操作结果:删除指定位置j元素i。
Hebing( &L )初始条件:线性表L已存在。
操作结果:清除新链表中相同的元素。
}ADT List四、算法流程图五、算法源代码#include <stdio.h> #include <malloc.h>typedef struct node {int data;struct node *next; }node;node *head;int k;node * creates(){node *p,*s,*h;int j=1,x, n;p=h=(node*)malloc(sizeof(node));h->next=NULL;printf("请输入链表长度:");scanf("%d",&n);printf("请输入 %d 个数字创建链表:",n);while(j<=n){scanf("%d",&x);s=(node*)malloc(sizeof(node));s->data=x;p->next=s;p=s;j++;}p->next=NULL;return h;}void insertsl(node *head, int k, int i){/*在带有头结点单链表的第k个元素之前插入元素i*/ int j;node *p, *t;p=head;j=0;while ( p&&j<k-1 ) /*若p不指向空,并且没有找到合适位置则继续循环*/ {p = p->next;j++;}if (!p||j>k-1) /*k小于1或大于表长*/printf("插入位置不对。
单链表基本操作在计算机科学里,链表是一种常见的数据结构,它可以用来解决各种复杂的问题。
其中,单链表是最常见的一种,它由一系列节点组成,每个节点包含了一个数据元素和一个指针,指向下一个节点。
这篇文章将介绍单链表的基本操作,包括创建、插入、删除和遍历等。
创建单链表创建单链表是基本操作之一,它有两种方法:头插法和尾插法。
头插法是从链表的头节点开始,逐个将新节点插入。
具体来说,创建一个空链表,设置一个头节点,将头节点的指针指向空;依次输入新节点,将新节点的指针指向表头,将表头的指针指向新节点。
这样,每插入一个新节点就成为了新的表头,即最后插入的节点为新的表头。
尾插法则是从链表的尾节点开始,逐个将新节点插入。
具体来说,创建一个空链表,设置一个头节点,将头节点的指针指向空;依次输入新节点,将新节点的指针指向空,将最后一个节点的指针指向新节点。
这样,最后插入的节点为尾节点,它的指针值为空。
插入节点插入节点是指在单链表的任意位置插入一个新节点。
插入节点的前提是找到插入位置,可以通过遍历单链表来查找插入位置。
插入新节点的基本步骤如下:1、创建新节点;2、将新节点的指针指向待插入节点的后继节点;3、将待插入节点的指针指向新节点。
删除节点删除节点是指删除单链表中的任意节点。
删除节点的前提是找到删除的节点位置,可以通过遍历单链表来查找删除位置。
删除节点的基本步骤如下:1、找到要删除的节点;2、将该节点的前驱节点的指针指向该节点的后继节点;3、删除该节点。
遍历节点遍历节点是指按照链表的顺序依次访问链表中的各个节点。
遍历节点的基本步骤如下:1、从链表的头节点开始遍历;2、依次访问每个节点的数据元素;3、通过指针访问下一个节点,直到遇到尾节点。
优缺点单链表的优点是简单,灵活,易于实现和扩展,可以方便地进行插入和删除等操作。
其缺点是存在指针开销,查找元素时需要遍历整个链表,不能直接访问链表中任意位置的节点。
总结单链表是一种最常用的数据结构,它是由一系列节点组成,每个节点包含一个数据元素和一个指针,指向下一个节点。
单链表(建⽴、插⼊、删除、打印)单向链表创建链表是动态分配存储空间的链式存储结构。
其包括⼀个“头指针”变量,其中第0个结点称为整个链表的头结点,头结点中存放⼀个地址,该地址指向⼀个元素,头结点⼀般不存放具体数据,只是存放第⼀个结点的地址。
链表中每⼀个元素称为“结点”,每个结点都由两部分组成:存放数据元素的数据域和存储直接后继存储位置的指针域。
指针域中存储的即是链表的下⼀个结点存储位置,是⼀个指针。
多个结点链接成⼀个链表。
最后⼀个结点的指针域设置为空(NULL),作为链表的结束标志,表⽰它没有后继结点。
使⽤结构体变量作为链表中的结点,因为结构体变量成员可以是数值类型,字符类型,数组类型,也可以是指针类型,这样就可以使⽤指针类型成员来存放下⼀个结点的地址,使其它类型成员存放数据信息。
当⼀个序列中只含有指向它的后继结点的链接时,就称该链表为单链表。
单链表的⽰意图如下:Head指针为单链表的头指针,单链表L:L既是单链表的名字,也是其头指针。
链表中的最后⼀个结点的指针域定义为空指针(NULL)。
在创建列表时要动态为链表分配空间,C语⾔的库函数提供了⼏种函数实现动态开辟存储单元。
malloc()函数实现动态开辟存储单元:malloc函数原型为:void *malloc(unsigned int size);其作⽤是在内存的动态存储区中分配⼀个长度为size的连续空间,函数返回值是⼀个指向分配域起始地址的指针(类型为void)。
如果分配空间失败(如,内存空间不⾜),则返回空间指针(NULL)1.单链表的初始化,即建⽴⼀个空链表。
//不带头结点的单链表的初始化void LinkedListInit1(LinkedList L){L=NULL;}//带头结点的单链表的初始化void LinkedListInit2(LinkedList L){L=(LNode *)malloc(sizeof(LNode));if(L==NULL){printf("申请空间失败!");exit(0);}L->next=NULL;}2.单链表的求表长操作单链表的求表长操作需要设定当前指针p和⼀个计数器j,初始时p指向链表中的第⼀个结点,p每向下移动⼀个结点时,j就加1,直到到达p 链表的尾部。
「C语⾔」单链表双向链表的建⽴遍历插⼊删除最近临近期末的C语⾔课程设计⽐平时练习作业⼀下难了不⽌⼀个档次,第⼀次接触到了C语⾔的框架开发,了解了View(界⾯层)、Service(业务逻辑层)、Persistence(持久化层)的分离和耦合,⼀种⾯向过程的MVC的感觉。
⽽这⼀切的基础就在于对链表的创建、删除、输出、写⼊⽂件、从⽂件读出......本篇⽂章在于巩固链表的基础知识(整理⾃《C语⾔程序设计教程--⼈民邮电出版社》第⼗章——指针与链表),只对链表的概念及增删改查作出探讨,欢迎指教。
⼀、链表结构和静态/动态链表⼆、单链表的建⽴与遍历三、单链表的插⼊与删除四、双向链表的概念五、双向链表的建⽴与遍历六、双向链表的元素查找七、循环链表的概念⼋、合并两个链表的实例九、链表实战拓展思维、拉到最后去看看 (•ᴗ•)و⼀、链表结构和静态/动态链表链表是⼀种常见的数据结构——与数组不同的是:1.数组⾸先需要在定义时声明数组⼤⼩,如果像这个数组中加⼊的元素个数超过了数组的长度时,便不能正确保存所有内容;链表可以根据⼤⼩需要进⾏拓展。
2.其次数组是同⼀数据类型的元素集合,在内存中是按⼀定顺序连续排列存放的;链表常⽤malloc等函数动态随机分配空间,⽤指针相连。
链表结构⽰意图如下所⽰:在链表中,每⼀个元素包含两个部分;数据部分和指针部分。
数据部分⽤来存放元素所包含的数据,指针部分⽤来指向下⼀个元素。
最后⼀个元素的指针指向NULL,表⽰指向的地址为空。
整体⽤结构体来定义,指针部分定义为指向本结构体类型的指针类型。
静态链表需要数组来实现,即把线性表的元素存放在数组中。
数组单元存放链表结点,结点的链域指向下⼀个元素的位置,即下⼀个元素所在数组单元的下标。
这些元素可能在物理上是连续存放的,也有可能是不连续的,它们之间通过逻辑关系来连接——这就要涉及到数组长度定义的问题,实现⽆法预知定义多⼤的数组,动态链表随即出现。
动态链表指在程序执⾏过程中从⽆到有地建⽴起⼀个链表,即⼀个⼀个地开辟结点和输⼊各结点的数据,并建⽴起前后相连的关系。
单链表插入和删除节点的代码单链表是一种常见的数据结构,它由一系列节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。
在实际应用中,我们经常需要对单链表进行插入和删除操作,以便动态地修改和管理数据。
1. 单链表的定义首先,我们需要定义一个单链表的数据结构。
在这个例子中,我们将使用C++语言来实现。
#include <iostream>// 定义单链表节点struct ListNode {int val; // 节点的值ListNode* next; // 指向下一个节点的指针// 构造函数ListNode(int x) : val(x), next(nullptr) {}};// 定义单链表类class LinkedList {private:ListNode* head; // 头指针public:LinkedList() : head(nullptr) {}// 插入节点到链表尾部void insertNode(int val) {ListNode* newNode = new ListNode(val);if (head == nullptr) {head = newNode;} else {ListNode* curr = head;while (curr->next != nullptr) {curr = curr->next;}curr->next = newNode;}}// 删除指定值的节点void deleteNode(int val) {if (head == nullptr) {return;}if (head->val == val) {ListNode* temp = head;head = head->next;delete temp;return;}ListNode* curr = head;while (curr->next != nullptr) {if (curr->next->val == val) {ListNode* temp = curr->next;curr->next = curr->next->next;delete temp;return;}curr = curr->next;}}// 打印链表void printList() {ListNode* curr = head;while (curr != nullptr) {std::cout << curr->val << " ";curr = curr->next;}std::cout << std::endl;}};2. 单链表插入节点在单链表中插入节点通常有两种情况:插入到链表的头部和插入到链表的尾部。
#include "stdlib.h"#include "stdio.h"#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEAIBLE -1#define OVERFLOW -2typedef int Status;typedef int ElemType;typedef struct LNode{ElemType data;struct LNode *next;}LNode,*LinkList;void GreaeList(LinkList &L,int n){int i; LNode *p;L=(LinkList)malloc(sizeof(LNode));L->next=NULL; printf(" 请输入元素的值:\n");for(i=n;i>0;--i){p=(LinkList)malloc(sizeof(LNode));scanf("%d",&p->data);p->next=L->next;L->next=p;}}Status ListInsert(LinkList &L,int i,ElemType e){LNode *p,*s;int j;p=L;j=0;while(p&&j<i-1){p=p->next;++j;}if(!p||j>i-1) return ERROR;s=(LinkList)malloc(sizeof(LNode));s->data=e;s->next=p->next;p->next=s;return OK;}Status ListDelete(LinkList &L,int i){LNode *p,*q;int j;ElemType e;p=L;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; free(q);return OK;}void print(LinkList &L){LNode *p;p=L->next;while(p){printf(" %d",p->data);p=p->next ;}printf("\n");}void main(){LinkList L;int i;GreaeList(L,10);printf(" 单链表的插入和删除\n");printf(" 实现插入按1\n");printf(" 实现删除按2\n");printf(" 请输入1或2\n");scanf("%d",&i);while(i!=1&&i!=2){printf(" 输入错请重新输入\n");scanf("%d",&i);}switch(i){case 1: {printf(" 插入后的线性表为:");ListInsert(L,2,9);print(L);break;}case 2: {printf(" 删除后的线性表为:");ListDelete(L,3);print(L);}}}。
单链表的建立、增加元素、删除元素、查找元素算法
单链表是一种常用的数据结构,由一个个节点构成,每个节点包含一个数据域和一个指向下一个节点的指针。
本文将介绍单链表的建立、增加元素、删除元素、查找元素算法。
一、单链表的建立
单链表的建立需要创建一个头结点,它不存储数据,只有一个指针域指向第一个节点。
接下来,我们用一个循环语句不断读入数据,创建新节点并将其插入到链表中。
二、单链表的增加元素
单链表的增加元素有两种情况,一种是在链表头插入新节点,另一种是在链表尾插入新节点。
在头部插入新节点时,需要先创建新节点,将它的指针域指向原来的头结点,再让头结点指向新节点;在尾部插入新节点时,需要先遍历整个链表找到最后一个节点,再将新节点插入到最后一个节点的后面。
三、单链表的删除元素
单链表的删除元素也有两种情况,一种是删除链表头的节点,另一种是删除链表中指定位置的节点。
在删除头结点时,需要先找到头结点的下一个节点,将其指针域赋给头结点,然后释放原来的头结点;在删除指定位置的节点时,需要先找到该节点的前一个节点,将前一个节点的指针域指向该节点的下一个节点,然后释放要删除的节点。
四、单链表的查找元素
单链表的查找元素有两种情况,一种是查找指定位置的节点,另
一种是查找指定数据域的节点。
在查找指定位置的节点时,需要遍历整个链表找到该位置的节点;在查找指定数据域的节点时,需要遍历整个链表找到数据域与目标值相等的节点。
实验二 单链表的插入和删除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. 插入操作:在单链表的指定位置插入一个新节点。
具体步骤如下:
找到要插入的位置的前一个节点;
将新节点插入到前一个节点和当前节点之间;
修改新节点的指针,使其指向当前节点;
修改前一个节点的指针,使其指向新节点。
2. 删除操作:删除单链表中的指定节点。
具体步骤如下:
找到要删除的节点的前一个节点;
将前一个节点的指针指向要删除的节点的下一个节点;
释放要删除的节点的内存。
3. 查找操作:在单链表中查找指定元素。
具体步骤如下:
从头节点开始遍历单链表;
找到与指定元素相等的节点;
返回该节点的位置。
4. 遍历操作:从头节点开始,依次访问单链表中的每个节点。
具体步骤如下:创建一个指针指向头节点;
依次访问指针所指向的每个节点,直到指针为空。
5. 打印操作:打印单链表中的所有元素。
具体步骤如下:
创建一个指针指向头节点;
依次打印指针所指向的每个节点的数据元素,直到指针为空。
以上是单链表的基本操作,通过这些操作可以对单链表进行各种操作,如插入元素、删除元素、查找元素等。
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<malloc.h>int n,id;//int fd;FILE *fp;struct student{long num;int age;float score;struct student *next;};struct student *head;//struct student *f,*sp;struct student *create(){struct student *p,*q;n=0,head=NULL;p=(struct student *)malloc(sizeof(struct student));q=(struct student *)malloc(sizeof(struct student));printf("please input the records:\n");scanf("%ld %d %f",&q->num,&q->age,&q->score);if(q->num!=0){if((fp=fopen("/home/linux/shiyan/listfile.c","ab+"))==NULL){printf("can not open the file.\n");return;}if(fwrite(q,sizeof(struct student),1,fp)!=1){printf("can not write file!\n");}printf("ok!\n");fclose(fp);}else{printf("over write records into file.\n");}while(q->num!=0){n+=1;if(n==1){head=q;}else{p->next=q;}p=q;q=(struct student *)malloc(sizeof(struct student));printf("please input more records:\n");scanf("%ld %d %f",&q->num,&q->age,&q->score);if(q->num!=0){if((fp=fopen("/home/linux/shiyan/listfile.c","ab+"))==NULL){printf("can not open the file.\n");return;}if(fwrite(q,sizeof(struct student),1,fp)!=1){printf("can not write file!\n");}printf("ok!\n");fclose(fp);}else{printf("over write records into file.\n");}}p->next=NULL;return head;}void print(){struct student *l;printf("the numbers of list are:%d\n",n);l=head;if(head!=NULL){do{printf("num:%ld age:%d score:%.1f\n",l->num,l->age,l->score);l=l->next;}while(l!=NULL);}else{printf("the list is null.\n");}struct student *insert(){struct student *e,*t,*x,*into;t=head;printf("please input the insert record:\n");into=(struct student *)malloc(sizeof(struct student));scanf("%ld %d %f",&into->num,&into->age,&into->score);if(into->num!=0){if((fp=fopen("/home/linux/shiyan/listfile.c","ab+"))==NULL){ printf("can not open the file.\n");return;}if(fwrite(into,sizeof(struct student),1,fp)!=1){printf("can not write file!\n");}printf("ok!\n");fclose(fp);}else{printf("over write records into file.\n");}while(into->num!=0){e=into;if(head==NULL){head=e;e->next=NULL;}else{while((e->num>t->num)&&t->next!=NULL){x=t;t=t->next;}if(e->num<=t->num){if(t==head){head=e;e->next=t;}elsex->next=e;e->next=t;}}else{t->next=e;e->next=NULL;}}n+=1;printf("please input the insert record:\n");into=(struct student *)malloc(sizeof(struct student));scanf("%ld %d %f",&into->num,&into->age,&into->score);if(into->num!=0){if((fp=fopen("/home/linux/shiyan/listfile.c","ab+"))==NULL){ printf("can not open the file.\n");return;}if(fwrite(into,sizeof(struct student),1,fp)!=1){printf("can not write file!\n");}printf("ok!\n");fclose(fp);}else{printf("over write records into file.\n");}}return head;}struct student *delete(){struct student *s,*c;long num;printf("please input the delete record:\n");scanf("%ld",&num);while(num!=0){if(head==NULL){printf("the list is null.\n");return head;}s=head;while((num!=s->num)&&(s->next!=NULL)) {c=s;s=s->next;}if(num==s->num){if(s==head){head=s->next;free(s);}else{c->next=s->next;s=s->next;free(s);}printf("delete %ld is success.\n",num);n-=1;}else{printf("can not found %ld\n",num);}printf("please input the delete record:\n");scanf("%ld",&num);}return head;}struct student *refer(){struct student *r,*m;long rnum;printf("please input to refer num:\n");scanf("%ld",&rnum);r=head;if(rnum!=0){while(m->next!=NULL&&r->num!=rnum){m=r;r=m->next;}if(m->next==NULL){printf("the record is not exist.\n");return head;}if(rnum==r->num){printf("the record find:\n");printf("num:%ld age:%d score:%.1f\n",r->num,r->age,r->score);}}else{printf("the inputer is error.\n");}return head;}/*struct student *save(){FILE *fp;struct student *l1;if((fp=fopen("/home/linux/shiyan/listx","ab+"))==NULL){printf("can not open the file.\n");return;}l1=head;for(id=0;id<n;id++){if(fwrite(l1,sizeof(struct student),1,fp)!=1){printf("can not write file!\n");}l1+=1;printf("ok!\n");}fclose(fp);return head;}*/struct student *load(){FILE *fp;struct student *f1;f1=(struct student *)malloc(sizeof(struct student));if((fp=fopen("/home/linux/shiyan/listfile.c","rb"))==NULL){printf("can not open the file!\n");return;}while(!feof(fp)){if(fread(f1,sizeof(struct student),1,fp)!=NULL){printf("num:%ld age:%d score:%.1f\n",f1->num,f1->age,f1->score); //sp=(struct student *)malloc(sizeof(struct student));// f1=f1->next;n+=1;}}fclose(fp);return f1;}/*void load(){fd=open("/home/linux/shiyan/list.txt",O_RDONLY);for(id=0;id<n;id++){read(fd,buffer,sizeof(buffer));printf("num:%ld age:%d score:%.1f\n",f->num,f->age,f->score);f=f->next;buffer=f;}close(fd);}*//*void save(){fd=open("/home/linux/shiyan/list.txt",O_WRONLY|O_CREAT);for(id=0;id<n;id++){write(fd,f,sizeof(struct student));f=f->next;}close(fd);}*/int choose(){int choice;scanf("%d",&choice);return choice;}void selecte(int number){// head=create();// struct student *head;switch(number){case 1:insert();break;case 2:delete();break;case 3:print();break;case 4:load();break;case 5:refer();break;// case 6:// save();// break;case 6:exit(0);default:printf("the choice is not lawful,please input again\n");break;}}void menu(){printf("==========THE MAIN MENU==========\n");printf("1:insert a record in list.\n");printf("2:delete a record from list.\n");printf("3:printf present records on screen.\n");printf("4:read the records from listfile.c.\n");printf("5:select the record from list.\n");printf("6:get away the main menu.\n");printf("=================================\n");printf("please input a choice:1--2--3--4--5--6\n");selecte(choose());}/*void save(){FILE *fp;if((fp=fopen("list.txt","w"))==NULL){printf("can not open file!\n");return;for(id=0;id<n;id++){if(fwrite(f,sizeof(struct student),1,fp)!=1){printf("can not write file!\n");}f=f->next;}fclose(fp);}*//*void load(){FILE *fp;if((fp=fopen("list.txt","r"==NULL))){printf("can not open file!\n");return;}for(id=0;id<n;id++){if(fread(head,sizeof(struct student),1,fp)!=1){if(feof(fp)){fclose(fp);return;}printf("can not read file!\n");}printf("num:%ld age:%d score:%.1f\n",head->num,head->age,head->score);head=head->next;}fclose(fp);}*/int main(){// printf("please input the records:\n");// h=create();// print(h);/* printf("please input the insert record:\n");into=(struct student *)malloc(sizeof(struct student));scanf("%ld %d %f",&into->num,&into->age,&into->score);while(into->num!=0){h=insert(h,into);print(h);printf("please input the insert record:\n");into=(struct student *)malloc(sizeof(struct student));scanf("%ld %d %f",&into->num,&into->age,&into->score);printf("please input the delete record:\n"); scanf("%ld",&dnum);while(dnum!=0){h=delete(h,dnum);print(h);printf("please input the delete record:\n");scanf("%ld",&dnum);} */head=create();while(1){menu();}return EXIT_SUCCESS;}。
实验一单链表的插入和删除(4个机时)1.1 实验目的:已知线性表中元素为“TANKK︼YOU”,利用模块化编程思想,编程实现如下函数功能:1)建立一个带头结点的单链表,将线性表中元素依次放入(函数1);输出该单链表中各元素(函数4)。
2)删除单链表中的第四个元素(函数2);输出执行删除操作之后的单链表(函数4);3)在单链表中的第二个元素前插入元素“H”(函数3);输出执行插入操作之后的单链表(函数4)。
1.2 流程图”1.3 实验步骤及程序代码#include<stdio.h>#include<string.h>#include<malloc.h>struct ZFSZ //定义指针类型{int chardata;struct ZFSZ*next;};#define LEN sizeof(struct ZFSZ)#define N 10char c[N]={'t','a','n','k','k','*','y','o','u'}; //字符数组定义,保存字符“tankk+you”struct ZFSZ* creat() //函数一:建立链表{int a;struct ZFSZ *head;struct ZFSZ *p1,*p2;a=0;p1=(struct ZFSZ*)malloc(LEN);p1->chardata=c[0];while(p1->chardata!=NULL){a=a+1;if(a==1){head=p1;}else{p2->next=p1;}p2=p1;p1=(struct ZFSZ*)malloc(LEN);p1->chardata=c[a];}p2->next=NULL;return(head);}void Print (ZFSZ*head) //函数二:建立打印程序,输出链表中的内容{struct ZFSZ*Pp1,*Phead;Phead=head;Pp1=head;while (Pp1!=NULL&&Pp1->chardata!=0){printf("%c",Pp1->chardata);Pp1=Pp1->next;}printf("\n");}void Dell(ZFSZ*head) //函数三:删除第四个元素{struct ZFSZ*Dp1,*Dp2,*Dhead;Dhead=head;int n=1;for(n;n<=4;n++){if(n==3){Dp1=Dhead;}if(n==4){Dp2=Dhead->next;}Dhead=Dhead->next;}free(Dp1->next);Dp1->next=Dp2;}void ChaRu(struct ZFSZ*head) //函数四:再第二个元素前插入字符‘h’{struct ZFSZ*Cp1,*Cp2,*Chead;Chead=head;int m=1;for(m;m<=2;m++){if(m==1){Cp1=Chead;}Cp2=Chead->next;}Chead=(struct ZFSZ*)malloc(LEN);scanf("%c",&Chead->chardata);Cp1->next=Chead;Chead->next=Cp2;}int main() //主函数{struct ZFSZ *head; //调用函数一,建立链表head = creat();Print(head); //调用函数二输出链表中的内容Dell(head); //调用函数三:删除第四个元素Print(head); //调用函数二输出链表中的内容ChaRu(head); //调用函数四:再第二个元素前插入字符‘h’Print(head); //调用函数二输出链表中的内容}1.4 实验结果。