链表的插入法排序

链表的插入法排序


         插入法排序,不同于冒泡排序,选择排序需要将链表比较很多遍。

相反他只需要将链表遍历一遍就可以将排序完成。


        直接插入排序的基本思想:假设链表的前面n-1个节点是已经有值的 并且排好序的,

对于节点n在 这个序列中找插入位置,使得n插入后新序列仍然有序。

按照这种思想,依次对链表从头到尾执行一遍,就可以使无序链表变为有序链表。



下面看单向链表的直接插入排序图示:


head---->[1]------>[3]------> [2]...------>[n]------>[NULL](原链表head为空)

head ---->[1]---->[NULL](从原链表中取第1个节点作为只有一个节点的有序链表)

first---->[3]---->[2]...---->[n]---->[NULL](first指向原链表剩下用于直接插入排序的节点)


先在原链表中以第一个节点为一个有序链表,原链表剩下的视为无序链表。

虽然是将一条链表截成两段,但实际上还是一条链表


void sort(struct Sum *head)  //传入链表头
{
       struct Sum *p,*q,*t,*first;  //定义中间指针变量。
       head=head->next;    //头节点为空则跳过头节点
       first=head->next;   //将剩余的链表默认为无序链表  head一直是有序链表的头结点
       head->next=NULL;    //提取出第一个节点为有序链表

       while(first!=NULL)  //当无序链表不为空
	{             
	      for(t = first,p = head;p !=NUL L&& p->num< = t->num;q = p,p = p->next);  //跳出循环找出插入的点 
	      first = first->next;//无序链表向后

              if(p == head)       //第一个节点不符合条件  
                  head = t;       //head中第一个节点 p->num 大于 无序链表 第一个节点 t->num,退出循环,
                                  //应将 t节点放在第一个结点,所以令head = t
              else 
                  q->next = t;    // q指向了p的上一个结点,将 t结点插入到 q结点之后。如果p == NULL, 则 t结点放在有序链表的末尾 
             
              t->next = p;        //当 p != NULL 时 使 t插入到 p 前一个的位置。 当 p == NULL 时使t->next = NULL  
              //first = first->next; //虽然放在这里与性也没错,如果理解了上面加粗的那句话,会发现放在这里是不行的。
	}
}

   请结合代码中的注释仔细分析

你可能感兴趣的:(C语言)