C语言数据结构-速率较高的链表排序算法-插入排序法

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

发布了8 篇原创文章 · 获赞 18 · 访问量 5128

猜你喜欢

转载自blog.csdn.net/weixin_44313435/article/details/104388677