直接插入排序
将链表断为两部分,一部分为有序链表,一部分为无序链表。逐步将无序链表中的结点按顺序插入到有序链表中。
void Listsort(LinkList head)
{
Node *p=head->next, *pNext, *r;
pNext = p->next;
p->next = NULL; //断开链表
p = pNext; //指针后移
while (p)
{
pNext = p->next; //pNext指向下一个结点
r = head; //r用来遍历单链表,寻找插入的位置
while (r->next != NULL && r->next->date < p->date) //在有序链表中寻找p差入的位置
r = r->next; //遍历
p->next = r->next;
r->next = p; //插入p
p = pNext; //p后移一位
}
}
转换数组
将每一个结点的地址保存到额外数组里,在对数组进行排序,安排好序的数组重新建立链表。
void Listsort(LinkList head)
{
Node **aux,*p=head->next; //建立二级指针aux
int len=0,i;
while (p) //遍历链表,求表长
{
p = p->next;
len++;
}
p = head->next;
aux = (Node**)malloc(sizeof(Node*)*len); //开辟储存链表各结点地址的空间,将空间首地址付给aux
for (i = 0; i < len; i++) //将链表各节点地址保存在指针数组aux[]中
{
aux[i] = p;
p = p->next;
}
List_insort(aux, len); //用数组的方式排序
head->next=aux[0]; //连接表头
for (i = 0; i < len-1; i++)
{
aux[i]->next = aux[i + 1]; //连接排好序的结点
}
aux[len - 1]->next = NULL; //尾结点的指针域设为空
}
数组排序的代码(插入排序)
void List_insort(Node*a[], int n)
{
int i, j;
Node *temp;
for (i = 1; i < n; i++)
{
j = i - 1;
if (a[j]->date > a[i]->date) //比较时用数据域比较
{
temp = a[i];
a[i] = a[j];
for (j = j - 1; j >= 0 && temp->date < a[j]->date; j--)
a[j + 1] = a[j];
a[j + 1] = temp;
}
}
}
冒泡排序
确定数据总量,限制循环次数,在循环中比较结点的数据并进行结点的交换。
void Listsort(LinkList head)
{
Node *p, *q;
int num = 0, j = 0,i;
q = head->next;
while (q) //遍历确定链表长度
{
q = q->next;
num++;
}
for (i = 0; i < num; i++)
{
q = head; //指向首元结点
p = head->next; //指向首元结点后的第一个结点
for(j=num-i-1;j>0;j--)
{
if (p->date > p->next->date)
{
q->next = p->next;
q = p->next;
p->next = q->next;
q->next = p;
p = q; //交换结点
}
q = p; //保证q在p前
p = p->next; //p后移
}
}
}
归并排序
- 用快慢指针遍历找到中间结点。
- 从中间结点断开,将链表分为左右两个链表,两个链表再分解(运用递归)。
- 当不能再分解时把两个链表合并。
- 继续向上合并直到链表唯一。
LinkList Listsort(LinkList start)
{
Node *slow = start;
Node *fast = start;
while (1)
{
if (NULL == fast)
break;
fast = fast->next;
if (NULL == fast)
break;
fast = fast->next;
if (NULL == fast)
break;
slow = slow->next;
}
Node *middle = slow->next; //中间点
if (NULL == middle) //只有一个结点,不用再分解
return start;
slow->next = NULL; //断开链表
Node *l = Listsort(start); //递归调用分解左链表
Node *r = Listsort(middle); //递归调用分解右链表
Node *tmp = Combine(l, r); //定义新指针合并左右链表
return tmp; //返回新指针
}
LinkList Combine(Node *left, Node *right)
{
if (NULL == left || NULL == right)
{
if (NULL == left)
return right;
else if(NULL == right)
return left;
}
else if (left->date <= right->date)
{
left->next = Combine(left->next, right);
return left;
}
else
{
right->next = Combine(left, right->next);
return right;
}
}