原来我一直都不会对链表进行排序,呵呵,比较菜。今天下了很大的功夫学习对链表的排序,和大家分享一下!
对链表的排序主要有两种方法:
一:只交换节点中的元素,不改变链表的顺序。
二:直接交换节点,不改变节点中的元素。
其中交换节点是最麻烦的,稍不注意就会出错!而交换节点中的元素还是比较简单的。用几个swap( )就可以了。
单链表的冒泡排序法:
// powered by sunkehappy QQ 675313675
// 用冒泡排序法对链表中的元素进行按照非降序排列
#include <stdio.h>
#include <conio.h> // getch()
#include <stdlib.h>
#include <malloc.h>
typedef struct link{
int data;
struct link *next;
}LNode, *LinkList;
LinkList CreateLink( LinkList *head, int num )
{
int i, data;
LinkList p;
// 建立链表
printf("请输入节点中的元素(整数):\n");
for( i = 0; i < num; i++ ){
p = ( LinkList )malloc( sizeof(LNode) );
// 读取数据并存放在节点中
scanf("%d",&data);
p->data = data;
// 建立链表,并插入到head后
p->next = ( *head )->next;
( *head )->next = p;
}
return ( *head )->next;
}// CreateList
// 用冒泡法对链表中的节点排序
void BubbleSort( LinkList head )
{
LinkList p, prep, temp, tail;
tail = NULL;
// 算法的核心部分
while( head->next != tail ){
prep = head;
p = head->next;
while( p->next != tail ){
if( p->data > p->next->data ){
temp = p->next;
prep->next = p->next;
p->next = p->next->next;
prep->next->next = p;
p = temp;
}
// 节点后移
p = p->next;
prep = prep->next;
}
tail = p;
}// 第一个while
}// BubbleSort
void Print( LinkList head )
{
while( head != NULL ){
printf("%d ",head->data);
head = head->next;
}
}
int main( void )
{
int num;
LinkList head;
// prep为指向p之前的节点的指针
printf("请输出要建立的节点的个数:\n");
scanf("%d",&num);
// 建立头结点
head = ( LinkList )malloc( sizeof(LNode) );
head->data = num;
head->next = NULL;
// 建立长度为num的链表
head->next = CreateLink( &head, num );
BubbleSort( head );
printf("经过排序后的数据为:\n");
Print( head->next );
getch();
}
我在刚开始的时候也是没能够自己想出来,怎么弄都弄不好。在网上搜了一些,终于看懂了。但是他们写的基本没有注释,可读性很差。所以我就自己写了一个。
单链表的冒泡排序法的难点在于如何实现双重循环,好好理解其中那个tail的用法;以及以及如何交换节点,注意temp的用法。
下面是单链表通过交换数据的排序方法(双循环有点像冒泡排序法):
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <malloc.h>
typedef struct link{
int data;
struct link *next;
}LNode, *LinkList;
LinkList CreateLink( int num )
{
int i;
LinkList p, head;
// 建立头结点
head = ( LinkList )malloc( sizeof(LNode) );
head->data = num;
head->next = NULL;
// 建立头结点以后的节点
printf("请输入节点中的数据:\n");
for( i = 0; i < num; i++ ){
p = ( LinkList )malloc( sizeof(LNode) );
p->next = head->next;
head->next = p;
scanf("%d", &p->data );
}
return head;
}// CreateLink
int ListLength( LinkList head )
{
int len = 0;
while( head != NULL ){
++ len;
head = head->next;
}
return len;
}
void SortLink( LinkList *head )
{
int i, j, temp, len ;
LinkList prep,p;
len = ListLength( *head );
for( i = 0; i < len; i++ ){
prep = ( *head );
p = ( *head )->next;
for( j = 0; j < len -1 - i; j++ ){
if( prep->data > p->data ){
temp = prep->data;
prep->data = p->data;
p->data = temp;
}
// 节点后移
p = p->next;
prep = prep->next;
}
}// while
}// SortLink
// 输出链表中的数据
void PrintLink( LinkList head )
{
printf("排序后的链表中的数据为:\n");
while( head != NULL ){
printf("%d ", head->data );
head = head->next;
}
}
int main( void )
{
int num;
LinkList head ;
printf("请输入要建立的节点数:\n");
scanf("%d", &num );
// 建立有num个节点的链表
head = CreateLink( num );
SortLink( &head->next );
PrintLink( head->next );
getch();
return 0;
}