c語言——單向鏈表

c語言——單向鏈表

此版鏈表需要手動管理內存,版本二爲優化版c語言——單向鏈表II

頭文件LinkList.h

#pragma once

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

#ifdef __cplusplus
extern "C"{
#endif

	typedef void * LinkList;
	typedef void(*FOREACH)(void *);
	typedef int(*COMPARE)(void *,void *);

	//初始化鏈表
	LinkList Init_LinkList();
	//插入節點
	void Insert_LinkList(LinkList list,int pos,void *data);
	//遍歷鏈表
	void Foreach_LinkList(LinkList list, FOREACH myforeach);
	//按位置刪除
	void RemoveByPos_LinkList(LinkList list,int pos);
	//按值刪除
	void RemoveByVal_LinkList(LinkList list, void *data, COMPARE compare);
	//清空鏈表
	void Clear_LinkList(LinkList list);
	//大小
	int Size_LinkList(LinkList list);
	//銷燬鏈表
	void Destroy_LinkList(LinkList list);


#ifdef __cplusplus
}
#endif

單向鏈表LinkList.c

初始化鏈表

#include"LinkList.h"

//鏈表節點數據類型
struct LinkNode
{
	void *data;
	struct LinkNode *next;
};

//鏈表數據類型
struct LList
{
	struct LinkNode header;
	int size;
};



//初始化鏈表
LinkList Init_LinkList()
{
	struct LList *list = malloc(sizeof(struct LList));
	if (NULL == list)
	{
		return NULL;
	}

	list->header.data = NULL;
	list->header.next = NULL;
	list->size = 0;

	return list;
}

插入節點

//插入節點
void Insert_LinkList(LinkList list, int pos, void *data)
{	
	if (NULL == list)
	{
		return;
	}

	if (NULL == data)
	{
		return;
	}

	struct LList * mylist = (struct LList *)list;

	if (pos < 0 || pos > mylist->size)
	{
		pos = mylist->size;
	}

	//查找插入位置
	struct LinkNode *pCurrent = &(mylist->header);
	for (int i = 0; i < pos; ++i)
	{
		pCurrent = pCurrent->next;
	}

	//創建新節點
	struct LinkNode *newnode = malloc(sizeof(struct LinkNode));
	newnode->data = data;
	newnode->next = NULL;

	//新節點插入到鏈表中
	newnode->next = pCurrent->next;
	pCurrent->next = newnode;

	mylist->size++;
}

遍歷鏈表

//遍歷鏈表
void Foreach_LinkList(LinkList list, FOREACH myforeach) /*回調函數*/
{

	if (NULL == list)
	{
		return;
	}

	if (NULL == myforeach)
	{
		return;
	}

	struct LList * mylist = (struct LList *)list;

	struct LinkNode *pCurrent = mylist->header.next;

	while (pCurrent != NULL)
	{
		myforeach(pCurrent->data);
		pCurrent = pCurrent->next;
	}

}

按位置刪除

//按位置刪除
void RemoveByPos_LinkList(LinkList list, int pos)
{

	if (NULL == list)
	{
		return;
	}

	struct LList *mylist = (struct LList *)list;

	if (pos < 0 || pos > mylist->size - 1)
	{
		return;
	}


	//找位置
	struct LinkNode *pCurrent = &(mylist->header);
	for (int i = 0; i < pos; ++i)
	{
		pCurrent = pCurrent->next;
	}


	//先保存待刪除結點
	struct LinkNode *pDel = pCurrent->next;
	//重新建立待刪除結點的前驅和後繼結點關係
	pCurrent->next = pDel->next;
	//釋放刪除節點內存
	free(pDel);
	pDel = NULL;

	mylist->size--;

}

按值刪除

//按值刪除
void RemoveByVal_LinkList(LinkList list, void *data, COMPARE compare)
{

	if (NULL == list)
	{
		return;
	}

	if (NULL == data)
	{
		return;
	}

	if (NULL == compare)
	{
		return;
	}

	struct LList *mylist = (struct LList *)list;

	//輔助指針變量
	struct LinkNode *pPrev = &(mylist->header);
	struct LinkNode *pCurrent = pPrev->next;

	while (pCurrent != NULL)
	{
		if (compare(pCurrent->data, data))
		{
			//找到了
			pPrev->next = pCurrent->next;
			//釋放刪除節點內存
			free(pCurrent);
			pCurrent = NULL;
			mylist->size--;
			break;
		}

		pPrev = pCurrent;
		pCurrent = pCurrent->next;
	}

}

清空鏈表

void Clear_LinkList(LinkList list)
{
	if (NULL == list)
	{
		return;
	}

	struct LList *mylist = (struct LList *)list;

	//輔助指針變量
	struct LinkNode *pCurrent = mylist->header.next;

	while (pCurrent != NULL)
	{
		//先緩存下一個節點的地址
		struct LinkNode *pNext = pCurrent->next;
		//釋放當前結點內存
		free(pCurrent);

		pCurrent = pNext;

	}

	mylist->header.next = NULL;
	mylist->size = 0;

}

大小

//大小
int Size_LinkList(LinkList list)
{
	if (NULL == list)
	{
		return -1;
	}

	struct LList *mylist = (struct LList *)list;

	return mylist->size;
}

銷燬鏈表

//銷燬鏈表
void Destroy_LinkList(LinkList list)
{

	if (NULL == list)
	{
		return;
	}

	//清空鏈表
	Clear_LinkList(list);
	free(list);
	list = NULL;
}

單向鏈表測試

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

#include"LinkList.h"

struct Person
{
	char name[64];
	int age;
};

void myPrint(void *data)
{
	struct Person *person = (struct Person *)data;
	printf("Name:%s Age:%d\n",person->name,person->age);
}

int myComapre(void *d1,void *d2)
{
	struct Person *p1 = (struct Person *)d1;
	struct Person *p2 = (struct Person *)d2;

#if 0
	if (strcmp(p1->name,p2->name) == 0 && p1->age == p2->age)
	{
		return 1;
	}

	return 0;
#endif

	return strcmp(p1->name, p2->name) == 0 && p1->age == p2->age;

}

void test()
{
	//創建鏈表
	LinkList list = Init_LinkList();

	//創建數據
	struct Person p1 = { "aaa", 10 };
	struct Person p2 = { "bbb", 20 };
	struct Person p3 = { "ccc", 30 };
	struct Person p4 = { "ddd", 40 };
	struct Person p5 = { "eee", 50 };
	struct Person p6 = { "fff", 60 };
	struct Person p7 = { "ggg", 70 };


	//插入數據
	Insert_LinkList(list, 0, &p1);
	Insert_LinkList(list, 0, &p2);
	Insert_LinkList(list, 1, &p3); //2 3 1
	Insert_LinkList(list, 2, &p4); //2 3 4 1
	Insert_LinkList(list, 20, &p5); //2 3 4 1 5
	Insert_LinkList(list, 3, &p6); //2 3 4 6 1 5
	Insert_LinkList(list, 6, &p7); //2 3 4 6 1 5 7

	Foreach_LinkList(list, myPrint);

	printf("----------------------\n");
	printf("List Size:%d\n", Size_LinkList(list));
	RemoveByPos_LinkList(list, 3);
	printf("----------------------\n");
	Foreach_LinkList(list, myPrint);


	struct Person pDelPerson = { "ggg", 70 };
	RemoveByVal_LinkList(list, &pDelPerson, myComapre);
	printf("----------------------\n");
	Foreach_LinkList(list, myPrint);

	//清空鏈表
	Clear_LinkList(list);
	printf("----------------------\n");
	printf("List Size:%d\n", Size_LinkList(list));

	//銷燬鏈表
	Destroy_LinkList(list);


}

int main(){

	test();

	system("pause");
	return EXIT_SUCCESS;
}

運行

capacity:5
capacity:10
Name:ccc Age:30
Name:eee Age:50
Name:ddd Age:40
Name:bbb Age:20
Name:aaa Age:10
Name:fff Age:60
---------------
Name:ccc Age:30
Name:eee Age:50
Name:bbb Age:20
Name:aaa Age:10
Name:fff Age:60
---------------
Name:ccc Age:30
Name:eee Age:50
Name:bbb Age:20
Name:fff Age:60
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章