单链表实现归并排序

有时冒泡排序很不优雅,这是就要用到神奇的归并排序
这也简单的算我算法坑中的一篇文章吧

此篇文章只说明代码,归并具体的含义请右转下面的链接

https://en.wikipedia.org/wiki/Merge_sort

这是wikipedia对归并算法的具体定义,以及很多的例子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
//
// main.c
// 单链表归并排序
//
// Created by SaberDa on 16/9/21.
// Copyright © 2016年 SaberDa. All rights reserved.
//

#include <stdio.h>
#include <stdlib.h>

/*Link list node*/
struct node
{
int data;
struct node* next;
};

/*function prototype */
struct node* SortedMerge(struct node* a, struct node* b);
void FrontBackSplit(struct node* source, struct node** frontRef, struct node** backRef);

/*sorts the linked list by changing next pointers(not data) */
void MergeSort(struct node** headRef)
{
struct node* head = *headRef;
struct node* a;
struct node* b;

/*base case-- length 0 or 1 */
if((head == NULL) || (head->next == NULL))
{
return;
}

/*Split head into 'a' and 'b' sublists */
FrontBackSplit(head, &a, &b);

/*Recursively sort the sublists */
MergeSort(&a);
MergeSort(&b);

/* answer = merge the two sorted lists together */
*headRef = SortedMerge(a, b);
}

struct node* SortedMerge(struct node* a, struct node* b)
{
struct node* result = NULL;

/* Base cases */
if(a == NULL)
return (b);
else if(b == NULL)
return (a);

/* Pick either a or b recur */
if(a->data <= b->data)
{
result = a;
result->next = SortedMerge(a->next, b);
}
else
{
result = b;
result->next = SortedMerge(a, b->next);
}
return (result);
}

//将单链表一份为二
void FrontBackSplit(struct node* source, struct node** frontRef, struct node** backRef)
{
struct node* fast;
struct node* slow;

if(source == NULL || source->next == NULL)
{
*frontRef = source;
*backRef = NULL;
}
else
{
slow = source;
fast = source->next;

/* Advance 'fast' two nodes, and advance 'slow' one node */
while(fast != NULL)
{
fast = fast->next;
if( fast != NULL )
{
slow = slow->next;
fast = fast->next;
}
}

*frontRef = source;
*backRef = slow->next;
slow->next = NULL;
}
}

/*Function to print nodes in a given linked list*/
void printList(struct node* node)
{
while( node != NULL )
{
printf("%d ", node->data);
node = node->next;
}
}

/* Function to insert a node at the begining of the linked list*/
void push(struct node** head_ref, int new_data)
{
/*allocate node*/
struct node* new_node = (struct node*)malloc(sizeof(struct node));

/*put in the data*/
new_node->data = new_data;

/*link the old list off the new node*/
new_node->next = (*head_ref);

/*move the head to point to the new node*/
(*head_ref) = new_node;
}

/* Drier program to test above functions*/
int main()
{
/* Start with the empty list */
struct node* res = NULL;
struct node* a = NULL;
int turn;
scanf("%d", &turn);

int num;
for (int i = 0; i < turn; i++) {
if (scanf("%d", &num)) {
push(&a, num);
}
}

/* Sort the above created Linked List */
MergeSort(&a);

printf("\n Sorted Linked List is: \n");
printList(a);

return 0;
}