目录
C语言通用链表,相关源码如下,仅供学习使用
1.CList.h [通用链表 头文件]
#ifndef CLIST_H
#define CLIST_H
//通用链表的结构体
typedef struct list_t
{
void *pdata; //(int或结构体)数据的地址 任意类型的指针
struct list_t*pnext; //存储下一个结构体的地址
}LIST_T;
//初始化链表头
LIST_T * List_init();
//把数据地址添加到链表的尾部
void List_add(LIST_T *head,void *node);
//统计链表的节点个数
int List_count(LIST_T *head);
//根据位置获取节点数据
void* List_getNode(LIST_T *head,int pos);
//根据位置插入节点
int List_insertByPos(LIST_T *head,int pos,void *data);
//根据位置删除节点
int List_deleteByPos(LIST_T *head,int pos);
//释放整条链表
void freeList(LIST_T *head);
#endif
2.CList.c [通用链表 源文件]
#include"CList.h"
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
//初始化链表头
LIST_T * List_init()
{
//创建菜谱结构体指针变量
LIST_T *head = NULL;
//动态开空间
head = (LIST_T *)malloc(sizeof(LIST_T));
if(head == NULL)
{
printf("open fail\n");
exit(0);
}
//初始化 数据域
memset(head,'\0',sizeof(LIST_T));
//初始化数据域
head->pdata=NULL;
//初始化指针域
head->pnext = NULL;
return head;
}
//把数据地址添加到链表的尾部
void List_add(LIST_T *head,void *node)
{
LIST_T *tmp=head;
LIST_T *pNewNode = NULL; //新节点
//判断pnext是否为空 找到链表的尾部
while(tmp->pnext!=NULL)
{
tmp=tmp->pnext;
}
//动态开空间
pNewNode = (LIST_T *)malloc(sizeof(LIST_T));
if(pNewNode==NULL)
{
printf("open fail\n");
exit(0);
}
//初始化 数据域
memset(pNewNode,'\0',sizeof(LIST_T));
//数据域赋值
pNewNode->pdata = node;
//指针域赋值
pNewNode->pnext=NULL;
//新节点连接到上一个节点的指针域
tmp->pnext = pNewNode;
}
//统计链表的节点个数
int List_count(LIST_T *head)
{
LIST_T *tmp=head;
int count =0;
while(tmp->pnext!=NULL)
{
count++;
tmp=tmp->pnext;
}
return count;
}
//根据位置获取节点数据
void* List_getNode(LIST_T *head,int pos)
{
int count=0; //计算数字
LIST_T* tmp=head;
while(tmp->pnext!=NULL)
{
count++;
tmp=tmp->pnext;
if(pos == count)
{
//返回数据域 存储节点的地址
return tmp->pdata;
}
}
return NULL;
}
//根据位置插入节点
//返回 1--成功 0--失败
int List_insertByPos(LIST_T *head,int pos,void *data)
{
int count=0;
LIST_T *tmp=head;
LIST_T *newNode = NULL;//新节点
while(tmp->pnext!=NULL)
{
count++;
tmp=tmp->pnext;
if(pos==count)//找到
{
newNode=(LIST_T*)malloc(sizeof(LIST_T));
memset(newNode,'\0',sizeof(LIST_T));
//数据域赋值
newNode->pdata=data;
//指针域赋值
newNode->pnext=tmp->pnext;
tmp->pnext=newNode;
return 1;
}
}
return 0;
}
//根据位置删除节点
int List_deleteByPos(LIST_T *head,int pos)
{
int count = 0;
LIST_T *tmp=head->pnext,*pre=head;
while(tmp!=NULL)
{
count++;
if(count==pos)
{
pre->pnext=tmp->pnext;
free(tmp);
return 1;
}
pre=pre->pnext;
tmp=tmp->pnext;
}
return -1;
}
//释放整条链表
void freeList(LIST_T *head)
{
LIST_T *tmp=head;
while(tmp!=NULL)
{
head=head->pnext;
free(tmp); // 释放节点
tmp=head;
}
}
3.main.c [程序主入口测试]
3.1 main.c 第二个节点的ID为:(根据位置获取查找数据),示例如下
#include<stdio.h>
#include<stdlib.h>//memset
#include<string.h>//strcpy
#include<windows.h>
#include"CList.h"
void demoList();
typedef struct user_t{//用户结构体定义(没有指针域)
int ID;
char name[20];
char pwd[20];
int role;
}USER1_T;
int main()
{
demoList();
return 0;
}
void demoList()
{
USER1_T user = {1001,"admin","123456",1};//1 定义结构体 &结构体名称
USER1_T *puser=NULL;//2 定义结构体指针 通过结构体指针->属性的方法赋值
LIST_T *userList=NULL;
int num=0;//统计节点个数
//动态开空间
puser=(USER1_T*)malloc(sizeof(USER1_T));
//初始化
memset(puser,'\0',sizeof(USER1_T));
puser->ID=1002;
strcpy(puser->name,"lily");
strcpy(puser->pwd,"123123");
puser->role=2;
userList =List_init();
// printf("%p\n",userList);//创建链表头
List_add(userList,&user);//定义1
List_add(userList,puser);//定义2
num = List_count(userList);
// printf("统计链表的节点的个数为:%d\n",num);
puser=List_getNode(userList,2);
printf("第二个节点的ID为:%d\n",puser->ID);
//第二个节点的ID为:1002
}
3.2 main.c 打印查看一条用户信息:1001 admin 123456 1,示例如下
#include<stdio.h>
#include<stdlib.h>//memset
#include<string.h>//strcpy
#include<windows.h>
#include"CList.h"
void demoList();
typedef struct user_t{
int ID;
char name[20];
char pwd[20];
int role;
}USER1_T;
void printUserInfo(LIST_T *head);//打印一条用户信息
int main()
{
demoList();
return 0;
}
void demoList()
{
USER1_T user = {1001,"admin","123456",1};
USER1_T *puser=NULL;
LIST_T *userList=NULL;
int num=0,pos=0;//统计节点个数
//动态开空间
puser=(USER1_T*)malloc(sizeof(USER1_T));
//初始化
memset(puser,'\0',sizeof(USER1_T));
puser->ID=1002;
strcpy(puser->name,"lily");
strcpy(puser->pwd,"123123");
puser->role=2;
userList =List_init();
// printf("%p\n",userList);
List_add(userList,&user);
List_add(userList,puser);
num = List_count(userList);
printf("统计链表的节点的个数为:%d\n",num);
printUserInfo(userList);//打印一条用户信息
//1001 admin 123456 1
}
void printUserInfo(LIST_T *head)
{
LIST_T *tmp=head;
USER1_T *puser = NULL;
int count =0,i=0;
//1.获取链表的长度 getListCount()
//2.遍历链表 getNodeByPos()
//3.获取数据域 结构体指针指向属性
puser = (USER1_T*)malloc(sizeof(USER1_T));//开空间
memset(puser,'\0',sizeof(USER1_T));//初始化
count = List_count(head);
for(i=1;i<count;i++)
{
puser=(USER1_T*)List_getNode(head,i);
printf("%d\t%s\t%s\t%d\n",puser->ID,puser->name,puser->pwd,puser->role);
}
}
3.3 main.c 插入增加节点,示例如下
#include<stdio.h>
#include<stdlib.h>//memset
#include<string.h>//strcpy
#include<windows.h>
#include"CList.h"
void demoList();
typedef struct user_t{
int ID;
char name[20];
char pwd[20];
int role;
}USER1_T;
void printUserInfo(LIST_T *head);//打印用户信息
int main()
{
demoList();
return 0;
}
void demoList()
{
USER1_T user = {1001,"admin","123456",1};
USER1_T newuser = {0};
USER1_T *puser=NULL;
LIST_T *userList=NULL;
int num=0,pos=0;//统计节点个数
//动态开空间
puser=(USER1_T*)malloc(sizeof(USER1_T));
//初始化
memset(puser,'\0',sizeof(USER1_T));
puser->ID=1002;
strcpy(puser->name,"lily");
strcpy(puser->pwd,"123123");
puser->role=2;
userList =List_init();
// printf("%p\n",userList);
List_add(userList,&user);
List_add(userList,puser);
num = List_count(userList);
// printf("统计链表的节点的个数为:%d\n",num);
printf("请输入插入的节点数:");
scanf("%d",&pos);
printf("\n请输入插入的id:");
scanf("%d",&newuser.ID);
printf("\n请输入插入的用户名:");
scanf("%s",newuser.name);
printf("\n请输入插入的密码:");
scanf("%s",newuser.pwd);
printf("\n请输入插入的角色:");
scanf("%d",&newuser.role);
pos = List_insertByPos(userList,pos,&newuser);
if(pos==1)
{
printf("数据插入成功\n");
}
printUserInfo(userList);
}
void printUserInfo(LIST_T *head)
{
LIST_T *tmp=head;
USER1_T *puser = NULL;
int count =0,i=0;
//1. 获取链表的长度 getListCount()
//2. 遍历链表 getNodeByPos()
//3. 获取数据域 结构体指针指向属性
puser = (USER1_T*)malloc(sizeof(USER1_T));
memset(puser,'\0',sizeof(USER1_T));
count = List_count(head);
for(i=1;i<count;i++)
{
puser=(USER1_T*)List_getNode(head,i);
printf("%d\t%s\t%s\t%d\n",puser->ID,puser->name,puser->pwd,puser->role);
}
}
3.4 main.c 删除节点和释放链表,示例如下
#include<stdio.h>
#include<stdlib.h>//memset
#include<string.h>//strcpy
#include<windows.h>
#include"CList.h"
void demoList();
typedef struct user_t{
int ID;
char name[20];
char pwd[20];
int role;
}USER1_T;
void printUserInfo(LIST_T *head);
int main()
{
demoList();
return 0;
}
void demoList()
{
USER1_T user = {1001,"admin","123456",1};
USER1_T newuser = {0};
USER1_T *puser=NULL;
LIST_T *userList=NULL;
int num=0,pos=0;//统计节点个数
//动态开空间
puser=(USER1_T*)malloc(sizeof(USER1_T));
//初始化
memset(puser,'\0',sizeof(USER1_T));
puser->ID=1002;
strcpy(puser->name,"lily");
strcpy(puser->pwd,"123123");
puser->role=2;
userList =List_init();
// printf("%p\n",userList);
List_add(userList,&user);
List_add(userList,puser);
num = List_count(userList);
// printf("统计链表的节点的个数为:%d\n",num);
printf("请输入插入的节点数:");
scanf("%d",&pos);
printf("\n请输入插入的id:");
scanf("%d",&newuser.ID);
printf("\n请输入插入的用户名:");
scanf("%s",newuser.name);
printf("\n请输入插入的密码:");
scanf("%s",newuser.pwd);
printf("\n请输入插入的角色:");
scanf("%d",&newuser.role);
pos = List_insertByPos(userList,pos,&newuser);
if(pos==1)
{
printf("数据插入成功\n");
}
printUserInfo(userList);
Sleep(1000);
system("cls");
printf("请输入删除的节点数:");
scanf("%d",&pos);
pos = List_deleteByPos(userList,pos);
if(pos==1)
{
printf("数据删除成功\n");
}
printUserInfo(userList);
printf("三秒后自动清空数据\n");
Sleep(3000);
system("cls");
freeList(userList);
}
void printUserInfo(LIST_T *head)
{
LIST_T *tmp=head;
USER1_T *puser = NULL;
int count =0,i=0;
//1. 获取链表的长度 getListCount()
//2. 遍历链表 getNodeByPos()
//3. 获取数据域 结构体指针指向属性
puser = (USER1_T*)malloc(sizeof(USER1_T));
memset(puser,'\0',sizeof(USER1_T));
count = List_count(head);
for(i=1;i<count;i++)
{
puser=(USER1_T*)List_getNode(head,i);
printf("%d\t%s\t%s\t%d\n",puser->ID,puser->name,puser->pwd,puser->role);
}
}