02-普通链表、企业链表

一、普通链表的实现

普通链表也就是我门平常上数据结构所写的一样。

(1)头文件
#ifndef LINKLIST
#define LINKLIST

//链表结点
typedef struct LINKNODE{
	void* data;//指向任何类型数据
	struct LINKNODE* next;
}LinkNode;

//打印函数指针(因为链表结点是void* 形指针,所以我们用一个回调函数,让用户自己去写这个回调函数进行数据的输出)
typedef void(*PRINTLINKNODE)(void*);

//链表结构体
typedef struct LINKLIST{
	LinkNode* head;
	int size;//需要容量吗?链表是没有容量的概念的
}LinkList;

//初始化链表
LinkList* Init_LinkList();
//指定位置插入
void Insert_LinkList(LinkList* list, int pos, void* data);
//删除指定的位置的值
void RemoveByPos_LinkList(LinkList* list, int pos);
//获取链表的长度
int Size_LinkList(LinkList* list);
//查找
int Find_LinkList(LinkList* list,void* data);
//打印链表结点
void Print_LinkList(LinkList* list, PRINTLINKNODE print);
//返回第一个结点
LinkNode* Front_LinkList(LinkList* list);
//释放链表内存
void FreeSpace_LinkList(LinkList* list);

#endif 
(2)函数的实现
#include<stdlib.h>
#include"LinkLIst.h"

//创建链表
LinkList* Init_LinkList(){
	LinkList* list = (LinkList*)malloc(sizeof(LinkList));
	//头结点是不保存数据信息的
	list->head = (LinkNode*)malloc(sizeof(LinkNode));
	list->head->next = NULL;
	list->head->data = NULL;
	list->size = 0;
	return list;
}
//指定位置插入
void Insert_LinkList(LinkList* list, int pos, void* data){
	if (list == NULL){
		return;
	}
	//友好的处理pose越界
	if (pos > list->size|| pos<0){
		pos = list->size;
	}
	//创建赋值指针变量
	LinkNode* pCurrent = list->head;
	for (int i = 0; i < pos; i++){
		pCurrent = pCurrent->next;
	}
	//创建新的结点
	LinkNode* newNode = (LinkNode*)malloc(sizeof(LinkNode));
	newNode->data = data;
	newNode->next = pCurrent->next;
	pCurrent->next = newNode;
	list->size++;
}
//删除指定的位置的值
void RemoveByPos_LinkList(LinkList* list, int pos){
	if (list == NULL){
		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 Size_LinkList(LinkList* list){
	if (list == NULL){
		return -1;
	}
	return list->size;
}
//查找
int Find_LinkList(LinkList* list,void* data){
	if (list == NULL){
		return -1;
	}
	//记录查找到的位置
	int pos;
	//创建辅助指针变量
	LinkNode* pCurrent = list->head->next;
	for (int i = 0; i < list->size; i++){
		if (pCurrent->data ==data){
			pos = i;
			break;
		}
		pCurrent = pCurrent->next;
	}
	return pos;
}
//打印链表结点
void Print_LinkList(LinkList* list, PRINTLINKNODE print){
	if (list == NULL){
		return;
	}
	//创建赋值指针变量
	LinkNode* pCurrent = list->head->next;
	while (pCurrent != NULL){
		print(pCurrent->data);
		pCurrent = pCurrent->next;
	}
}
//返回第一个结点
LinkNode* Front_LinkList(LinkList* list){
	if (list == NULL){
		return NULL;
	}
	return list->head->next->data;
}
//释放链表内存(这样写是错误的!!!你看如果到了pcurrent等于最后一个节点,则rpcurrent=null进入while循环
//到了rpcurrent=rpCurrent->next这一行时,就报空指针异常了
/*void FreeSpace_LinkList(LinkList* list){
	if (list == NULL){
		return;
	}
	//创建辅助指针变量
	LinkNode* pCureent = list->head;
	//缓存下一个结点
	LinkNode* rpCurrent = list->head->next;
	while (pCureent != NULL){
		free(pCureent);
		pCureent = rpCurrent;
		rpCurrent = rpCurrent->next;
	}
	list->size = 0;
	free(list);
}*/

void FreeSpace_LinkList(LinkList* list){
	if (list == NULL){
		return;
	}
	//创建辅助指针变量
	LinkNode* pCurrent = list->head;
	while (pCurrent != NULL){
		LinkNode* pNext = pCurrent->next;
		free(pCurrent);
		pCurrent = pNext;
	}
}
(3)测试
#include<stdlib.h>
#include<stdio.h>
#include"LinkLIst.h"

//创建打印函数
void myPrint(void * data){
	printf("%s\n", (char*)data);
}
int main(){

	

	//获取链表
	LinkList* list = Init_LinkList();
	//创建一些数据
	char* str1 = "有很多话想对你说 但一直没有机会";
	char* str2 = "我携带这它们穿越季节 掠过高架 铺在山与海之间";
	char* str3 = "花盛开就是一句 夜漫过就是一篇";
	char* str4 = "黄昏开始书写 黎明是无数的扉页";
	char* str5 = "全世界拼成首诗 我爱你当做最后一行";

	//向链表中插入数据
	Insert_LinkList(list, 0,str1);
	Insert_LinkList(list, 1, str2);
	Insert_LinkList(list, 2, str3);
	Insert_LinkList(list, 3, str4);
	Insert_LinkList(list, 4, str5);

	//打印数据
	Print_LinkList(list, myPrint);
	printf("-------------------------------------\n");

	//返回链表的第一个元素
	char* str = (char*)Front_LinkList(list);
	printf("%s\n", str);
	printf("-------------------------------------\n");

	//删除	char* str3 = "花盛开就是一句 夜漫过就是一篇";
	RemoveByPos_LinkList(list, 2);
	Print_LinkList(list, myPrint);
	printf("-------------------------------------\n");

	//获取链表的大小
	printf("%d\n", list->size);
	
	//查找值
	printf("查到str2的位置为%d\n",Find_LinkList(list, str5));
	//释放链表内存
	FreeSpace_LinkList(list);

	system("pause");
}

在这里插入图片描述

二、企业链表的实现

(1)头文件
#ifndef LINKLIST_H
#define LINKLIST_H

//链表小节点
typedef struct LINKNODE
{
	struct LINKNODE* next;
}LinkNode;

//链表结点
typedef struct LINKLIST{
	LinkNode head;
	int size;
}LinkList;

//打印函数
typedef void(*PRINTNODE)(LinkNode*);

//初始化链表
LinkList* Init_LinkList();
//安装顺序插入
void Insert_LinkList(LinkList* list, LinkNode* data);
//按照指定位置进行插入
void InsertByPose_LinkList(LinkList* list, int pose, LinkNode* data);
//删除
void Remove_LinkList(LinkList* list, int pose);
//查找
int Find_LinkList(LinkList* list, LinkNode* data);
//返回链表大小
int Size_LinkList(LinkList* list);
//打印
void Print_LinkList(LinkList* list, PRINTNODE print);
//释放链表内存
void Free_LinkList(LinkList* list);

#endif
(2)函数的实现
#include<stdlib.h>
#include"LinkList.h"
//初始化链表
LinkList* Init_LinkList(){
	LinkList* list = (LinkList*)malloc(sizeof(LinkList));
	list->head.next = NULL;
	list->size = 0;
	return list;
}
//按照顺序插入
void Insert_LinkList(LinkList* list, LinkNode* data){
	if (list == NULL){
		return;
	}
	//创建辅助指针变量
	LinkNode* pCurrent = &(list->head);
	while (pCurrent->next != NULL)
	{
		pCurrent = pCurrent->next;
	}
	pCurrent->next = data;
	data->next = NULL;
	list->size++;
}
//按照指定位置进行插入
void InsertByPose_LinkList(LinkList* list, int pose, LinkNode* data){
	if (list == NULL){
		return;
	}
	//创建辅助指针变量
	LinkNode* pCurrent = &(list->head);
	for (int i = 0; i < pose; i++){
		pCurrent = pCurrent->next;
	}	
	data->next = pCurrent->next;
	pCurrent->next = data;
	list->size++;
}
//删除
void Remove_LinkList(LinkList* list, int pose){
	if (list == NULL){
		return;
	}
	//创建辅助指针变量
	LinkNode* pCurrent = &(list->head);
	for (int i = 0; i < pose; i++){
		pCurrent = pCurrent->next;
	}
	pCurrent->next = pCurrent->next->next;
	list->size--;
}
//查找
int Find_LinkList(LinkList* list, LinkNode* data){
	if (list == NULL){
		return -1;
	}
	//创建辅助指针变量
	int pose=0;
	LinkNode* pCurrent = list->head.next;
	while (pCurrent){
		if (pCurrent == data){
			return pose;
		}
		pose++;
		pCurrent = pCurrent->next;
	}
}
//返回链表大小
int Size_LinkList(LinkList* list){
	if (list == NULL){
		return -1;
	}
	return list->size;
}
//打印
void Print_LinkList(LinkList* list, PRINTNODE print){
	if (list == NULL){
		return;
	}
	//创建辅助指针变量
	LinkNode* pCurrent = list->head.next;
	while (pCurrent){
		print(pCurrent);
		pCurrent = pCurrent->next;
	}
}
//释放链表内存
void Free_LinkList(LinkList* list){
	if (list == NULL){
		return;
	}
	free(list);
}
(3)测试
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"LinkList.h"

typedef struct SCENTENCE {
	LinkNode node;
	char str[64];
}Sctence;

//打印函数
void myPrint(LinkNode* data){
	Sctence* s = (Sctence*)data;
	printf("%s\n", s->str);
}
int main(){

	//获得链表对象
	LinkList* list = Init_LinkList();

	//创建一些数据
	Sctence s1, s2, s3, s4, s5,s6;
	strcpy(s1.str, "有很多话想对你说 但一直没有机会");
	strcpy(s2.str, "我携带这它们穿越季节 掠过高架 铺在山与海之间");
	strcpy(s3.str, "花盛开就是一句 夜漫过就是一篇");
	strcpy(s4.str, "黄昏开始书写 黎明是无数的扉页");
	strcpy(s5.str, "全世界拼成首诗 我爱你当做最后一行");
	strcpy(s6.str, "你归来是诗 离去成词 且笑风尘不敢造次");

	//插入数据到链表
	Insert_LinkList(list,(LinkNode*)&s1);
	Insert_LinkList(list, (LinkNode*)&s2);
	Insert_LinkList(list, (LinkNode*)&s3);
	Insert_LinkList(list, (LinkNode*)&s4);
	Insert_LinkList(list, (LinkNode*)&s5);

	InsertByPose_LinkList(list, 3, (LinkNode*)&s6);

	//InsertByPose_LinkList(list, 0,(LinkNode*)&s1);

	//删除某个元素
	Remove_LinkList(list, 3);

	//打印
	Print_LinkList(list, myPrint);

	//查找某个元素
	int pose = Find_LinkList(list, (LinkNode*)&s3);
	printf("查找到的位置为%d\n", pose);

	//返回链表的大小
	int size = Size_LinkList(list);
	printf("链表的长度为:%d\n", size);
	//释放内存
	Free_LinkList(list);
	system("pause");
	return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值