肥貓學習日記------關於鏈表的擴展(二)通用鏈表

通用鏈表

通用鏈表與一般鏈表不同的地方在與其數據域類型是不確定的,我們用void這個萬能指針來代替原有的數據域類型
void
是一個萬能指針,可以與任意類型的指針互換,如 int* = void*,char* =void*
要注意的一點是:由於存儲類型的不確定性,我們無法直接使用到關係運算符進行運算,需要使用者提供一個函數供鏈表使用,也就是回調函數
比方說比較兩個數據時,我們不知道數據類型,就要自己提供一個比較函數。

通用鏈表的創建

準備工具

就之前而言,通用鏈表的難點就是我們無法使用關係運算符,如相等,不等等,所以我們需要先準備一個比較函數

int cmp(const void*ptr1,const void*ptr2)
{
	const double* p1=ptr1;
	//這裏只是舉例爲double類型,根據實際需要可以自己改變類型
	//比如說學生管理系統裏,節點爲Student*類型,那我們就可以改爲
	//const Student* 然後再比較需要比較的數據類型
	const double* p2=ptr2;
	if(*p1>*p2)
		return 1;
	else if(*p1<*p2)
		return -1;
	else
		return 0;
}

如果我們需要顯示節點中的數據,由於不知道數據類型,我們也要自己寫一個函數

void show(void* ptr)
{
	const double* p=ptr;//同理如上,double只是舉例
	printf("%lf",p);
}
創建結點

與普通鏈表相比,只是改變了數據域的類型

typedef struct Node
{
	void* ptr;	//從準確的數據類型變爲指向首地址的指針,那麼數據類型我們就可以進行改變
	struct Node* next;
}Node;

Node* creat_node(void* ptr)
{
	Node* node=malloc(sizeof(Node));
	node->ptr=ptr;
	node->next= NULL;
	return node;
}
創建鏈表
typedef struct List
{
	Node* head;
	size_t size;
}List;

List* creat_list(void)
{
	List* list = malloc(sizeof(List));
	list->head=NULL;
	list->size=0;
	return list;
}
對鏈表的操作

大部分操作與鏈表相同,我就寫一些稍微不同的

查找值爲value的元素
int find_list(List* list,void* ptr,compar cmp)
{
	int index=0;
	for(Node* i=list->head;NULL != i;i=i->next)
	{
		if(0 == cmp(i->ptr,ptr))//調用上述函數進行比較
		{
			return index;
			}
		index++;
	}
}
遍歷
void show_list(List* list,void(*show)(const void* ptr))
{
	for(Node* i=list->head;NULL != i;i=i->next)
	{
		show(i->ptr);
	}
	printf("\n");
}
其餘的與長長鏈表差不多相同,稍微修改下參數就行了,需要比較的話參考查找就行
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章