数据结构----单向带头结点链表(含企业级)

>>>>普通单向链表

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

//节点结构体
struct LinkNode
{
	void* data;  //数据域
	struct LinkNode* next;  //指针域
};

//链表结构体
struct Llist
{
	struct LinkNode pHeader;  //头节点
	int m_size;  //链表长度
};

//使用void*类型,防止用户直接操作结构体属性,在使用前记得类型转换
typedef void* LinkList;  

//链表初始化
LinkList initLinkList()
{
	//创建链表空间
	struct Llist* mylist = (struct Llist*)malloc(sizeof(struct Llist));
	if (mylist == NULL)
	{
		return NULL;
	}

	//初始化链表属性
	mylist->pHeader.data = NULL;
	mylist->pHeader.next = NULL;
	mylist->m_size = 0;

	return mylist;
}

//插入链表
void insertLinkList(LinkList list, int pos, void* data)
{
	//判断
	if (list == NULL || data == NULL)
	{
		return;
	}
	struct Llist* llist = (struct Llist*)list;  //将list还原成 struct LList数据类型
	if (pos < 0 || pos > llist->m_size)
	{
		pos = llist->m_size;  //无效位置 强制做尾插
	}

	//找到插入节点的前驱节点位置
	struct LinkNode* pCurrent = &llist->pHeader;
	for (int i = 0; i < pos; i++)
	{
		pCurrent = pCurrent->next;
	}

	//创建要插入的节点
	struct LinkNode* newNode = (struct LinkNode*)malloc(sizeof(struct LinkNode));
	newNode->data = data;
	newNode->next = NULL;

	//建立节点关系--插入
	newNode->next = pCurrent->next;
	pCurrent->next = newNode;

	//更新链表长度
	llist->m_size++;
}

//遍历
void foreachLinkList(LinkList list, void(*myPrint)(void*))
{
	if (list == NULL)
	{
		return;
	}

	struct Llist* llist = (struct Llist*)list;
	struct LinkNode* pCurrent = llist->pHeader.next;
	for (int i = 0; i < llist->m_size; i++)
	{
		myPrint(pCurrent->data);
		pCurrent = pCurrent->next;
	}
}

//按照位置删除节点
void removeByposLinkList(LinkList list, int pos)
{
	if (list == NULL)
	{
		return;
	}
	struct Llist* llist = (struct Llist*)list;
	if (pos < 0 || pos > llist->m_size-1)
	{
		return;
	}

	//找到待删除节点的前驱节点
	struct LinkNode* pCurrent = &llist->pHeader;
	for (int i = 0; i < pos; i++)
	{
		pCurrent = pCurrent->next; 
	}

	//记录待删除的节点
	struct LinkNode* pDelete = pCurrent->next;

	//重新建立节点关系
	pCurrent->next = pDelete->next;

	free(pDelete);
	pDelete = NULL;

	llist->m_size--;  //更新链表长度
}

//按照值删除
void removeByValueLinkList(LinkList list, void* data, int(*myCompare)(void*, void*))
{
	if (list == NULL || data == NULL)
	{
		return;
	}

	//创建两个辅助指针
	struct Llist* llist = (struct Llist*)list;
	struct LinkNode* pPrev = &llist->pHeader;
	struct LinkNode* pCur = pPrev->next;

	for (int i = 0; i < llist->m_size; i++)
	{
		if (myCompare(pCur->data, data))
		{
			//删除节点
			pPrev->next = pCur->next;
			free(pCur);
			pCur = NULL;

			llist->m_size--;
			break;
		}

		//辅助指针后移
		pPrev = pCur;
		pCur = pCur->next;
	}

}

//清除链表
void clearLinkList(LinkList list)
{
	if (list == NULL)
	{
		return;
	}

	struct Llist* llist = (struct Llist*)list;
	struct LinkNode* pCur = llist->pHeader.next;
	//循环释放所有节点
	for (int i = 0; i < llist->m_size; i++)
	{
		struct LinkNode* pTem = pCur->next;
		free(pCur);
		pCur = pTem;
		//最后一个节点指针指向NULL
	}

	//清除列表属性
	llist->pHeader.data = NULL;
	llist->m_size = 0;
}

//销毁链表
void destroyLinkList(LinkList list)
{
	if (list == NULL)
	{
		return;
	}

	clearLinkList(list);
	free(list);
	list = NULL;
}

//----------测试-----------
//自定义类型
struct Person
{
	char name[64];
	int age;
};

void myPrint(void* data)
{
	struct Person* p = (struct Person*) data;
	printf("姓名:%s ---- 年龄:%d\n", p->name, p->age);
}

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

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

int main()
{
	//struct Llsit* mylist = (struct Llsit*)initLinkList();  
	LinkList mylist = initLinkList();

	struct Person p1 = { "san", 11 };
	struct Person p2 = { "si", 22 };
	struct Person p3 = { "wu", 33 };
	struct Person p4 = { "w", 33 };

	insertLinkList(mylist, 0, &p1);
	insertLinkList(mylist, 0, &p2);
	insertLinkList(mylist, -1, &p3);
	insertLinkList(mylist, 3, &p4);

	foreachLinkList(mylist, myPrint);

	printf("------------\n");
	/*removeByposLinkList(mylist, 1);
	foreachLinkList(mylist, myPrint);*/

	struct Person p = { "wu", 33 };
	removeByValueLinkList(mylist, &p, myCompare);
	foreachLinkList(mylist, myPrint);

	return 0;
}

>>>>企业级单向链表

 

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

struct LinkNode
{
	struct LinkNode* next;  //只有指针域
};

struct Llist
{
	struct LinkNode pHeader;
	int m_size;
};

typedef void* LinkList;

//初始化
LinkList initLinkList()
{
	struct Llist* mylist = (struct Llist*)malloc(sizeof(struct Llist));
	if (mylist == NULL)
	{
		return NULL;
	}
	mylist->m_size = 0;
	mylist->pHeader.next = NULL;
	return mylist;
}

//插入
void insertLinkList(LinkList list, int pos, void* data)
{
	if (list == NULL || data == NULL)
	{
		return;
	}
	struct Llist* llist = (struct Llist*)list;
	if (pos < 0 || pos > llist->m_size-1)
	{
		pos = llist->m_size;
	}

	struct LinkNode* pCur = &llist->pHeader;
	for (int i = 0; i < pos; i++)
	{
		pCur = pCur->next;
	}

	//用户数据前4个字节 由我们来使用
	struct LinkNode* newNode = (struct LinkNode*)data;

	newNode->next = pCur->next;
	pCur->next = newNode;

	llist->m_size++;
}

//遍历
void foreachLinkList(LinkList list, void(*myPrint)(void*))
{
	if (list == NULL)
	{
		return;
	}

	struct Llist* llist = (struct Llist*)list;
	struct LinkNode* pCur = &llist->pHeader;
	for (int i = 0; i < llist->m_size; i++)
	{
		myPrint(pCur->next);
		pCur = pCur->next;
	}
}

//删除
void removeByposLinkList(LinkList list, int pos)
{
	if (list == NULL)
	{
		return;
	}

	struct Llist* llist = (struct Llist*)list;
	struct LinkNode* pCur = &llist->pHeader;
	for (int i = 0; i < pos; i++)
	{
		pCur = pCur->next;
	}

	struct LinkNode* pDel = pCur->next;

	pCur->next = pDel->next;
	//free(pDel);  //数据是用户管理开辟的,用户管理释放
	//pDel = NULL;

	llist->m_size--;
}

//销毁
void destroyLinkList(LinkList list)
{
	if (list == NULL)
	{
		return;
	}

	free(list);
	list = NULL;
}

//-------------测试------------
struct Person
{
	void* node;  //预留4个字节空间
	char name[20];
	int age;
};

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


int main()
{
	LinkList mylist = initLinkList();

	struct Person p1 = {NULL, "san", 11 };
	struct Person p2 = {NULL, "si", 22 };
	struct Person p3 = {NULL, "wu", 33 };
	struct Person p4 = {NULL, "w", 33 };

	insertLinkList(mylist, 0, &p1);
	insertLinkList(mylist, 0, &p2);
	insertLinkList(mylist, 4, &p3);
	insertLinkList(mylist, 0, &p4);

	foreachLinkList(mylist, myPrint);

	printf("--------------------\n");
	removeByposLinkList(mylist, 1);
	foreachLinkList(mylist, myPrint);

	return 0;
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值