【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
}
}
原文地址:https://blog.csdn.net/weixin_74154742/article/details/143818504
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!