本文用C 实现4种排序算法: 冒泡排序(buble sort),选择排序(selection sort),插入排序(insertion sort),合并排序(merge sort).
本文是动画讲解4种排序算法的继续,如果对4种排序算法不是很清楚,可以回过头看看。
先把代码放上:
#include <stdio.h>
// Prints all the elements in an array on one line.
void print_array(int array[], int n,int m)
{
for(int i = m; i < n; i++)
{
printf("%i ", array[i]);
}
printf("\n");
}
// Sorts array in place using bubble sort - optimizes to end if there are no swaps
void bubble_sort(int array[], int n)
{
// cycle through array
for(int k = 0; k < n - 1; k++)
{
// optimize; check if there are no swaps
int swaps = 0;
// swap adjacent elements if out of order
for(int i = 0; i < n - 1 - k; i++)
{
if (array[i] > array[i + 1])
{
int temp = array[i + 1];
array[i + 1] = array[i];
array[i] = temp;
swaps++;
print_array(array,n,0);
}
}
if (!swaps)
break;
}
}
// Sorts array in place using selection sort
void selection_sort(int array[], int size)
{
// iterate over array
for(int i = 0; i < size - 1; i++)
{
// smallest element and its position in sorted array
int smallest = array[i];
int position = i;
// unsorted part of array
for(int k = i + 1; k < size; k++)
{
// find the next smallest element
if (array[k] < smallest)
{
smallest = array[k];
position = k;
}
}
// swap
int temp = array[i];
array[i] = smallest;
array[position] = temp;
print_array(array,size,0);
}
}
// Sorts array in place using insertion sort
void insertion_sort(int array[], int size)
{
// iterate through unsorted part of array from l->r
for(int i = 1; i < size; i++)
{
// define the start of the sorted array
int j = i - 1;
// specify the next element to sort
int to_sort = array[i];
// iterate through sorted part of array from r->l
// figure out where in sorted portion to_sort should go
while(j >= 0 && to_sort < array[j])
{
// shift sorted elements rightward
array[j + 1] = array[j];
j--;
}
// insert element into sorted portion of array
array[j + 1] = to_sort;
print_array(array,size,0);
}
}
// function to sort the subsection a[i .. j] of the array a[]
void merge_sort(int i, int j, int a[], int aux[]) {
if (j <= i) {
return; // the subsection is empty or a single element
}
int mid = (i + j) / 2;
// left sub-array is a[i .. mid]
// right sub-array is a[mid + 1 .. j]
printf("begin sort: ");
print_array(a,j+1,i);
merge_sort(i, mid, a, aux); // sort the left sub-array recursively
merge_sort(mid + 1, j, a, aux); // sort the right sub-array recursively
int pointer_left = i; // pointer_left points to the beginning of the left sub-array
int pointer_right = mid + 1; // pointer_right points to the beginning of the right sub-array
int k; // k is the loop counter
// we loop from i to j to fill each element of the final merged array
for (k = i; k <= j; k++) {
if (pointer_left == mid + 1) { // left pointer has reached the limit
aux[k] = a[pointer_right];
pointer_right++;
} else if (pointer_right == j + 1) { // right pointer has reached the limit
aux[k] = a[pointer_left];
pointer_left++;
} else if (a[pointer_left] < a[pointer_right]) { // pointer left points to smaller element
aux[k] = a[pointer_left];
pointer_left++;
} else { // pointer right points to smaller element
aux[k] = a[pointer_right];
pointer_right++;
}
}
for (k = i; k <= j; k++) { // copy the elements from aux[] to a[]
a[k] = aux[k];
}
printf("after merge: ");
print_array(a,j+1,i);
}
int main(int argc, char *argv[])
{
int size = 8;
char flag='b';
int nums[] = {6,5,3,1,8,7,2,4};
int aux[size];
printf("begin :");
print_array(nums, size,0);
// get parameter from command line
if(argc>1)
{
flag=argv[1][0];
}
else
printf("usage: sort1 b(bubble)|s(seleccction)|i(insertion)|m(merge\n");
if(flag=='b')
{
// bubble sort
printf("Bubble sort\n");
bubble_sort(nums, size);
}
else if (flag=='s')
{
// selection sort
printf("Selection sort\n");
selection_sort(nums, size);
}
else if(flag=='i')
{
// insertion sort
printf("Insertion sort\n");
insertion_sort(nums, size);
}
else if(flag=='m')
{
// merge sort
printf("Merge sort\n");
merge_sort( 0, size - 1,nums,aux);
}
else
printf("only option b,s,i,m\n");
printf("end: ");
print_array(nums, size,0);
}
4种算法,分别用4个函数实现。
程序运行带参数,比如程序名为sort1
那么 sort1 b 用泡沫排序, sort1 m 用合并排序 sort1 s 用选择排序 sort1 i 插入排序
程序运行结果分别如下:
~/ $ ./sort1 m
begin :6 5 3 1 8 7 2 4
Merge sort
begin sort: 6 5 3 1 8 7 2 4
begin sort: 6 5 3 1
begin sort: 6 5
after merge: 5 6
begin sort: 3 1
after merge: 1 3
after merge: 1 3 5 6
begin sort: 8 7 2 4
begin sort: 8 7
after merge: 7 8
begin sort: 2 4
after merge: 2 4
after merge: 2 4 7 8
after merge: 1 2 3 4 5 6 7 8
end: 1 2 3 4 5 6 7 8
~/ $ ./sort1 b
begin :6 5 3 1 8 7 2 4
Bubble sort
5 6 3 1 8 7 2 4
5 3 6 1 8 7 2 4
5 3 1 6 8 7 2 4
5 3 1 6 7 8 2 4
5 3 1 6 7 2 8 4
5 3 1 6 7 2 4 8
3 5 1 6 7 2 4 8
3 1 5 6 7 2 4 8
3 1 5 6 2 7 4 8
3 1 5 6 2 4 7 8
1 3 5 6 2 4 7 8
1 3 5 2 6 4 7 8
1 3 5 2 4 6 7 8
1 3 2 5 4 6 7 8
1 3 2 4 5 6 7 8
1 2 3 4 5 6 7 8
end: 1 2 3 4 5 6 7 8
~/ $ ./sort1 s
begin :6 5 3 1 8 7 2 4
Selection sort
1 5 3 6 8 7 2 4
1 2 3 6 8 7 5 4
1 2 3 6 8 7 5 4
1 2 3 4 8 7 5 6
1 2 3 4 5 7 8 6
1 2 3 4 5 6 8 7
1 2 3 4 5 6 7 8
end: 1 2 3 4 5 6 7 8
~/ $ ./sort1 i
begin :6 5 3 1 8 7 2 4
Insertion sort
5 6 3 1 8 7 2 4
3 5 6 1 8 7 2 4
1 3 5 6 8 7 2 4
1 3 5 6 8 7 2 4
1 3 5 6 7 8 2 4
1 2 3 5 6 7 8 4
1 2 3 4 5 6 7 8
end: 1 2 3 4 5 6 7 8
~/ $
算法函数中,合并算法可能比较复杂一点,用了递归函数。从中间分解为2个排序,然后合并。
合并循环中,分4种情况,
pointer_left == mid + 1: 左边空了,
pointer_right == j + 1: 右边空了
a[pointer_left] < a[pointer_right]: 左边第1< 右边第一
左边第1》= 右边第一
如果觉得main 函数看不懂,可以用下面main 函数替代上面的main函数。
int main(int argc, char *argv[])
{
int size = 8;
char flag='b';
int nums[] = {6,5,3,1,8,7,2,4};
int aux[size];
print_array(nums, size,0);
// bubble sort
//bubble_sort(nums, size);
// selection sort
//selection_sort(nums, size);
// insertion sort
//insertion_sort(nums, size);
// merge sort
merge_sort( 0, size - 1,nums,aux);
print_array(nums, size,0);
}
这个时候,main函数是主函数,代码中只调用 合并算法,如果要换一种算法,注释掉他的调用,换一种你想要算法的调用即可。运行结果与上面一样。
算法中,为了体现过程,加了显示语句,明白了也可以注释掉。
介绍到此。