普通链表、企业链表之间的比较:
普通链表
对于普通链表,首先,我们会定义一个节点结构体。
这个链表节点结构体中会包含一个数据域,一个指针域
//链表节点的结构体
typedef struct LINKNODE
{
int data; //用来存放数据,但是这里的数据被写死了,只能存放 int 类型的数据
struct LINKNODE* next; //指针域
}LinkNode;
//定义链表的结构体
typedef struct LINKLIST
{
LinkNode* head; //定义一个头节点,用来对链表的初始化
int size; //用来记录链表中的数据的多少
}LinkList;
通过上述代码,可以看出。如果把节点中的数据域的类型写死,那么每换一种数据类型,就需要重新写一个链表。但是,如果我们把这个节点结构体 改成 void* 类型,那么就可以接收各种类型的数据。如下代码:
//链表节点的结构体
typedef struct LINKNODE
{
void* data; //改成void* ,就可以接收各种类型的数据
struct LINKNODE* next; //指针域
}LinkNode;
//定义链表的结构体
typedef struct LINKLIST
{
LinkNode* head; //定义一个头节点,用来对链表的初始化
int size; //用来记录链表中的数据的多少
}LinkList;
企业链表
如下代码
//链表节点的结构体
typedef struct LINKNODE
{
struct LINKNODE* next; //指针域
}LinkNode;
//定义链表的结构体
typedef struct LINKLIST
{
LinkNode head;
/*这里没有将头节点定义指针类型,链表每次初始化的时候,就不用再为头节点分配空
间,并且可以随着链表的释放一块释放
*/
int size; //用来记录链表中的数据的多少
}LinkList;
可以看出,企业链表在定义链表结构体时,并未在节点中添加数据域 。
也就是说,链表可以不用参加对数据的管理。可以降低耦合性。
但是,如果我们需要向链表中添加数据,我们就要在所需要添加的数据结构体中定义一个
LinkNode 类型的数据,这个 LinkNode 类型的数据就相当于将每个数据连接起来的链子,当每个所插入链表当中的数据能够通过这个链子连接起来,那么就构成了一个链表。
如果需要插入一个数据,需要将此数据的结构体如此定义:
typedef struct LINKDATA
{
LinkNode node; //node 即为上述连接数据之间的 链子
int a;
char b[32];
}LinkData;
企业链表的定义与实现
头文件:
//.h 文件
#ifndef QYLB_H
#define QYLB_H
#include <stdio.h>
#include <stdlib.h>
//定义链表节点
typedef struct LINKNODE
{
struct LINKNODE* next;
}LinkNode;
//定义链表结构体
typedef struct LINKLIST
{
LinkNode head;
int size;
}LinkList;
//定义函数指针
typedef int(*COMPARENODE)(LinkNode*,LinkNode*);
typedef void(*PRINTNODE)(LinkNode*);
//链表初始化
LinkList* Init_LinkList();
//根据位置插入
void Insert_LinkList(LinkList* list,int pos,LinkNode* data);
//根据位置删除
void Remove_LinkList(LinkList* list,int pos);
//查找
int Find_LinkList(LinkList* list,LinkNode* data,COMPARE compare);
//打印
void Print_LinkList(LinkList* list,PRINTNODE print);
//返回链表大小
int Size_LinkList(LinkList* list);
//释放链表内存
void FreeSpace_LinkList(LinkList* list);
#endif //QYLB_H
.c 文件
#include "qylb.h"
#include <string.h>
//链表初始化
LinkList* Init_LinkList();
{
LinkList* list = (LinkList*)malloc(sizeof(LinkList));
list->head.next = NULL;
list->size = 0;
return list;
}
//根据位置插入
void Insert_LinkList(LinkList* list,int pos,LinkNode* data)
{
//首先进行条件判断
if(list == NULL) return;
if(data == NULL) return;
if(pos < 0 || pos > list->size)
{
pos = list->size;
}
//进行指针移动,设置辅助指针
LinkNode* pCurrent = &(list->head);
for(int i = 0; i < pos; i++)
pCurrent = pCurrent->next;
//进行节点插入
data->next = pCurrent->next;
pCurrent->next = data;
list->size++;
}
//根据位置删除
void Remove_LinkList(LinkList* list,int pos);
{
//首先进行条件判断
if(list == NULL) return;
if(pos < 0 || pos > list->size) return;
//设置辅助指针
LinkNode* pCurrent = &(list->head);
for(int i = 0; i < pos; i++)
pCurrent = pCurrent->next;
//将需要删除的节点暂存
LinkNode* pDel = pCurrent->next;
pCurrent->next = pDel->next;
//释放内存
free(pDel);
list->size--;
}
//查找
int Find_LinkList(LinkList* list,LinkNode* data,COMPARE compare)
{
if(list == NULL) return -1;
if(data == NULL) return -1;
//设置辅助指针
LinkNode* pCurrent = &(list->head);
int i = -1;
for(i = 0; i < list->size; i++)
{
pCurrent = pCurrent->next;
if(compare(pCurrent,data) == 0)
{
break;
}
}
return i;
}
//打印
void Print_LinkList(LinkList* list,PRINTNODE print)
{
if(list == NULL) return;
LinkNode* pCurrent = list->head.next;
for(int i = 0; i < list->size - 1; i++)
{
print(pCurrent);
pCurrent = pCurrent->next;
}
}
//返回链表大小
int Size_LinkList(LinkList* list)
{
if(list == NULL) return -1;
return list->size;
}
//释放链表内存
void FreeSpace_LinkList(LinkList* list)
{
if(list == NULL) return;
free(list);
list->size = 0;
}
//定义数据结构体
typedef struct PERSON
{
LinkNode node;
int age;
char name[32];
}Person;
void MyPrint(LinkNode* data)
{
Person* p = (Person*)data;
printf("Name:%s Age:%d\n",p->name,p->age);
}
int MyCompare(LinkNode* node1,LinkNode* node2)
{
Person* p1 = (Person*)node1;
Person* p2 = (Person*)node2;
if(strcmp(p1->name,p2->name) == 0 && p1->age == p2->age)
return 0;
return -1;
}
int main()
{
return 0;
}