C/C++Linux服务器开发/后台架构师【零声教育】-学习视频教程-腾讯课堂
防止用户能在主程序对链表内数据进行修改:用void* 修饰数据,回调函数来遍历数据。
代码如下:
LinkList.h
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//节点结构体
struct LinkNode {
//数据域
void* data;
//指针域
struct LinkNode* next;
};
//链表结构体
struct LList {
//头结点
struct LinkNode *pHeader;
//链表长度
int m_size;
};
typedef void* LinkList;
//初始化链表
LinkList init_LinkList();
//插入链表 按位置插
LinkList insert_LinkList(LinkList List , int pos, void * data);
//遍历链表
void foreach_LinkList(LinkList List , void (*MyPrint)(void*));
//删除链表 按位置删除
void DeleteByPos_LinkList(LinkList List, int pos);
//删除链表 按值删除
void DeleteByVal_LinkList(LinkList List, void * data , int (*Mycompare)(void* , void*));
//清空链表
void clean_LinkList(LinkList List);
//返回链表长度
int size_LinkList(LinkList list);
//销毁链表
void destroy_Linklist(LinkList list);
LinkList.c
#include "LinkList.h"
//初始化链表
LinkList init_LinkList()
{
struct LList * MyList = (struct LList *)malloc(sizeof(struct LList));
if (MyList == NULL)
{
return NULL;
}
//初始化头结点
MyList->pHeader = (struct LinkNode *)malloc(sizeof(struct LinkNode));
MyList->pHeader->data = NULL;
MyList->pHeader->next = NULL;
//初始化链表长度
MyList->m_size = 0;
return MyList;
}
//插入链表 按位置插
LinkList insert_LinkList(LinkList List , int pos, void * data)
{
if (List == NULL)
{
return ;
}
if (data == NULL)
{
return ;
}
//将List 还原成 struct LList 数据类型
struct LList * MyList = List;
//无效位置 尾插
if (pos < 0 || pos > MyList->m_size)
{
pos = MyList->m_size;
}
//插入结点的前驱结点
struct LinkNode * pCurrebt = MyList->pHeader;
//找到插入结点的前驱结点
for (int i = 0; i < pos; i++)
{
pCurrebt = pCurrebt->next;
}
//创建新节点
struct LinkNode * NewLinkNode = (struct LinkNode *)malloc(sizeof(struct LinkNode));
NewLinkNode->data = data;
//建立关系
NewLinkNode->next = pCurrebt->next;
pCurrebt->next = NewLinkNode;
//更新链表长度
MyList->m_size++;
}
//遍历链表
void foreach_LinkList(LinkList List, void (*MyPrint)(void*))
{
if (List == NULL)
{
return;
}
//将List 还原成 struct LList 数据类型
struct LList * MyList = List;
struct LinkNode * pCurrebt = MyList->pHeader->next;
for(int i = 0; i < MyList->m_size ; i++)
{
MyPrint(pCurrebt->data);
pCurrebt = pCurrebt->next;
}
}
//删除链表 按位置删除
void DeleteByPos_LinkList(LinkList List, int pos)
{
if (List == NULL)
{
return;
}
//将List 还原成 struct LList 数据类型
struct LList * MyList = List;
//无效删除位置
if (pos < 0 || pos > MyList->m_size - 1)
{
return;
}
//删除结点的前驱结点
struct LinkNode * pCurrebt = MyList->pHeader;
//找到删除结点的前驱结点
for (int i = 0; i < pos; i++)
{
pCurrebt = pCurrebt->next;
}
//待删除节点
struct LinkNode * DeleteLinkNode = pCurrebt->next;
//删除结点
pCurrebt->next = DeleteLinkNode->next;
free(DeleteLinkNode);
DeleteLinkNode = NULL;
//更新链表长度
MyList->m_size--;
}
//删除链表 按值删除
void DeleteByVal_LinkList(LinkList List, void * data, int(*Mycompare)(void*, void*))
{
if (List == NULL)
{
return;
}
if (data == NULL)
{
return;
}
//将List 还原成 struct LList 数据类型
struct LList * MyList = List;
//待删除的结点
struct LinkNode* pCurrent = MyList->pHeader->next;
/* //方法1
for(int i = 0; i < MyList->m_size ; i++)
{
if(Mycompare(pCurrent->data, data))
{
DeleteByPos_LinkList(List, i);
break;
}
pCurrent = pCurrent->next;
}
*/
//方法2
//删除结点的前驱结点
struct LinkNode* pPrev = MyList->pHeader;
for (int i = 0; i < MyList->m_size; i++)
{
if (Mycompare(pCurrent->data, data))
{
//建立关系
pPrev->next = pCurrent->next;
free(pCurrent);
pPrev = NULL;
//更新链表长度
MyList->m_size--;
break;
}
pPrev = pCurrent;
pCurrent = pCurrent->next;
}
}
//清空链表
void clean_LinkList(LinkList List)
{
if (List == NULL)
{
return;
}
//将List 还原成 struct LList 数据类型
struct LList * MyList = List;
//待删除的结点
struct LinkNode* pCurrent = MyList->pHeader->next;
//删除结点的后继结点
struct LinkNode* pNext = pCurrent;
for (int i = 0; i < MyList->m_size ; i++)
{
pNext = pCurrent->next;
free(pCurrent);
pCurrent = pNext;
}
MyList->pHeader->next = NULL;
MyList->m_size = 0;
}
//返回链表长度
int size_LinkList(LinkList list)
{
if (list == NULL)
{
return -1;
}
struct LList * Mylist = list;
return Mylist->m_size;
}
//销毁链表
void destroy_Linklist(LinkList list)
{
if (list == NULL)
{
return;
}
//清空链表
clean_LinkList(list);
free(list);
list = NULL;
}
main.c
#include "LinkList.h"
//测试
struct Person {
char name[128];
int age;
};
void myPrintPerson(void * data)
{
struct Person * p = data;
printf("name: %s \t, age: %d\n" , p->name , p->age);
}
int Mycompare(void* data1, void* data2)
{
struct Person * p1 = data1;
struct Person * p2 = data2;
return strcmp(p1->name, p2->name) == 0 && p1->age == p2->age;
}
int main(void)
{
//准备数据
struct Person p1 = { "亚瑟", 18 };
struct Person p2 = { "妲己", 20 };
struct Person p3 = { "安琪拉", 19 };
struct Person p4 = { "凯", 21 };
struct Person p5 = { "孙悟空", 999 };
struct Person p6 = { "李白", 999 };
//初始化链表
LinkList MyList = init_LinkList();
//插入数据
insert_LinkList(MyList, 0, &p1);
insert_LinkList(MyList, 0, &p2);
insert_LinkList(MyList, -1, &p3);
insert_LinkList(MyList, 0, &p4);
insert_LinkList(MyList, 1, &p5);
insert_LinkList(MyList, 0, &p6);
//遍历
foreach_LinkList(MyList, myPrintPerson);
printf("链表长度为:%d\n", size_LinkList(MyList));
printf("------------------------------\n");
// 李白 凯 孙悟空 妲己 亚瑟 安琪拉
//删除链表 按位置删除
DeleteByPos_LinkList(MyList, 1);
//遍历
foreach_LinkList(MyList, myPrintPerson);
printf("链表长度为:%d\n", size_LinkList(MyList));
printf("------------------------------\n");
// 李白 孙悟空 妲己 亚瑟 安琪拉
//删除链表 按位置删除
struct Person pD = { "亚瑟", 18 };
DeleteByVal_LinkList(MyList, &pD, Mycompare );
//遍历
foreach_LinkList(MyList, myPrintPerson);
printf("链表长度为:%d\n", size_LinkList(MyList));
printf("------------------------------\n");
// 李白 孙悟空 妲己 安琪拉
//测试清空
clean_LinkList(MyList);
//返回链表长度
printf("链表长度为:%d\n", size_LinkList(MyList));
//销毁
destroy_Linklist(MyList);
system("pause");
return EXIT_SUCCESS;
}
输出效果: