单链表排序不同于一般的排序,一般的排序支持随机读取,但是单链表不支持随机读取,要一点一点从头开始遍历,而且在排序时要特别注重指针的操作。在这里,介绍几种应用于单链表的排序方法。
首先,做一些提前的准备工作,创建链表和打印链表。
创建链表:
struct ListNode
{
int val;
ListNode* next;
};
void InsertNode(ListNode* &head, int value)
{
if (head == NULL)
{
head = (ListNode *)malloc(sizeof(ListNode));
if (head == NULL)
{
cout<<"malloc failed";
return;
}
else
{
head->val = value;
head->next = NULL;
}
}
else
{
ListNode *temp = (ListNode *)malloc(sizeof(ListNode));
if (temp == NULL)
{
cout<<"malloc failed";
return;
}
else
{
temp->val = value;
temp->next = head;
head = temp;
}
}
return;
}
void Insert(int n,ListNode* &head)
{
srand((unsigned)time(NULL)); //初始化随机数
for (int i = 0; i < n; i++)
InsertNode(head, rand());
ListNode *p = (ListNode *)malloc(sizeof(ListNode));
p->next = head;
head = p;
cout<<"所有的随机数为: ";
p = head->next; //输出测试
while (p)
{
//printf("%d ", p->val);
cout << p->val << " ";
p = p->next;
}
cout << endl;
cout << endl;
return;
}
打印链表:
void printlist(ListNode* head)
{
ListNode* node = head->next;
while (node)
{
cout << node->val << " ";
node = node->next;
}
cout << endl;
}
主函数:
int main()
{
ListNode* head = NULL;
Insert(20, head);
select_sort(head);//这里的函数可改变
printlist(head);
system("pause");
return 0;
}
下面进入正题:
第一个算法:选择排序算法在单链表的应用。
选择排序算法的基本思想是:将待排序数组分成有序区和无序区,初始化时整个数组都是无序区,每次从无序区中选择最小的数加到有序区的后面,直到无序区只剩下最后一个数为止。
void select_sort(ListNode* &head)
{
//sorted是已排序数组的末尾,unsorted是未排序数组的开头,min指向最小的节点
//premin指向min前面一个节点
ListNode* sorted, *unsorted, *min,*premin;
sorted = NULL;
unsorted = head;
min = NULL;
while (unsorted->next)
{
min = unsorted;
ListNode* temp = unsorted->next;
while (temp)
{
if (temp->val < min->val)
min = temp;
temp = temp->next;
}
if (min == unsorted)
sorted = unsorted;
else
{
//premin是为了保证链表不断开,min之前的结点指向min之后的结点
premin = unsorted;
while (premin->next != min)
premin = premin->next;
premin->next = min->next;
if (sorted == NULL)
{
min->next = head;
head = sorted = min;
}
else
{
sorted->next = min;
min->next = unsorted;
sorted = min;
}
}
unsorted = sorted->next;
}
}
输出:
算法二:插入算法。
直接插入算法:将待排序数组分成有序区和无序区,初始化时认为左边第一个元素有序,每次将无序区的首个元素依次与有序区的数比较,将其插入到有序区合适的位置,直到无序区元素个数为0
void insert_sort(ListNode* head)
{
if (head == NULL)
return;
ListNode *sorted,*unsorted;//划分有序区和无序区
sorted = NULL;
unsorted = head;
while (unsorted)
{
ListNode* prenode = NULL;
ListNode* node = head;
while (node && node != unsorted &&node->val < unsorted->val)
{
prenode = node;
node = node->next;
}
if (node == unsorted)
{
sorted = unsorted;
//unsorted = unsorted->next;
}
else
{
sorted->next = unsorted->next;
prenode->next = unsorted;
unsorted->next = node;
//unsorted = sorted->next;
}
unsorted = sorted->next;
}
}
输出: