03黑马数据结构笔记之(单向)企业链表(小挂钩)

03黑马数据结构笔记之(单向)企业链表(小挂钩)

1 思路:链表不直接存放插入的整个数据,只存放数据的首地址,也就是我们自定义的小挂钩,实际上是一个节点,该节点只有一个用于连接数据的next指针。 例如我们在mian函数看数据插入时,将类型转为挂钩类型插入,链表一次将挂钩连接起来。

//小节点,即挂钩
typedef struct Node{
	struct Node *next;
}SNode;

//大节点,即用来保存整个链表的结构体
typedef struct List{
	SNode head;  //挂钩对象,不需要在开辟内存了
	int size;
}LinkList;

代码实现:
1)头文件.h:

#ifndef LINKLIST_H
#define LINKLIST_H

#include<stdio.h>
#include<stdlib.h>

//小节点,即挂钩
typedef struct Node{
	struct Node *next;
}SNode;

//大节点,即用来保存整个链表的结构体
typedef struct List{
	SNode head;  //挂钩对象,不需要在开辟内存了
	int size;
}LinkList;


//打印函数指针
typedef void(*PRINT)(SNode *);
typedef int(*MYCOMPARE)(SNode *s1,SNode *s2);

//初始化链表
LinkList *Init_LinkList();
//插入链表   插入时只需将数据的首地址传过来插入 打印时在转回全部打印
int Insert_LinkList(LinkList *list,int pos,SNode *data);
//删除
int Del_LinkList(LinkList *list,int pos);
//查找
int Find_LinkList(LinkList *list,MYCOMPARE myc,SNode *data);
//打印
int Printt_LinkLis(LinkList *list,PRINT print);
//返回链表大小
int Get_Size_LinkList(LinkList *list);
//释放内存
int Destory_LinkList(LinkList *list);

#endif

2).cpp文件:

#include"LinkList.h"

//初始化链表
LinkList *Init_LinkList(){

	LinkList *list=(LinkList*)malloc(sizeof(LinkList));
	list->size=0;
	list->head.next=NULL;  //对象不需要再赋值

	return list;

}
//插入链表   插入时只需将数据的首地址传过来插入 打印时在转回全部打印
int Insert_LinkList(LinkList *list,int pos,SNode *data){

	if(list==NULL){
		return -1;
	}
	if(pos<0 || pos > list->size){
		pos=list->size;
	}

	//查找插入点的前一个点--因为头结点不包含在size,且第一个有效节点下标为0。
	//我之前写传统的代码是减1的,不怎么对,之前的数据以1开始下标,这里应该以0更好!!!
	SNode *pPre=&(list->head);
	for(int i=0;i<pos ;i++){
		pPre=pPre->next;
	}
	//插入
	SNode *pCur=pPre->next;
	data->next=pCur;
	pPre->next=data;

	list->size++;
	
	return 0;

}
//删除--根据下标删除
int Del_LinkList(LinkList *list,int pos){
	if(list==NULL){
		return -1;
	}
	//找到要删除的前一节点  注意是按下标的,所以pos不需要减1了
	SNode *pPre=&(list->head);
	for(int i=0;i<pos ;i++){
		pPre=pPre->next;
	}

	//删除
	pPre->next=pPre->next->next;

	list->size--;

	return 0;

}
//查找
int Find_LinkList(LinkList *list,MYCOMPARE myc,SNode *data){
	if(list==NULL){
		return -1;
	}
	if(data==NULL){
		return -1;
	}
	SNode *pCur=list->head.next;
	int count=0;   //注意:头结点不包含在size,且第一个有效节点下标为0
	while(pCur!=NULL){
		//需要使用到自定义函数查找,所以需要函数指针
		if(myc(pCur,data)){
			break;
		}
		pCur=pCur->next;
		count++;
	}
	if(count==list->size){
		printf("没找到而退出\n");
		return -1;
	}

	return count;
}
//打印
int Printt_LinkLis(LinkList *list,PRINT print){
	if(list==NULL){
		return -1;
	}
	SNode *pCur=list->head.next;
	while(pCur!=NULL){
		print(pCur);
		pCur=pCur->next;
	}

	return 0;
}
//返回链表大小
int Get_Size_LinkList(LinkList *list){
	return list->size;
}
//释放内存
int Destory_LinkList(LinkList *list){
	if(list==NULL){
		return -1;
	}
	//只有链表的结构体需要释放
	free(list);
	
	return 0;
}

3)主函数测试:

#include"LinkList.h"
#include<string>

typedef struct Person{
	SNode *node;
	char name[64];
	int age;
}Person;

//打印自定义回调函数
void MyPrint(SNode *s){
	Person *p=(Person*)s; //将SNode*型转回自定义类型打印
	printf("名字:%s,年龄:%d\n",p->name,p->age);

}

//查找自定义回调函数
int MyCompare(SNode *s1,SNode *s2){
	Person *p1=(Person*)s1;
	Person *p2=(Person*)s2;
	if(strcmp(p1->name,p2->name)==0 && p1->age==p2->age){
		return 1;   //返回1代表相等找到了
	}
	return 0;
}

void test02(){

	//创建结构体链表
	LinkList *list=Init_LinkList();

	//创建数据
	Person p1;
	Person p2;
	Person p3;
	Person p4;
	Person p5;

	strcpy(p1.name,"aaa");
	strcpy(p2.name,"bbb");
	strcpy(p3.name,"ccc");
	strcpy(p4.name,"ddd");
	strcpy(p5.name,"eee");

	p1.age=18;
	p2.age=20;
	p3.age=32;
	p4.age=28;
	p5.age=19;
	 
	//插入数据   插入时只需传挂钩就可以 链表实际上只存放挂钩的地址 需要打印数据在转化成相应类型
	Insert_LinkList(list,0,(SNode*)&p1);
	Insert_LinkList(list,0,(SNode*)&p2);
	Insert_LinkList(list,0,(SNode*)&p3);
	Insert_LinkList(list,0,(SNode*)&p4);
	Insert_LinkList(list,0,(SNode*)&p5);

	//打印链表
	Printt_LinkLis(list,MyPrint);

	//根据数据查找链表节点
	int pos=Find_LinkList(list,MyCompare,(SNode*)&p3); 
	printf("查到返回的下标是:%d\n",pos);  //2

	//删除
	Del_LinkList(list,2);
	Printt_LinkLis(list,MyPrint);

	//返回链表大小
	int size=Get_Size_LinkList(list);
	printf("链表大小:%d\n",size);

	//销毁链表
	Destory_LinkList(list);
}

int main(){

	test02();

	return 0;
}


//总结:主要是要懂企业链表的思想.将节点放在首地址
发布了54 篇原创文章 · 获赞 1 · 访问量 714

猜你喜欢

转载自blog.csdn.net/weixin_44517656/article/details/105288226