C语言——单向链表
1. 定义
链表是由一系列节点组成,每个节点包含两个域,一个是数据域,一个是指针域,数据用来保存用户数据,指针域保存下一个节点或者上一个节点的地址,非连续的一块内存空间。
链表在指定位置插入和删除时,不需要移动元素,只需修改指针即可
相对数组来说,查找效率较低
相对数组来说,多了指针域的开销
2. 分类
-
静态链表、动态链表
-
单向、 双向、 循环链表
链表中,头节点不添加任何数据,可以少判断一次情况
链表C语言实现
以下的代码是基于C语言写的单向链表的实现方式
静态链表
struct linknode{
int data;
struct linknode *next;
};
void linknode_test()
{
struct linknode node1 = {10,null};
struct linknode node2 = {20,null};
struct linknode node3 = {40,null};
struct linknode node4 = {60,null};
struct linknode node5 = {70,null};
node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
//遍历链表
struct linknode *pcurrentnode = &node1;
while(pcurrent != null)
{
printf("%d",pcurrentnode->data);
pcurrentnode = pcurrentnode->next;
}
}
void main()
{
}
动态链表
//linklist.h
#pragma once
#ifndef __cplusplus//表示能够在c++当中调用
extern "c"{
#endif
struct linknode{
int data;
struct linknode *next;
};
//链表结构体
//初始化链表
struct linknode *Init_linklist();
//插入数据
void Insetbytevalue_linklist(struct linknode *header ,int oldvalue,int newval);
//删除数据
void removebytevalue_linklist(struct linknode *header ,int newval);
//遍历
void foreach_linklist(struct linknode *header);
//销毁链表
void destroy_linklist(struct linknode *header);
//清空
void clear_linklist(struct linknode *header);
#ifndef __cplusplus
}
#endif
//linklist.c
//初始化
struct linknode *Init_linklist()
{
struct linknode *header = malloc(sizeof(struct linknode));
header->data = null;
header->next = null;
//创建尾部指针
struct linknode *prear = header;
int val = -1;
while(1)
{
printf("输入插入的值");
scanf("%d",&val);
if(val = -1)
break;
//先创建新节点
struct linknode *newnode = malloc(size(struct linknode));
newnode->data = val;
newnode->next = null;
//新节点插入链表
prear->next = newnode;
prear = newnode;
}
return header;
}
//插入数据 在lodvalue前插入一个node
void Insetbytevalue_linklist(struct linknode *header ,int oldvalue,int newval)
{
if(0 == header) return;
struct linknode *pcurrentnode = header->next;
struct linknode *poldnode = header;
while(pcurrentnode != null)
{
if(pcurrentnode->data == oldvalue)
{
break;
}
poldnode = pcurrentnode;
pcurrentnode = pcurrentnode->next;
}
if(pcurrentnode == null) return;
//创建新节点
struct linknode *newnode = malloc(size(struct linknode));
newnode->data = newval;
newnode->next = pcurrentnode;
poldnode-next = newnode;
}
//删除数据
void removebytevalue_linklist(struct linknode *header ,int delval)
{
if(null == header) return;
struct linknode *pcurrent = header->next;
struct linknode *pprev = header;
while(pcurrent != null)
{
if(pcurrent->data == delval) break;
pprev = pcurrent;
pcurrent = pprev->next;
}
if(null == pcurrent) return;
pprev->next = pcurrent->next;
free(pcurrent);
pcurrent = null;
}
//遍历
void foreach_linklist(struct linknode *header)
{
if(null = header){ return;}
struct linknode *pcurrent = header;
while(pcurrent != null){
pcurrent = pcurrent->next;
}
}
//销毁链表
void destroy_linklist(struct linknode *header)
{
if(null == header) return;
struct linknode *pcurrent = header;
while(pcurrent != null)
{
struct linknode *pnext = pcurrent->next;
free(pcurrent);
pcurrent = pnext;;
}
}
//清空
void clear_linklist(struct linknode *header)
{
if(null == header ) return;
struct linknode *pcurrent = header->next;
while(pcurrent != null)
{
struct linknode *pnext = pcurrent->next;
free(pcurrent);
pcurrent = pnext;
}
}
写在后面:不来虚的,直接上代码,对着原理进行理解。笔者在看某源码时,链表的写法有点懵,就上网看了各位大佬的文章,画的图,结果发现越来懵,越来越怀疑本以为的链表,结果越来不知道链表是啥,无奈去b站找个讲链表的,解决自己之前的疑虑。建议各位不理解的小伙伴,可以看着各位大佬画的图,来理解上述代码。