主要的排序方式分为:插入型(直接插入、希尔排序)、交换型(冒泡排序、快速排序)、选择型(简单选择排序、堆排序)、归并排序、基数排序。
直接插入排序:
对于给定的一组记录,初始时假定第一个记录自成一个有序的序列,其余的记录为无序序列;接着从第二个记录开始,按照记录的大小依次将当前处理的记录插入到其之前的有序序列中,直至最后一个记录插入到有序序列为止。
代码实现:
#include <stdio.h>
void InsertSort(int par_array[], int array_size)
{
int i, j;
int temp;
for (i = 1; i < array_size; i++)
{
temp = par_array[i];
for (j = i - 1; j >= 0; j--)
{
if (temp < par_array[j])
{
par_array[j + 1] = par_array[j];
}
else
{
break;
}
}
par_array[j + 1] = temp;
}
}
int main()
{
int i = 0;
int a[] = {3, 5, 2, 1, 9, 0, 6, 4, 7, 8};
int length = sizeof(a) / sizeof(a[0]);
InsertSort(a, length);
for (i = 0; i < length; i++)
{
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
希尔排序:
希尔排序也称为“缩小增量排序”,基本原理是:首先将待排序的元素分为多个子序列,使得每个子序的元素个数相对较少,对各个子序分别进行直接插入排序,待整个待排序序列“基本有序后”,再对所有元素进行一次直接插入排序。
#include <stdio.h>
void ShellSort(int array[], int length)
{
int i, j;
int h;
int temp;
for (h = length / 2; h > 0; h = h / 2)
{
for (i = h; i < length; i++)
{
temp = array[i];
for (j = i - h; j >= 0; j -=h)
{
if (temp < array[j])
{
array[j + h] = array[j];
}
else
{
break;
}
}
array[j + h] = temp;
}
}
}
int main()
{
int i = 0;
int a[] = {0, 5, 2, 4, 3, 1, 7, 6, 8, 9};
int length = sizeof (a) / sizeof(a[0]);
ShellSort(a, length);
for (i = 0; i < length; i++)
{
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
冒泡排序:
对于给定的n个记录,从第一个记录开始依次对相邻的两个记录进行比较,当前面的记录大于后面的记录时,交换其位置,进行一轮比较和交换位置后,n个记录中的最大记录将位于第n位;然后对前(n- 1)个记录进行第二轮比较;重复该过程直到进行比较的记录只剩下一个为止。对于给定的n个记录,从第一个记录开始依次对相邻的两个记录进行比较,当前面的记录大于后面的记录时,交换其位置,进行一轮比较和交换位置后,n个记录中的最大记录将位于第n位;然后对前(n- 1)个记录进行第二轮比较;重复该过程直到进行比较的记录只剩下一个为止。
代码实现:
#include <stdio.h>
void BubbleSort(int array[], int len)
{
int i, j;
int temp;
for (i = 0; i < len -1; ++i)
{
for (j = len - 1; j > i; --j)
{
if (array[j] < array[j - 1])
{
temp = array[j];
array[j] = array[j - 1];
array[j - 1] = temp;
}
}
}
}
int main()
{
int i = 0;
int a[] = {29, 18, 87, 56, 3, 27};
int length = sizeof(a) / sizeof(a[0]);
BubbleSort(a, length);
for (i = 0; i < length; i++)
{
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
快速排序:
快速排序是一种非常高效的排序方法,采用“分而治之”的思想,把大的拆分为小的,小的在拆分为更小的。
原理是:对于一组给定的记录,通过一趟排序后,将原序列分为两部分,其中前部分的所有记录均比后部分的所有记录小,然后再依次对前后两部分的记录进行快速排序,递归该过程,直到序列中的所有记录均为有序为止。
{
array[i++] = array[j];
}
while (i < j && array[i] < index )
{
i++;
}
if (i < j)
{
array[j--] = array[i];
}
}
array[i] = index;
Sort(array, low, i - 1);
Sort(array, i + 1, high);
}
void QuickSort(int array[], int length)
{
Sort(array, 0, length - 1);
}
int main()
{
int i = 0;
int a[] = {29, 96, 18, 56, 3, 56, 39, 77};
int length = sizeof (a) / sizeof(a[0]);
QuickSort(a, length);
for (i = 0; i < length; i++)
{
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
简单选择排序:
是一种简单直观的排序算法,他的基本原理是:对于给定的一组记录,经过第一轮比较后得到最小的记录,然后将记录与第一个记录的位置进行交换;接着对不包括第一个记录以外的其他记录进行第二轮排序,得到最小的记录并与第二个记录进行位置交换;重负该过程,直到进行比较的记录只有一个为止。
#include <stdio.h>
void SelectSort(int *a, int n)
{
int i, j;
int temp = 0;
int flag = 0;
for (i = 0; i < n - 1; i++)
{
temp = a[i];
flag = i;
for (j = i + 1; j < n; j++)
{
if (a[j] < temp)
{
temp = a[j];
flag = j;
}
}
if (flag != i)
{
a[flag] = a[i];
a[i] = temp;
}
}
}
int main()
{
int i = 0;
int a[] = {5, 4, 3, 6, 1, 9, 7, 0, 2, 8};
int length = sizeof(a) / sizeof(a[0]);
SelectSort(a, length);
for (i = 0; i < length; i++)
{
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
堆排序:
堆排序是一种特殊的树形数据结构,其每个节点都有一个值,通常提到的堆都是指一棵完全二叉树,根节点的值小于(或大于)两个子节点的值,同时根节点的两个子树也分别是一个堆。堆排序主要包括两个过程:一是构建堆,二是交换堆顶元素与最后一个元素的位置。
#include <stdio.h>
void AdjustMinHeap(int *a, int pos, int len)
{
int temp;
int child;
for (temp = a[pos]; 2 * pos + 1 <= len; pos = child)
{
child = 2 * pos + 1; 5
if (child < len && a[child] > a[child + 1])
{
child++;
}
if (a[child] < temp)
{
a[pos] < a[child];
}
else
{
break;
}
}
a[pos] = temp;
}
void Swap(int a, int b)
{
int temp;
temp = a;
a = b;
b = temp;
}
void PrintArray(int *a, int length)
{
int i;
for (i = 0; i < length; i++)
{
printf("%d ", a[i]);
}
printf("\n");
}
void HeapSort(int *array, int len)
{
int i;
for (i = len / 2 - 1; i >= 0; i--) i = 2 i = 1 i = 0
{
AdjustMinHeap(array, i, len - 1);
}
for (i = len -1; i >= 0; i--)
{
Swap(array[0], array[i]);
AdjustMinHeap(array, 0, i - 1);
}
}
int main()
{
int array[] = {0, 13, 1, 14, 27, 18};
int length = sizeof(array) / sizeof(array[0]);
HeapSort(array, length);
PrintArray(array, length);
return 0;
}
归并排序:
利用递归与分治技术将数据序列划分为越来越小的半子表,再对半子表排序,最后再用递归步骤将排好序的半子表合并成为越来越大的有序序列。
原理如下:对于给定的一组记录,首先将两个相邻的长度为1的子序列进行归并,得到n/2个长度为2或者1的有序子序列,在将其两两归并,反复执行此过程,直到得到一个有序的序列为止。
array[k] = L[j];
}
}
if (j < n2)
{
for (i = j; i < n2; i++, k++)
{
array[k] = R[i];
}
}
}
void MergeSort(int array[], int start, int end)
{
int middle;
int i;
if (start < end)
{
middle = (start + end) / 2;
MergeSort(array, start, middle);
MergeSort(array, middle + 1, end);
Merge(array, start, middle, end);
}
}
int main()
{
int i = 0;
int a[] = {49, 38, 65, 97, 76, 13, 27};
int length = sizeof(a) / sizeof(a[0]);
MergeSort(a, 0, length -1);
for (i = 0 ; i < length; i++)
{
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
基数排序:
基数排序(RadixSorting)是一种借助多关键字排序的思想对单逻辑关键字进行关系的方法。基数排序不需要进行记录关键字间的比较。
主要分为两个过程:
(1)分配,先从个位开始,根据位值(0-9)分别放到0~9号桶中(比如53,个位为3,则放入3号桶中)
(2)收集,再将放置在0~9号桶中的数据按顺序放到数组中
#include <stdio.h>
#include <stdlib.h>
int RadixCountSort(int *index, int *a, int len) //收集
{
int *count = (int *)malloc(sizeof(int) * len);
int i;
for (i = 0; i < len; ++i)
{
count[i] = 0;
}
for (i = 0; i < len; ++i)
{
++count[index[i]];
}
for (i = 1; i < 10; ++i)
{
count[i] += count[i - 1];
}
int *sort = (int *)malloc(sizeof(int) * len);
for (i = len - 1; i >= 0; --i)
{
--count[index[i]];
sort[count[index[i]]] = a[i];
}
for (i = 0; i < len; ++i)
{
a[i] = sort[i];
}
free(sort);
free(count);
return 1;
}
int RadixSort(int *a, int len) //分配
{
int *radix = (int *)malloc(sizeof(int) * len);
int radix_base = 1;
int is_ok = 0;
while (!is_ok)
{
int i;
is_ok = 1;
radix_base *= 10;
for (i = 0; i < len; ++i)
{
radix[i] = a[i] % radix_base;
radix[i] /= radix_base / 10;
if (radix[i] > 0)
{
is_ok = 0;
}
}
if (is_ok)
{
break;
}
RadixCountSort(radix, a, len);
}
free(radix);
return 1;
}
int main()
{
int i;
int a[] = {278, 109, 63, 930, 589, 184, 505, 269, 8, 83};
int len = sizeof (a) / sizeof (a[0]);
RadixSort(a, len);
for (i = 0; i < len; ++i)
{
printf("%d ", a[i]);
}
printf("\n");
return 0;
}