C语言数据结构-速率较高的链表排序算法-插入排序法
一,链表的排序算法简介
链表的排序在实际应用中被广泛使用,不管是你在按时间顺序看照片还是将你的Excel表排序,都属于链表排序。
关于排序问题是数组的必考题,相对于数组的排序算法在链表中视乎也几乎能够使用。所以如果你对数组的排序都不是很理解建议先转战”数值排序“。最简单的冒泡排序和选择排序在这里视乎并没有太大研究的必要,都是体力活。
通过多方面考虑决定选择使用插入法完成对链表的排序函数,主要在于其复杂度不算太高,并且效率相对于前面两种也较好。通过该算法的学习对于理解希尔排序(效率很高)也会有一定帮助。
下面是插入排序的简单图解
二,程序算法设计
相对于数组链表有自需要多操心的地方。本算法设计思路主要通过设定pmin,pmax两个值,有效的简化了算法设计难度。
-
当由大到小排时,pmin始终作为已操作的节点里data值最小的数,也就是始终为已操作数的最后一个节点。
-
当由小到大排时,pmax始终作为已操作的节点里data值最大的数,也就是始终为已操作数的最后一个节点。
设计p1指针用于遍历链表已被操作过的节点,从而找到插入节点的位置。定义p1Prev指针用于链接要插入的节点。
详细内容我们看代码。
- 下面是主要声明参数,包括节点的声明和头节点。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//链表节点
struct node
{
int data;
struct node *pNext;
};
int main(void)
{
struct node *pHeader = NULL; //头指针
pHeader = create_node(0); //创建头节点,存取节点数
- 排序函数,*pH传的是头节点,oeder为选择排序规则。
//order 1大到小,0小到大
void linked_list_sort(struct node *pH,int order)
{
struct node *p = pH->pNext;
struct node *pBack = NULL;
struct node *pmin = p; //指向第一个节点
struct node *pmax = p; //(已插入数的最大值)
struct node *p1 = NULL;
struct node *p1Prev = NULL; //p1的前一个节点
//没有有效节点或一个则不操作
if ((NULL ==p) || (NULL == p->pNext))
return;
p = p->pNext; //p指向第二个节点(从第二个开始插入)
//由大到小排序
if(order == 1)
{
while(NULL != p)
{
pBack = p->pNext; //保存下一个节点地址
p1=pH->pNext; //使p1重复指向第一个节点
p1Prev = pH; //指向p1的前一个节点
//如果最后一位更换则改变pmin(已插入数的最小值,也
//就是前面被操作过的最后一个节点)的值
if(p->data < pmin->data)
pmin = p;
//在循环中实现插入
while(p != p1)
{
//插入值更小,则与下一个比较
if(p->data < p1->data)
{
p1Prev = p1;
p1 = p1->pNext;
}
else
{
//找到要插入的位置,链接成新链表
pmin->pNext = pBack;
p->pNext = p1;
p1Prev->pNext = p;
break;
}
}
p = pBack; //指向下一个节点
}
pmin->pNext = NULL; //让最后一个节点指向NULL
}
//由小到大排序
else
{
while(NULL != p)
{
pBack = p->pNext; //保存下一个节点地址
p1=pH->pNext; //使p1重复指向第一个节点
p1Prev = pH; //指向p1的前一个节点
//如果最后一位更换则改变pmax(已插入数的最大值,也
//就是前面被操作过的最后一个节点)的值
if(p->data > pmax->data)
pmax = p;
while(p != p1)
{
//插入值更大,则与下一个比较
if(p->data > p1->data)
{
p1Prev = p1;
p1 = p1->pNext;
}
else
{
//找到要插入的位置,链接成新链表
pmax->pNext = pBack;
p->pNext = p1;
p1Prev->pNext = p;
break;
}
}
p = pBack; //指向下一个节点
}
pmax->pNext = NULL; //让最后一个节点指向NULL
}
关于希尔排序会在后期的博客中贴出。
关于链表的基本操作可参考我的另一篇博客:https://blog.csdn.net/weixin_44313435/article/details/104373582