首页 > 编程知识 正文

单链表的实现方式,c语言链表详解

时间:2023-05-06 00:58:41 阅读:48255 作者:2770

1 .链表概述链表是一种常见的数据结构。 与常规数组不同,使用数组时必须指定数组中的元素数(即数组长度),但如果添加到此数组的元素超过数组的大小,则无法保存所有内容。

链表这种存储方式不限定元素的数量,添加元素后存储的数量会发生变化。

链表一般有两种形式。 没有空头链表和空头链表。

链表具有一个头指针变量,用于保存指向第一个节点的地址。 此指针变量包含两部分:数据部分和指针部分。 结构不能包含与自己类型相同的结构,但可以包含指向同一类型结构的指针。 此定义是链表的基础,链表中的每个项目都包含在哪里可以找到以下项目的信息: 指向最后一个节点的指针必须为空NULL,不必担心链表的长度超出链表原理的范围。

2 .链表的基本使用2.0在准备使用链表时,必须首先包含基本的头文件。 这是因为内存操作和字符串操作有关。

# include ' stdio.h ' # include ' stdlib.h ' /提供malloc (和free ) (#include'string.h )//提供strcpy )等3358www

函数的原型如下:

统一集成(void * malloc ); 请注意,此函数返回void类型指针,因此使用时强制类型将转换为所需的指针类型。malloc函数

函数的原型如下:

语音自由(语音* p ); 该函数是用于将指针p作为指针释放的存储器区域。

2.1节点(结构)结构节点inta; //数据域结构节点*下一步; //指针字段(指向节点的指针); 2.2全局定义链表头尾指针,便于调用结构节点*头=null。 结构节点*结束=空值; 2.3创建链表并将数据添加到链表(末尾添加) ————voidaddlisttill(inta )//节点structnode*temp=) structnode* ) malloc temp-next=空值; //连接分为两种情况1 .一个节点也没有2 .已经有节点,尾部有if (空值==头部) {头部=时间; //end=temp; }else{end-next=temp; //end=temp; //末尾的节点应该始终指向最后}end=temp; //末尾的节点必须始终指向末尾} AddListTill函数的功能是通过末尾添加将节点添加到链表的末尾。 其中,输入的参数是此节点的数据。 首先创建节点,请求节点的内存,然后为接收节点的数据赋值。 请注意,指向最近添加的新节点的指针指向空。 此时,分为2种情况,1为链表中没有一个节点时,该节点既是开头节点也是尾部节点; 2表示已经有节点的情况下,新添加的节点成为最后一个节点,前面的节点成为倒数第二个节点,所以指针应该指向新添加的节点,然后全局变量的最后一个节点应该指向当前节点(操作的优先级保持不变)

2.4遍历链表—————的void扫描列表() {结构节点* temp=head; //定义指向头部while(temp )的临时变量=null(printf ) ' %dn ',temp-a ); temp=temp-next; //temp指向以下地址即实现操作} }扫描列表函数的功能是遍历该链表,首先定义用于遍历的临时指针,在while环路中实现遍历输出。

2.5搜索指定节点(逐个搜索) struct node * find node inta ) {struct Node *temp=head; wile(temp!=空(if ) a==temp-a ) {return temp; }temp=temp-next; 未找到返回空值; } FindNode函数的功能是遍历链表,但它逐个确定每个节点的数据,如果找到则返回该节点,如果找不到则返回NULL。

2.6链表清除——3354————全部删除voidFreelist(((/每个空结构节点* temp=head; //定义指向头部while(temp )的临时变量=null((/printf ) ' %dn ',temp-a ); 结构节点* pt=temp; temp=temp-next; //temp通过指向以下地址来实现操作free(pt ) : //当前版本//如果不做头尾空,下一个头接0x 10头=空; 结束=空值; }请注意,} FreeList函数仍然具有遍历一次释放一个节点内存,最后删除所有节点的效果,但最后应该从头尾节点到空值。 否则,下一张链表将紧随这次头尾。

2.

7.在指定位置插入节点 ————在指定位置增 void AddListRand(int index,int a){ if (NULL==head){printf("链表没有节点n");return;} struct Node* pt =FindNode(index);if(NULL==pt) //没有此节点{printf("没有指定节点n");return;} //有此节点 //创建临时节点,申请内存struct Node* temp =(struct Node *)malloc(sizeof(struct Node));//节点成员进行赋值temp->a=a;temp->next=NULL;//连接到链表上 1.找到的节点在尾部 2.找到的节点在中间 if (pt == end){//尾巴的下一个指向新插入的节点end->next=temp;//新的尾巴end=temp;}else{// 先连后面 (先将要插入的节点指针指向原来找到节点的下一个)temp->next=pt->next;//后连前面pt->next=temp;}}

首先要知道在指定节点插入的过程就像手拉手得人在一条线,这时来了一个新人,他要求站在甲之后,首先要找到甲的位置,如果链表为空或者没有甲则无法插入,如果链表不为空并且甲在这个链表中,则还要看甲是在链表中间还是甲就在最后的尾巴上,如果在尾巴上则新插入的即为尾巴如图1,若在甲乙之间则需要先连上后面乙再连上前面的甲,如图2。

2.8尾删除————删 void DeleteListTail(){ if (NULL == end){printf("链表为空,无需删除n");return;}//链表不为空 //链表有一个节点 if (head==end) { free(head); head=NULL; end=NULL; } else {//找到尾巴前一个节点 struct Node* temp =head; while (temp->next!=end) { temp = temp->next; } //找到了,删尾巴//释放尾巴 free(end); //尾巴迁移 end=temp; //尾巴指针为NULL end->next=NULL; }}

尾删除的过程和前面一样首先应判断这个链表是不是为空或者只有一个节点,若只有一个节点则直接置NULL,若不为空,则先通过遍历找到倒数第二个节点,安徽将最后一个节点释放内存,再讲倒数第二个节点设置为end,然后将它的指针指向NULL。

2.9 删除头——————删 void DeleteListHead(){//记住旧头struct Node* temp=head;//链表检测 if (NULL==head){printf("链表为空n");return;}head=head->next;//头的第二个节点变成新的头free(temp);}

先定义一个临时变量指向旧的头,将头的第二个记为新的头指针head,之后将旧的头释放

2.10 删除指定节点 void DeleteListRand(int a){//链表判断 是不是没有东西if(NULL==head){printf("链表没东西n");return;} //链表有东西,找这个节点struct Node* temp =FindNode(a);if(NULL==temp){printf("查无此点n");return;}//找到了,且只有一个节点if(head==end){free(head);head=NULL;end=NULL;}else if(head->next==end) //有两个节点{//看是删除头还是删除尾if(end==temp){DeleteListTail(); }else if(temp==head){DeleteListHead(); }}else//多个节点{//看是删除头还是删除尾if(end==temp)DeleteListTail();else if(temp==head)DeleteListHead();else//删除中间某个节点{//找要删除temp前一个,遍历struct Node*pt =head;while(pt->next!=temp){pt=pt->next;}//找到了//让前一个直接连接后一个 跳过指定的即可 pt->next=temp->next; free(temp);}}}

情况与前面增加类似不再赘述,具体见图

3. 测试主程序

下面是测试用的主程序,主要实现了链表的增删查改等基本操作。

void main (){struct Node *pFind ;//创建5个节点for(i=0;i<6;i++)AddListTill(i);//AddListRand(4,14);//在指定位置4增加节点14//DeleteListTail();//删除一个尾结点DeleteListRand(4);//删除4节点ScanList();//便利输出链表FreeList();//删除链表/*pFind = FindNode(5);//查找5节点if (pFind != NULL){printf("找到%dn",pFind->a);//找到节点并且输出该节点数据}else{printf("No Find!n");}*/}

有关无空头的单链表的基本操作就总结到这里,当然还有双链表等更复杂的数据结构,以及遍历和查找的优化算法也有待进一步探索与学习。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。