在链表上对直接插入排序算法的思想:
在带头结点的单链表L 中,如果将已有元素进行升序(或降序)排列,可先将原单链表L 暂时断成两条短链L1和L2,新链L1的头结点用原链L 的头结点(head),并且链L1中仅放一个元素即原链的第一个元素。而链L2中的头结点可从原链的第二个元素开始,然后用L2中的第一个元素与L1中的第一个元素作比较链入链L1中,接着继续在L2中取一个元
素让它跟链L1中的第一个元素开始依次向后比较找相应位置插入完成排序操作。后面元素的排序同理,直到将链L2中的所有的元素取完为止。
代码实现:
//单链表上实现直接插入排序
//输入任意N个数,按“回车”结束输入。递增排序后输出(若要实现递减,修改"l1->data<l2->data"为“l1->data>l2->data”)。
#include <stdio.h>
#include <stdlib.h>
typedef struct node //定义单链表结点
{
int data; //数据域
struct node *next;//指针域
}linklist;
void creatlist(linklist *head) //尾插法建立单链表
{
linklist *p,*q;//p是指向新分配节点的指针,q是已分配链表尾指针
int i=0;
int x=0;
int j=0;
printf("please input the node:\n");
while(1)
{
scanf("%d",&x);
p=(linklist *)malloc(sizeof(linklist));
p->data=x;
if(++i==1) //头指针指向第一个结点
{
head->next=p;
}
else //链入新结点
{
q->next=p;
}
q=p; //更新尾指针
q->next=NULL; //尾指针置空
if(getchar()=='\n')//按回车结束输入
{
break;
}
}//end while
}
void sortlist(linklist *head) //插入排序在单链表上的实现
{
linklist *newhead, *pre, *l1, *l2,*l;
l1=head->next; //变量p用来存放链L1的头结点地址
newhead=l1->next; //newhead用来标记链L2的头结点的地址
l1->next=NULL; //将原来的链L断开
while(newhead) //判断:1.原链L中元素不少于两个。2.新链L2中还有元素未插入L1
{
l2=newhead; //l2指向待插入结点(链L2的头结点)
newhead=newhead->next; //l2去掉头结点后头指针后移
pre=head; //pre指向链L1待插入位置的前驱
l1=head->next; //l1指向链L1待插入位置的后继
while(l1!=NULL&&l1->data<l2->data)//与L1中元素作比较
{
pre=l1;//依次向后找合适的插入点
l1=l1->next;
}
l2->next=l1;
pre->next=l2;//将L2中元素链入L1中合适位置
}
l=head->next;
printf("insert-sort output:\n");
while(l) //依次输出排序后链表元素
{
printf("%d ",l->data);
l=l->next;
}
}
void main()
{
linklist *h;
h=(linklist *)malloc(sizeof(linklist)); //建头结点
h->next=NULL; //初始化头指针
creatlist(h);
sortlist(h);
}
欢迎交流和指正!- –