【C】链表的创建、打印、插入、删除等

链表两个概念:

1.普通链表 data定义数据类型指针(不够灵活)

2.通用链表 data定义void*(可以接受任何数据类型的指针地址)

注意:头结点是哨兵结点,没有数据及其地址

1.创建结点

通过结构体定义一个结点:

typedef struct node_t

{

int val;//记录节点链表的位置

void *data;//存放数据字段

struct node_t *pnext;//下一结点地址

}NODE_T;

2.创建链表,返回头结点

步骤:

1.创建一个链表结点

2.开辟内存,并去清空内存(可以使用calloc函数,malloc不能清理内存)

3.赋值

NODE_T *List_Init()

{

//1.创建一个链表结点

NODE_T *head=NULL;//一开始指向0,需要开内存

//开辟内存

// head=(NODE_T *)malloc(sizeof(NODE_T));//未清空内存

head=(NODE_T *)calloc(1,sizeof(NODE_T));//开辟空间,清空内存

if(head==NULL)

{

printf("开辟内存空间失败!\n");

return NULL;

}

head->data=NULL;

head->pnext=NULL;

head->val=0;

return head;

}

3.链表添加结点(默认尾插)

把节点添加到链表

head:头结点指针 data:要插入数据地址

void List_Add(NODE_T *head,void *data)

{

NODE_T *ptmp=head;//保存头结点

NODE_T *newNode=NULL;

int tmp_val=0;

//找到链表尾部结点

while(ptmp->pnext!=NULL)

{

tmp_val=ptmp->val;

ptmp=ptmp->pnext;

}

//在内存中开辟新节点空间

newNode=(NODE_T *)calloc(1,sizeof(NODE_T));

newNode->data=data;

newNode->val=++tmp_val;

newNode->pnext=NULL;

ptmp->pnext=newNode;

}

4.打印链表

里面的数据data,因为定义无类型指针,这里指向结构体

void printList(NODE_T *head)

{

NODE_T *ptmp=head;

while(ptmp!=NULL)

{

if(ptmp->data!=NULL)

{

printf("age=%d\n",((PACK_T*)(ptmp->data))->age);

}

ptmp=ptmp->pnext;

}

}

5.获取链表的结点个数

获取链表有多少结点,链表第一个结点data无数据,叫哨兵结点

int getListCount(NODE_T *head)

{

int count=0;

NODE_T *ptmp=head;

while(ptmp->pnext!=NULL)

{

count++;

ptmp=ptmp->pnext;

}

return count;//链表有效结点的个数

}

6.插入结点(尾插)

pos:第几个结点,data:插入的数据

int insertList(NODE_T *head,int pos,void *data)

{

NODE_T *ptmp=head;

NODE_T *newNode=NULL;

int num=0;

//1.找pos在链表位置

while(ptmp->pnext!=NULL)

{

ptmp=ptmp->pnext;//跳开哨兵结点

num++;

if(num==pos)

{

newNode=(NODE_T*)calloc(1,sizeof(NODE_T));

if(newNode==NULL)

{

printf("calloc error!\n");

exit(0);

}

newNode->data=data;

//以下两个顺序不能颠倒

newNode->pnext=ptmp->pnext;

ptmp->pnext=newNode;//指向新的

return 0;

}

}

return -1;

}

7.删除指定结点

1.找到要删除的结点位置,要保存前一个结点指针

2.定义两个指针,pre:前个结点

int deleteNodeByPos(NODE_T *head,int pos)

{

//找到要删除的结点位置

//要保存前一个结点指针

//定义两个指针,pre:前个结点

NODE_T *ptmp=head->pnext,*pre=head;

int num=0;

while(ptmp!=NULL)

{

num++;

if(num==pos)

{

pre->pnext=ptmp->pnext;//把前一个结点指向后一个结点

free(ptmp);

return 1;

}

//如果不是匹配的位置ptmp与pre往后移

pre=pre->pnext;

ptmp=ptmp->pnext;

}

return -1;

}

8.指定位置返回数据

void *getListDataByPos(NODE_T *head,int pos)

{

NODE_T *ptmp=head;

int num=0;

while(ptmp->pnext!=NULL)

{

ptmp=ptmp->pnext;

num++;

if(num==pos)

{

return ptmp->data;

}

}

return NULL;

}

9.释放整个链表

void freeList(NODE_T *head)

{

NODE_T *ptmp=head;

while(ptmp!=NULL)

{

head=head->pnext;//首相移动到下一个结点

free(ptmp);//可以释放ptmp,因为ptmp还是指向移动之前的结点

ptmp=head;//再把移动后的结点赋值ptmp

}

}

相关推荐
1白天的黑夜112 分钟前
链表-25.k个一组翻转链表-力扣(LeetCode)
数据结构·leetcode·链表
ALex_zry18 分钟前
Golang云端编程入门指南:前沿框架与技术全景解析
开发语言·后端·golang
zl_dfq34 分钟前
数据结构之 【红黑树的简介与插入问题的实现】
数据结构
jinlei200934 分钟前
在python 代码中调用rust 源码库操作步骤
开发语言·python·rust
小巫程序Demo日记35 分钟前
插入排序讲解
数据结构·算法·排序算法
yjx2333236 分钟前
并行多核体系结构基础——共享存储并行编程与针对链式数据结构的并行编程(笔记)
笔记
越前君1 小时前
如何开发一个 Raycast 扩展?
前端·笔记
人生游戏牛马NPC1号1 小时前
学习 Android (十七) 学习 OpenCV (二)
android·opencv·学习
float_六七1 小时前
Apache Commons Lang 3
开发语言·python·apache
悠哉悠哉愿意1 小时前
【机器学习学习笔记】机器学习引言
笔记·学习·机器学习