is_exist_linklist(
判断给定的数据是否存在于链表中)完整代码如下 :
int is_exist_linklist(list_node_t *phead, datatype tmpdata)
{
list_node_t *ptmpnode = NULL;
if (NULL == phead)
{
return -1;
}
ptmpnode = phead->pnext;
while (ptmpnode != NULL)
{
if (ptmpnode->data == tmpdata)
{
return 1;
}
ptmpnode = ptmpnode->pnext;
}
return 0;
}
int is_exist_linklist(list_node_t *phead, datatype tmpdata)
函数 is_exist_linklist
接受两个参数:
phead
:指向链表头节点的指针。
tmpdata
:要查找的数据。
函数返回值为 int
类型,用于表示查找结果。
list_node_t *ptmpnode = NULL;
声明一个指向链表节点的指针 ptmpnode
,并初始化为 NULL
,用于遍历链表。
if (NULL == phead)
{
return -1;
}
如果链表头指针 phead
为 NULL
,表示链表为空,函数返回 -1
表示错误或无效情况。
ptmpnode = phead->pnext;
将 ptmpnode
指向链表的第一个实际节点(跳过头节点)。
while (ptmpnode!= NULL)
{
if (ptmpnode->data == tmpdata)
{
return 1;
}
ptmpnode = ptmpnode->pnext;
}
使用 while
循环遍历链表,直到 ptmpnode
为 NULL
(到达链表末尾)。在每次循环中:
检查当前节点的数据 ptmpnode->data
是否等于要查找的数据 tmpdata
。
如果相等,返回 1
表示找到了目标数据。
如果不相等,将 ptmpnode
指向下一个节点。
return 0;
如果循环结束后仍未找到目标数据,函数返回 0
表示数据不存在于链表中。
replace_linklist(
链表中查找并替换指定的数据)
完整代码如下:
int replace_linklist(list_node_t *phead, datatype olddata, datatype newdata)
{
list_node_t *ptmpnode = NULL;
if (NULL == phead)
{
return -1;
}
ptmpnode = phead->pnext;
while (ptmpnode != NULL)
{
if (ptmpnode->data == olddata)
{
ptmpnode->data = newdata;
}
ptmpnode = ptmpnode->pnext;
}
return 0;
}
int replace_linklist(list_node_t *phead, datatype olddata, datatype newdata)
replace_linklist
是函数名,返回值类型为int
。
phead
是指向链表头节点的指针,类型为list_node_t *
。
olddata
和newdata
是要查找和替换的数据,类型为datatype。
list_node_t *ptmpnode = NULL;
声明一个指向链表节点的指针ptmpnode
,并初始化为NULL
,用于遍历链表。
if (NULL == phead)
{
return -1;
}
如果链表头指针phead
为NULL
,表示链表为空,函数返回 - 1
ptmpnode = phead->pnext;
while (ptmpnode != NULL)
{
if (ptmpnode->data == olddata)
{
ptmpnode->data = newdata;
}
ptmpnode = ptmpnode->pnext;
}
ptmpnode = phead->pnext;
:将ptmpnode
指向链表的第一个实际节点(头节点之后的节点)。
while (ptmpnode != NULL)
:当ptmpnode
不为NULL
时,继续遍历链表。
if (ptmpnode->data == olddata)
:检查当前节点的数据是否等于要查找的olddata
。
如果相等,ptmpnode->data = newdata;
将当前节点的数据替换为newdata
。
ptmpnode = ptmpnode->pnext;
:将ptmpnode
移动到下一个节点。
return 0;
当链表遍历完成后,函数返回 0,表示操作成功。
总体来说,这个函数的作用是在给定的链表中查找所有等于olddata
的数据,并将其替换为newdata
,如果链表为空则返回 - 1,否则返回 0 表示操作成功。
完整代码如下:
int append_linklist(list_node_t *phead, datatype tmpdata)
{
list_node_t *pnewnode = NULL;
list_node_t *plastnode = NULL;
//参数合法性检测
if (NULL == phead)
{
return -1;
}
//申请新的节点
pnewnode = malloc(sizeof(list_node_t));
if (NULL == pnewnode)
{
return -1;
}
//对新节点内容初始化
pnewnode->data = tmpdata;
pnewnode->pnext = NULL;
//找到最后一个节点
plastnode = phead;
while (plastnode->pnext != NULL)
{
plastnode = plastnode->pnext;
}
//插入元素
plastnode->pnext = pnewnode;
return 0;
}
int append_linklist(list_node_t *phead, datatype tmpdata);
append_linklist
是函数名。
list_node_t *phead
是指向链表头节点的指针,函数通过这个指针来操作链表。
datatype tmpdata
是要插入到链表中的数据,datatype
在这里是一个自定义的数据类型。
list_node_t *pnewnode = NULL;
list_node_t *plastnode = NULL;
pnewnode
用于指向新创建的节点。
plastnode
用于在链表中找到最后一个节点。
if (NULL == phead)
{
return -1;
}
检查传入的链表头指针是否为NULL
,如果是,则说明链表不存在,函数返回 - 1 表示操作失败。
pnewnode = malloc(sizeof(list_node_t));
if (NULL == pnewnode)
{
return -1;
}
使用malloc
函数动态分配一个list_node_t
类型的内存空间,用于存储新节点。
如果malloc
分配内存失败(返回NULL
),函数返回 - 1 表示操作失败。
pnewnode->data = tmpdata;
pnewnode->pnext = NULL;
将传入的tmpdata
赋值给新节点的数据域data
。
将新节点的指针域pnext
设置为NULL
,表示它是链表的最后一个节点。
plastnode = phead;
while (plastnode->pnext != NULL)
{
plastnode = plastnode->pnext;
}
从链表头节点开始,通过遍历链表找到最后一个节点,将plastnode
指向该节点。
plastnode->pnext = pnewnode;
将最后一个节点的pnext
指针指向新创建的节点,从而将新节点添加到链表末尾。
return 0;
如果整个操作成功,函数返回 0 表示操作完成。
delete_linklist(
从链表中删除指定数据节点)
完整代码如下:
int delete_linklist(list_node_t *phead, datatype tmpdata)
{
list_node_t *pprenode = NULL;
list_node_t *ptmpnode = NULL;
//参数合法性检测
if (NULL == phead)
{
return -1;
}
ptmpnode = phead->pnext;
pprenode = phead;
while (ptmpnode != NULL)
{
if (ptmpnode->data == tmpdata)
{
pprenode->pnext = ptmpnode->pnext;
free(ptmpnode);
ptmpnode = pprenode->pnext;
}
else
{
ptmpnode = ptmpnode->pnext;
pprenode = pprenode->pnext;
}
}
return 0;
}
int delete_linklist(list_node_t *pphead, datatype tmpdata)
函数名为delete_linklist
,返回值类型为int
。它接受两个参数:
pphead
:指向链表头节点指针的指针,用于在函数中修改链表头指针(如果删除的是头节点)。
tmpdata
:要删除的节点中的数据。
list_node_t *pprenode = NULL;
list_node_t *ptmpnode = NULL;
声明了两个指向链表节点的指针:
pprenode
:用于指向当前节点的前一个节点。
ptmpnode
:用于遍历链表的当前节点。
if (NULL == phead)
{
return -1;
}
检查传入的链表头指针是否为NULL
,如果是,说明链表不存在,函数返回 - 1 表示操作失败。
ptmpnode = phead->next;
pprenode = phead;
将ptmpnode
指向链表的第一个有效节点(头节点后面的节点),pprenode
指向头节点。
while (ptmpnode != NULL)
{
if (ptmpnode->data == tmpdata)
{
pprenode->next = ptmpnode->next;
free(ptmpnode);
ptmpnode = pprenode->next;
}
else
{
ptmpnode = ptmpnode->next;
pprenode = pprenode->next;
}
}
使用while
循环遍历链表,直到ptmpnode
为NULL
(即到达链表末尾)。在每次循环中:
如果当前节点ptmpnode
的数据等于要删除的数据tmpdata
,则将当前节点从链表中删除,通过修改前一个节点pprenode
的next
指针跳过当前节点,并使用free
函数释放当前节点的内存。然后将ptmpnode
指向下一个节点。
如果当前节点的数据不等于要删除的数据,则将ptmpnode
和pprenode
都指向下一个节点,继续遍历链表。
return 0;
函数返回 0 表示操作成功。
完整代码如下:
int destroy_linklist(list_node_t **pphead)
{
list_node_t *pprenode = NULL;
list_node_t *ptmpnode = NULL;
//参数合法性检测
if (NULL == pphead || NULL == *pphead)
{
return -1;
}
pprenode = *pphead;
ptmpnode = *pphead;
while (ptmpnode != NULL)
{
ptmpnode = ptmpnode->pnext;
free(pprenode);
pprenode = ptmpnode;
}
*pphead = NULL;
return 0;
}
int destroy_linklist(list_node_t **pphead)
函数名为destroy_linklist
,返回值类型为int
。
函数接受一个指向list_node_t
类型指针的指针pphead
,这意味着它可以修改传入的链表头指针。
list_node_t *pprenode = NULL;
list_node_t *ptmpnode = NULL;
声明了两个指向list_node_t
类型的指针pprenode
和ptmpnode
,并初始化为NULL
。它们将用于遍历链表和释放节点内存。
if (NULL == phead || NULL == *pphead)
{
return -1;
}
检查传入的指针pphead
是否为NULL
,以及pphead
所指向的链表头指针是否为NULL
。如果其中任何一个为NULL
,说明链表不存在或传入参数无效,函数返回-1
表示错误。
pprenode = *pphead;
ptmpnode = *pphead;
pprenode
和ptmpnode
都初始化为链表的头节点。while (ptmpnode != NULL)
{
ptmpnode = ptmpnode->pnext;
free(pprenode);
pprenode = ptmpnode;
}
使用while
循环遍历链表。
ptmpnode = ptmpnode->pnext;
:将ptmpnode
指向下一个节点,以便在释放当前节点后仍能访问后续节点。
free(pprenode);
:释放当前节点的内存。
pprenode = ptmpnode;
:将pprenode
更新为ptmpnode
,以便继续遍历和释放后续节点。
NULL
*pphead = NULL;
将链表的头指针设置为NULL
,表示链表已被销毁
5.7返回值
return 0;
函数执行成功,返回0
这个函数通过遍历链表并释放每个节点的内存,最终将链表头指针设置为NULL
,完成链表的销毁操作。
find_mid_node_linklist(
在链表中找到中间节点)
完整代码如下:
list_node_t *find_mid_node_linklist(list_node_t *phead)
{
list_node_t *pfast = NULL;
list_node_t *pslow = NULL;
pslow = phead->pnext;
pfast = phead->pnext;
while (1)
{
pfast = pfast->pnext;
if (NULL == pfast)
{
break;
}
pfast = pfast->pnext;
if (NULL == pfast)
{
break;
}
pslow = pslow->pnext;
}
return pslow;
}
list_node_t *find_mid_node_linklist(list_node_t *phead)
函数名为 find_mid_node_linklist
,它接受一个指向 list_node_t
类型的指针 phead
(链表头指针)作为参数,返回值是一个指向 list_node_t
类型的指针,即链表的中间节点指针。
list_node_t *pfast = NULL;
list_node_t *pslow = NULL;
声明了两个指向 list_node_t
类型的指针 pfast
和 pslow
,并初始化为 NULL
。它们将用于遍历链表,其中 pfast
每次移动两个节点,pslow
每次移动一个节点。
pslow = phead->pnext;
pfast = phead->pnext;
将 pslow
和 pfast
都初始化为链表头节点的下一个节点。这意味着链表至少需要有一个节点(头节点之后的节点)才能进行后续操作。
while (1)
{
pfast = pfast->pnext;
if (NULL == pfast)
{
break;
}
pfast = pfast->pnext;
if (NULL == pfast)
{
break;
}
pslow = pslow->pnext;
}
这是一个无限循环,用于遍历链表。在循环中:
pfast
先移动一个节点。
检查 pfast
是否为 NULL
,如果是则说明链表节点数为奇数且 pfast
到达链表末尾,退出循环。
pfast
再移动一个节点。
再次检查 pfast
是否为 NULL
,如果是则说明链表节点数为偶数且 pfast
到达链表末尾,退出循环。
如果 pfast
两次移动后都不为 NULL
,则 pslow
移动一个节点。
return pslow;
循环结束后,pslow
指向的就是链表的中间节点,将其返回。
该函数使用快慢指针(pfast
和 pslow
)的方法,快指针每次移动两个节点,慢指针每次移动一个节点,当快指针到达链表末尾时,慢指针正好指向链表的中间节点,从而实现了找到链表中间节点的功能。
find_last_kth_node(
在链表中找到倒数第 k
个节点)
完整代码如下:
list_node_t *find_last_kth_node(list_node_t *phead, int k)
{
list_node_t *pfast = NULL;
list_node_t *pslow = NULL;
int i = 0;
pfast = phead->pnext;
pslow = phead->pnext;
for (i = 0; i < k; i++)
{
pfast = pfast->pnext;
if (NULL == pfast)
{
return NULL;
}
}
while (pfast != NULL)
{
pfast = pfast->pnext;
pslow = pslow->pnext;
}
return pslow;
}
list_node_t *find_last_kth_node(list_node_t *phead, int k)
函数 find_last_kth_node
接受两个参数,第一个参数 phead
是链表的头指针,类型为 list_node_t *
;第二个参数 k
是一个整数,表示要找的倒数第 k
个节点。函数的返回值是一个指向 list_node_t
类型的指针,即找到的倒数第 k
个节点的指针,如果找不到则返回 NULL
list_node_t *pfast = NULL;
list_node_t *pslow = NULL;
int i = 0;
声明了两个指向 list_node_t
类型的指针 pfast
和 pslow
,并初始化为 NULL
,还声明了一个整数变量 i
并初始化为 0
。
pfast = phead->pnext;
pslow = phead->pnext;
将 pfast
和 pslow
都初始化为链表头节点的下一个节点(即第一个实际数据节点)。
pfast
指针for (i = 0; i < k; i++)
{
pfast = pfast->pnext;
if (NULL == pfast)
{
return NULL;
}
}
使用 for
循环将 pfast
指针向前移动 k
步。如果在移动过程中 pfast
指向了 NULL
,说明链表长度小于 k
,无法找到倒数第 k
个节点,直接返回 NULL
。
pfast
和 pslow
指针while (pfast != NULL)
{
pfast = pfast->pnext;
pslow = pslow->pnext;
}
当 pfast
指针没有到达链表末尾(即 pfast != NULL
)时,同时将 pfast
和 pslow
指针向前移动一步。当 pfast
到达链表末尾时,pslow
就指向了链表的倒数第 k
个节点。
return pslow;
最后返回 pslow
指针,它指向的就是链表中倒数第 k
个节点。
这段代码通过复制数据和调整指针的方式,实现了在链表中删除指定节点的下一个节点的功能。完整代码如下 :
int delete_mid_node(list_node_t *ptmpnode)
{
list_node_t *pnextnode = NULL;
pnextnode = ptmpnode->pnext;
ptmpnode->data = pnextnode->data;
ptmpnode->pnext = pnextnode->pnext;
free(pnextnode);
return 0;
}
int delete_mid_node(list_node_t *ptmpnode)
int
:表示函数的返回值类型为整数。这里返回0
,通常用于表示操作成功。
delete_mid_node
:函数名。
list_node_t *ptmpnode
:函数的参数,是一个指向链表节点的指针。这个指针指向的是链表中需要操作的当前节点。
list_node_t *pnextnode = NULL;
声明了一个指向链表节点的指针pnextnode
,并初始化为NULL
。这个指针将用于指向当前节点ptmpnode
的下一个节点。
pnextnode = ptmpnode->pnext;
将ptmpnode
的下一个节点的地址赋值给pnextnode
。
ptmpnode->data = pnextnode->data;
将下一个节点pnextnode
的数据复制到当前节点ptmpnode
。
ptmpnode->pnext = pnextnode->pnext;
将当前节点ptmpnode
的pnext
指针指向pnextnode
的下一个节点,跳过了pnextnode
,从逻辑上删除了pnextnode
。
free(pnextnode);
使用free
函数释放pnextnode
所指向的内存,防止内存泄漏。
return 0;
0
,表示操作成功完成。完整代码如下:
int invert_linklist(list_node_t *phead)
{
list_node_t *ptmpnode = NULL;
list_node_t *pinsertnode = NULL;
//参数合法性检测
if (NULL == phead)
{
return -1;
}
//让头结点与后序节点断开
ptmpnode = phead->pnext;
pinsertnode = ptmpnode;
phead->pnext = NULL;
while (ptmpnode != NULL)
{
ptmpnode = ptmpnode->pnext;
pinsertnode->pnext = phead->pnext;
phead->pnext = pinsertnode;
pinsertnode = ptmpnode;
}
return 0;
}
int invert_linklist(list_node_t *phead)
该函数接受一个指向链表头节点的指针 phead
作为参数,返回值为 int
类型。
list_node_t *ptmpnode = NULL;
list_node_t *pinsertnode = NULL;
声明了两个指向 list_node_t
类型的指针变量 ptmpnode
和 pinsertnode
,并初始化为 NULL
。这两个指针将用于链表倒置过程中的临时操作。
if (NULL == phead)
{
return -1;
}
检查传入的链表头指针 phead
是否为 NULL
。如果是,则说明链表为空,函数返回 -1
表示操作失败。
ptmpnode = phead->pnext;
pinsertnode = ptmpnode;
phead->pnext = NULL;
将 ptmpnode
指向头节点的下一个节点,pinsertnode
也指向该节点,然后将头节点的 pnext
指针设为 NULL
,使头节点成为新链表的尾节点。
假设我们有一个链表,头指针为 phead
,链表结构为 phead -> node1 -> node2 -> node3 ->...
。
ptmpnode = phead->pnext;
:这一步将 ptmpnode
指向头节点 phead
的下一个节点,也就是 node1
。此时 ptmpnode
就指向了原链表除头节点外的部分。
pinsertnode = ptmpnode;
:让 pinsertnode
也指向 node1
,后续会用它来处理节点插入操作。
phead->pnext = NULL;
:将头节点 phead
的 pnext
指针设置为 NULL
,这就使得头节点与后面的节点断开了连接,此时头节点变成了一个独立的节点,并且将成为反转后链表的尾节点。链表状态变为 phead
(独立,尾节点) 和 node1 -> node2 -> node3 ->...
两部分。
while (ptmpnode != NULL)
{
ptmpnode = ptmpnode->pnext;
pinsertnode->pnext = phead->pnext;
phead->pnext = pinsertnode;
pinsertnode = ptmpnode;
}
循环遍历原链表的剩余节点,将每个节点插入到头节点之后,实现链表的反转。具体步骤如下:
ptmpnode = ptmpnode->pnext;
:将 ptmpnode
指向下一个节点,以便后续处理。
pinsertnode->pnext = phead->pnext;
:将当前要插入的节点的 pnext
指针指向原头节点的下一个节点。
phead->pnext = pinsertnode;
:将原头节点的 pnext
指针指向当前要插入的节点。
pinsertnode = ptmpnode;
:更新 pinsertnode
为下一个要处理的节点。
假设当前链表状态是 phead
(独立,尾节点) 和 node1 -> node2 -> node3 ->...
。
第一次循环:
ptmpnode = ptmpnode->pnext;
:ptmpnode
原本指向 node1
,执行后它指向 node2
。此时 pinsertnode
仍指向 node1
。
pinsertnode->pnext = phead->pnext;
:因为 phead->pnext
是 NULL
(前面断开头节点时设置的),所以 node1
的 pnext
被设置为 NULL
。
phead->pnext = pinsertnode;
:将 phead
的 pnext
指针指向 node1
,此时链表变为 phead -> node1
(反转后的一小段),剩下未处理的是 node2 -> node3 ->...
。
pinsertnode = ptmpnode;
:让 pinsertnode
指向 node2
,为下一次循环做准备。
第二次循环及后续:
重复上述过程,每次循环都将 pinsertnode
指向的节点(当前未处理链表的第一个节点)插入到 phead
后面,不断改变指针指向关系,逐步将剩余未处理的链表节点反转到 phead
之后。随着循环的进行,phead
后面的节点越来越多,最终原链表所有节点都被反转到 phead
之后,完成整个链表的反转。
return 0;
如果链表反转成功,函数返回 0
完整代码如下:
int bubble_sort_linklist(list_node_t *phead)
{
list_node_t *ptmpnode1 = NULL;
list_node_t *ptmpnode2 = NULL;
list_node_t *pend = NULL;
datatype tmpdata;
if (NULL == phead)
{
return -1;
}
if (NULL == phead->pnext || NULL == phead->pnext->pnext)
{
return 0;
}
while (1)
{
ptmpnode1 = phead->pnext;
ptmpnode2 = phead->pnext->pnext;
if (pend == ptmpnode2)
{
break;
}
while (ptmpnode2 != pend)
{
if (ptmpnode1->data > ptmpnode2->data)
{
tmpdata = ptmpnode1->data;
ptmpnode1->data = ptmpnode2->data;
ptmpnode2->data = tmpdata;
}
ptmpnode1 = ptmpnode1->pnext;
ptmpnode2 = ptmpnode2->pnext;
}
pend = ptmpnode1;
}
return 0;
}
int bubble_sort_linklist(list_node_t *phead)
这是函数bubble_sort_linklist
的声明,它接受一个指向链表头节点的指针phead
,并返回一个整数。函数的返回值在不同情况下有不同的含义:
如果链表为空(phead
为NULL
),返回-1
。
如果链表只有一个节点或没有节点,返回0
。
如果排序成功,返回0
。
list_node_t *ptmpnode1 = NULL;
list_node_t *ptmpnode2 = NULL;
list_node_t *pend = NULL;
datatype tmpdata;
ptmpnode1
和ptmpnode2
是用于遍历链表的临时指针。
pend
是一个指针,用于标记已经排序好的部分的末尾。
tmpdata
是一个临时变量,用于交换节点的数据。
if (NULL == phead)
{
return -1;
}
如果链表头指针phead
为NULL
,说明链表为空,函数返回-1。
if (NULL == phead->pnext || NULL == phead->pnext->pnext)
{
return 0;
}
如果链表只有一个节点或没有节点,不需要排序,函数返回0。
while (1)
{
ptmpnode1 = phead->pnext;
ptmpnode2 = phead->pnext->pnext;
if (pend == ptmpnode2)
{
break;
}
while (ptmpnode2 != pend)
{
if (ptmpnode1->data > ptmpnode2->data)
{
tmpdata = ptmpnode1->data;
ptmpnode1->data = ptmpnode2->data;
ptmpnode2->data = tmpdata;
}
ptmpnode1 = ptmpnode1->pnext;
ptmpnode2 = ptmpnode2->pnext;
}
pend = ptmpnode1;
}
外层while (1)
是一个无限循环,直到排序完成。
ptmpnode1
和ptmpnode2
分别指向链表的前两个节点。
如果ptmpnode2
等于pend
,说明已经到达已排序部分的末尾,退出外层循环。
内层while
循环用于比较相邻节点,并在需要时交换它们的数据。
每次内层循环结束后,pend
指针移动到当前已排序部分的末尾。
循环初始化:while(1)
是一个无限循环,只有在满足特定条件时才会退出。每次循环开始时,ptmpnode1
指向链表头节点的下一个节点(即第一个有效节点),ptmpnode2
指向 ptmpnode1
的下一个节点。
终止条件判断:if (pend == ptmpnode2)
用于检查是否已经完成了所有需要的排序轮次。pend
指针标记了已经排序好的部分的末尾,当 ptmpnode2
到达 pend
的位置时,说明当前轮次已经检查完了未排序部分的所有元素,此时退出外层循环。
内层 whi
le
循环:
while
循环用于在未排序的链表部分中进行一次完整的冒泡操作,即比较相邻节点并交换顺序不正确的节点。if (ptmpnode1->data > ptmpnode2->data)
检查相邻的两个节点 ptmpnode1
和 ptmpnode2
的数据。如果 ptmpnode1
的数据大于 ptmpnode2
的数据,就通过临时变量 tmpdata
交换这两个节点的数据。ptmpnode1
和 ptmpnode2
都向后移动一个节点,以便继续比较下一对相邻节点,直到 ptmpnode2
到达 pend
所标记的位置,即未排序部分的末尾。pend
指针更新:
pend = ptmpnode1;
将 pend
指针更新为当前轮次中最后一个进行比较的节点 ptmpnode1
。这意味着 pend
之后的节点已经是有序的,在下一轮排序中不需要再检查这些节点。通过外层循环不断重复上述过程,每一轮都会将未排序部分中最大(或最小)的元素移动到未排序部分的末尾,直到整个链表都被排序完成。
return 0;
排序成功后,函数返回0。
select_sort_linklist)
这段代码实现了对链表的选择排序,通过两层循环找到最小值节点并与当前节点交换数据,从而逐步将链表排序。完整代码如下:
int select_sort_linklist(list_node_t *phead)
{
list_node_t *ptmpnode1 = NULL;
list_node_t *ptmpnode2 = NULL;
list_node_t *pminnode = NULL;
datatype tmpdata;
if (NULL == phead)
{
return -1;
}
if (NULL == phead->pnext || NULL == phead->pnext->pnext)
{
return 0;
}
ptmpnode1 = phead->pnext;
while (ptmpnode1->pnext != NULL)
{
pminnode = ptmpnode1;
ptmpnode2 = ptmpnode1->pnext;
while (ptmpnode2 != NULL)
{
if (ptmpnode2->data < pminnode->data)
{
pminnode = ptmpnode2;
}
ptmpnode2 = ptmpnode2->pnext;
}
if (pminnode != ptmpnode1)
{
tmpdata = pminnode->data;
pminnode->data = ptmpnode1->data;
ptmpnode1->data = tmpdata;
}
ptmpnode1 = ptmpnode1->pnext;
}
return 0;
}
int select_sort_linklist(list_node_t *phead)
函数 select_sort_linklist
接受一个指向链表头节点的指针 phead
作为参数,返回值为 int
类型。函数的目的是对传入的链表进行选择排序。
list_node_t *ptmpnode1 = NULL;
list_node_t *ptmpnode2 = NULL;
list_node_t *pminnode = NULL;
datatype tmpdata;
声明了三个指向链表节点的指针 ptmpnode1
、ptmpnode2
和 pminnode
,以及一个 datatype
类型的变量 tmpdata
。ptmpnode1
用于遍历链表,ptmpnode2
用于在每次 ptmpnode1
移动时从 ptmpnode1
的下一个节点开始遍历寻找最小值节点,pminnode
用于记录当前找到的最小值节点,tmpdata
用于临时存储数据以便交换。
if (NULL == phead)
{
return -1;
}
if (NULL == phead->pnext || NULL == phead->pnext->pnext)
{
return 0;
}
第一个 if
语句检查链表头指针是否为空,如果为空,说明链表不存在,返回 -1
表示错误。
第二个 if
语句检查链表是否只有一个节点或者没有节点(即头节点的下一个节点为空,或者头节点的下一个节点的下一个节点为空),如果是这种情况,链表已经是有序的,返回 0
表示排序成功(这里排序成功但实际上无需排序)。
ptmpnode1 = phead->pnext;
while (ptmpnode1->pnext!= NULL)
{
pminnode = ptmpnode1;
ptmpnode2 = ptmpnode1->pnext;
while (ptmpnode2!= NULL)
{
if (ptmpnode2->data < pminnode->data)
{
pminnode = ptmpnode2;
}
ptmpnode2 = ptmpnode2->pnext;
}
if (pminnode!= ptmpnode1)
{
tmpdata = pminnode->data;
pminnode->data = ptmpnode1->data;
ptmpnode1->data = tmpdata;
}
ptmpnode1 = ptmpnode1->pnext;
}
ptmpnode1 = phead->pnext;
:将 ptmpnode1
指向链表的第一个实际节点(跳过头节点)。while
循环:当 ptmpnode1
的下一个节点不为空时,继续循环。这是为了确保 ptmpnode1
可以遍历到链表的倒数第二个节点。pminnode
初始化为 ptmpnode1
,即假设当前节点是最小值节点。while
循环:从 ptmpnode1
的下一个节点开始遍历链表,寻找最小值节点。如果找到比当前 pminnode
更小的节点,更新 pminnode
。pminnode
不是最初假设的 ptmpnode1
,则交换它们的数据。
return 0;
函数最后返回 0
,表示链表排序成功。