当前位置: 代码网 > it编程>编程语言>C/C++ > 使用万能指针实现通用链表

使用万能指针实现通用链表

2024年07月28日 C/C++ 我要评论
通过以上代码示例,我们实现了一个通用链表,可以存储任意类型的数据。通过使用函数指针和万能指针,我们实现了对不同类型数据的存储和操作。这种通用链表的设计可以在实际开发中提供更大的灵活性和可扩展性。

使用万能指针实现通用链表

在这里插入图片描述

前面通过地址偏移量计算结构体成员变量首地址,来访问结构体里的成员。现在,我们将通过使用万能指针来实现通用链表,使得链表可以存储任意类型的数据。

废话不多说,直接上代码

#list.h

#ifndef list_h
#define list_h
#include<stdbool.h>
#include<stdio.h>

typedef int (*compar)(const void*,const void*);

//结点
typedef struct node
{
	void *ptr;
	struct node *prev;
	struct node *next;
}node;

//通用链表
typedef struct list
{
	node *head;
	size_t size;
}list;

//创建
list *create_list(void);
//添加
void add_list(list *list,void *ptr);
//插入
bool insert_list(list *list,size_t index,void *ptr);
//删除 按位置
bool del_index_list(list *list,size_t index);
//删除  按值
bool del_value_list(list *list,void *ptr,compar cmp);
//查询
void *query_list(list *list,void *ptr,compar cmp);
//访问
void *visit_list(list *list,size_t index);
//遍历
void show_list(list *list,void (*show)(void*));
//排序
void sort_list(list *list,compar cmp);
//清空
void clean_list (list *list);
//销毁
void destroy_list(list *list);

#endif//list_h

#list.c

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


//创建结点
static node *create_node(void *ptr)
{
	node *node=malloc(sizeof(node));
	node->ptr=ptr;
	node->prev=node;
	node->next=node;
	return node;
}

//创建
list *create_list(void)
{
	list *list=malloc(sizeof(list));
	list->head=create_node(0);
	list->size=0;
	return list;
}
//两节点间插入新结点
void _add_list(node *prev,node *next,void *ptr)
{
	node *node=create_node(ptr);
	prev->next=node;
	node->next=next;
	next->prev=node;
	node->prev=prev;
}

//根据位置访问结点
static node *_visit_list(list *list,size_t index)
{
	if(index<0||index>=list->size)return null;
	if(index>list->size/2)
	{
		node *node=list->head->prev;
		while(++index<list->size)node=node->prev;
		return node;
	}
	else
	{
		node *node=list->head->next;
		while(index--)node=node->next;
		return node;
	}
}
//删除结点
static void _del_list(node *node)
{
	node->prev->next=node->next;
	node->next->prev=node->prev;
	free(node->ptr);
	free(node);
}
//尾添加
void add_list(list *list,void *ptr)
{
	_add_list(list->head->prev,list->head,ptr);
	list->size++;
}


//插入
bool insert_list(list *list,size_t index,void *ptr)
{
	node *node=_visit_list(list,index);	
	if(null==node)return false;
	_add_list(node->prev,node,ptr);
	list->size++;
	return true;
}
//删除 按位置
bool del_index_list(list *list,size_t index)
{
	node *node=_visit_list(list,index);
	if(null==node)return false;
	_del_list(node);
	list->size--;
	return true;
}
//删除  按值
bool del_value_list(list *list,void *ptr,compar cmp)
{
	for(node *n=list->head->next;n!=list->head;n=n->next)
	{
		if(0==cmp(ptr,n->ptr))
		{
			_del_list(n);
			list->size--;
			return true;
		}
	}
	return false;
}

//查询
void *query_list(list *list,void *ptr,compar cmp)
{
	 for(node *n=list->head->next;n!=list->head;n=n->next)
	 {
			if(0==cmp(ptr,n->ptr))
			{
				return n->ptr;
			}
	 }
	 return null;
}
//访问
void *visit_list(list *list,size_t index)
{
	node *n=_visit_list(list,index);
	if(null==n)return false;
	return n->ptr;
}
//遍历
void show_list(list *list,void (*show)(void*))
{	
	for(node *node=list->head->next;node!=list->head;node=node->next)
	{	
		show(node->ptr);
	}
}
//排序
void sort_list(list *list,compar cmp)
{
	for(node *n=list->head->next;n!=list->head;n=n->next)
	{
		for(node *m=n->next;m!=list->head;m=m->next)
		{
			if(1==cmp(n->ptr,m->ptr))
			{
				void *temp=n->ptr;
				n->ptr=m->ptr;
				m->ptr=temp;
			}
		}
	}
}
//清空
void clean_list (list *list)
{
	node *n=list->head->next;
	while(n!=list->head)
	{
		node *temp=n;
		n=n->next;
		free(temp);
	}
	list->head->next=list->head;
	list->head->prev=list->head;
	list->size=0;
}
//销毁
void destroy_list(list *list)
{
	clean_list(list);
	free(list->head);
	free(list);
}


#main.c

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

typedef struct student
{
	char name[20];
	char sex;
	int id;
}student;

void show_stu(void *ptr)
{
	student *stu=ptr;
	printf("name:%s sex:%c id:%d \n",stu->name,stu->sex,stu->id);
}
int stucmp(const void *p1,const void *p2)
{
	const student *s1=p1,*s2=p2;
	if(s1->id>s2->id)
	{
		return 1;
	}
	else if(s1->id<s2->id)
		return -1;
	else return 0;
}
int main(int argc,const char* argv[])
{
	list *list=create_list();
	for(int i=0;i<10;i++)
	{
		student *stu=malloc(sizeof(student));
		sprintf(stu->name,"浩楠%d",i);
		stu->sex=i%2?'w':'m';
		stu->id=1000-i;
		add_list(list,stu);
	}

	show_list(list,show_stu);
	student s={"刘浩1",'m',1001};
	insert_list(list,5,&s);
	sort_list(list,stucmp);
	printf("------------------\n");
	show_list(list,show_stu);
	return 0;
}

通过以上代码示例,我们实现了一个通用链表,可以存储任意类型的数据。通过使用函数指针和万能指针,我们实现了对不同类型数据的存储和操作。这种通用链表的设计可以在实际开发中提供更大的灵活性和可扩展性。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com