单向链表的初始化、插入、遍历的实现【加强版】

单向链表的初始化、插入、遍历的实现【加强版】,第1张

单向链表的初始化、插入、遍历的实现【加强版】

定义两个结构体:
1.节点结构体

struct LinkNode{
	void *data;
	struct LinkNode *next;
};

节点的数据域类型为void *,是一个泛型指针,可维护任意类型的数据

2.链表结构体

struct LList{
	struct LinkNode pHeader;//非指针类型,节点
	int m_size;
}

链表的结构体有两个成员:pHeader为头节点,用于维护链表;m_size记录链表的长度,不计入头节点

1.单向链表的初始化

为了避免用户访问到结构体LList的成员,造成不必要的隐患。


这里选择用泛型指针类型void *作为单向链表初始化函数的返回值类型。


为了提高代码可读性,选择用typedefvoid *进行重定义,如下:

typedef void * LinkList;

函数设计为LinkList initLinkList();该函数内部主要是创建链表,然后对struct LList结构体内部的成员进行初始化
其函数实现如下:

LinkList initLinkList()
{
	//创建链表
	struct LList *myList = malloc(sizeof(struct LList));
	if(myList == NULL)
		return;.//返回一个空
	//链表成员初始化
	myList->pHeader.next = NULL; 
	myList->pHeader.data = NULL;
	myList->m_size = 0;
	
	return myList;
}
2.单向链表的节点插入
  • 函数设计为void insertLinkList(LinkList list,int pos,void *data);
  • 参数1LinkList lsit,类型为void *,函数内部应将其还原成struct LList类型,使得节点和链表长度成员可以正常访问
  • 如果输入的pos是无效位置,则强制进行尾插
  • 插入新的节点前,应先找到插入位置的前驱节点,可创建一个辅助节点指针pCurrentNode来实现
  • 节点插入到链表成功后,需及时更新链表的长度m_size
void insertLinkList(LinkList list,int pos,void *data)
{
	if(list == NULL || data == NULL)
		return;
	
	struct LList *myList = list;//将链表还原成LList,使头节点和链表长度成员可以正常访问
	
	if(pos < 0 || pos > myList->m_size)//无效位置,强制尾插
		pos = myList->m_size;

	struct LinkNode *pCurrentNode = &myList->pHeader;
	for(int i = 0; i < pos; i++)
	{
		pCurrentNode = pCurrentNode->next;
	}
	
	//创建一个新的节点,并对节点成员进行初始化
	struct LinkNode *pNewNode = malloc(sizeof(struct LinkNode));
	pNewNode->data = data;
	pNewNode->next = NULL;

	//建立关系
	pNewNode->next = pCurrentNode->next;
	pCurrent->next = pNewNode;
	
	//更新链表长度
	myList->m_size++;
}	
3.单向链表的节点遍历打印
  • 函数设计为void foreachLinkList(LinkList list,void(*myForeach)(void*));
  • 参数1LinkList lsit,类型为void *,函数内部应将其还原成struct LList类型,使得节点和链表长度成员可以正常访问
  • 参数2void(*myPrint)(void*),定义了一个函数指针,用于接收用户定义的回调函数

函数实现最终如下

void foreachLinkList(LinkList list,void(*myPrint)(void*))
{
	if(lsit == NULL)
		return;
	struct LList *myList = list;
	
	struct LinkNode *pCurrentNode = &myList->pHeader;
	for(int i = 0; i < myList->m_size; i++)
	{
		pCurrentNode = pCurrentNode->next;
		myForeach(pCurrentNode->data);
	}
}

回调函数设计

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

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

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/578146.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-11
下一篇 2022-04-11

发表评论

登录后才能评论

评论列表(0条)

保存