【3】线性表的存储--企业级链表

本文详细讲解了如何在C++中使用自定义的Person结构体,并结合链表实现数据存储与操作。重点介绍了链表的构建、插入、删除、查找功能,以及如何通过LinkList结构处理不同类型的数据,如Person。
摘要由CSDN通过智能技术生成

企业级链表

·····原理理解·······:

如果存在以下两个结构体(person中包含了abc):

typedef struct ABC {
	int a;
}abc;

typedef struct PERSON {
	abc c;
	char name[64];
	int age;
}Person;

那么如输出所示:

int main() {
	Person p1;
	strcpy(p1.name, "aaa");
	p1.age = 10;
	p1.c.a = 1;
	ABC* x1 = (ABC*)&p1;
	cout << (*x1).a<<endl;//1
	cout << p1.c.a;//1
	return 0;
}

1、p1是结构体person的实例,其中p1.c.a=1
2、(ABC* x1 = (ABC*)&p1)将p1的地址中属于结构体abc的地址赋值给x1
3、x1包含了p1的内容,但是只能访问到abc。而访问不到name、age等变量。
4、对*x1的操作等同于对p1.c的操作。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

1、数据结构

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

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

2、打印与比较函数(用户自定)

//遍历函数指针
typedef void(*PRINTNODE)(LinkNode*);
//比较函数指针
typedef int(*COMPARENODE)(LinkNode*, LinkNode*);

3、初始化

LinkList* Init_LinkList(){

	LinkList* list = (LinkList*)malloc(sizeof(LinkList));
	list->head.next = NULL;
	list->size = 0;
	return list;
}

3、插入

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++;
}

5、删除

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;
	}

	//删除结点
	pCurrent->next = pCurrent->next->next;

	list->size--;
}

6、查找

int Find_LinkList(LinkList* list, LinkNode* data, COMPARENODE compare){

	if (list == NULL){
		return -1;
	}

	if (data == NULL){
		return -1;
	}

	//赋值指针变量
	LinkNode* pCurrent = list->head.next;
	int index = 0;
	int flag = -1;
	while (pCurrent != NULL	){
		if (compare(pCurrent, data) == 0){
			flag = index;
			break;
		}
		pCurrent = pCurrent->next;
		index++;
	}

	return flag;
}

7、返回链表大小

//返回链表大小
int Size_LinkList(LinkList* list){
	return 0;
}

8、打印整个链表

void Print_LinkList(LinkList* list, PRINTNODE print){//具体的打印函数需要用户自己编写

	if (list == NULL){
		return;
	}

	//辅助指针
	LinkNode* pCurrent = list->head.next;
	while (pCurrent != NULL){
		print(pCurrent);
		pCurrent = pCurrent->next;
	}
}

9、释放链表

//释放链表内存
void FreeSpace_LinkList(LinkList* list){

	if (list == NULL){
		return;
	}

	free(list);
}

主程序示意

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "LinkList.h"

typedef struct PERSON{//用户自定数据类型
	LinkNode node;
	char name[64];
	int age;
}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(void){
	//创建链表
	LinkList* list = Init_LinkList();
	//创建数据
	Person p1, p2, p3, p4, p5;
	strcpy(p1.name, "aaa");
	strcpy(p2.name, "bbb");
	strcpy(p3.name, "ccc");
	strcpy(p4.name, "ddd");
	strcpy(p5.name, "eee");
	
	p1.age = 10;
	p2.age = 20;
	p3.age = 30;
	p4.age = 40;
	p5.age = 50;

	//将结点插入链表
	Insert_LinkList(list, 0, (LinkNode*)&p1);//只需要传入p1中linknode的部分
	Insert_LinkList(list, 0, (LinkNode*)&p2);
	Insert_LinkList(list, 0, (LinkNode*)&p3);
	Insert_LinkList(list, 0, (LinkNode*)&p4);
	Insert_LinkList(list, 0, (LinkNode*)&p5);

	//打印
	Print_LinkList(list, MyPrint);//需要传入自建的打印函数

	//删除结点
	Remove_LinkList(list, 2);

	//打印
	printf("---------------\n");
	Print_LinkList(list, MyPrint);

	//查找
	Person findP;
	strcpy(findP.name, "bbb");
	findP.age = 20;
	int pos = Find_LinkList(list, (LinkNode*)&findP, MyCompare);
	printf("位置:%d\n",pos);

	//释放链表内存
	FreeSpace_LinkList(list);


	system("pause");
	return 0;
}

总结:

这种链表的构建方式可以适应各种数据类型(结构体)。用户自己建立的结构体中必须要含有linknode结构体。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值