第一:
按照排序过程中所依据的原则的不同可以分类为:
►插入排序
直接插入排序 希尔排序
►交换排序
冒泡排序 快速排序
►选择排序
简单选择排序 堆排序
►归并排序
►基数排序
第一 :插入排序(直接插入排序)(suju——》lesson6——》1.c)
一:直接插入排序的基本思想过程
① (29) (18 87 56 3 27)
② (18 29) (87 56 3 27)
③ (18 29 87) (56 3 27)
④ (18 29 56 87) (3 27)
⑤ ( 3 18 29 56 87) (27)
⑥ (3 18 27 29 56 87)
直接插入排序的代码
注意点:稳定性:稳定
时间复杂度: O(n^2)
#include <stdio.h>
void InsertSort(int a[], int k)
{
int i, j;
int tmp;
for (i = 1; i < k; i++)
{
temp = a[i];
for (j = i - 1; j >= 0; j--)
{
if (temp < a[j])
{
a[j + 1] = a[j];
}
else
{
break;
}
}
a[j + 1] = tmp;
}
}
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;
}
第二: 插入排序(希尔排序)(suju——》lesson6——》2.c)
例,序列 49 38 65 97 76 13 27 48 55 4 19 排序
13 27 48 55 4 19 38 65 97 76 40
希尔排序的代码
注意点:
时间复杂度:希尔排序的时间复杂性在O(nlog2n)和O(n2 )之间,大致为O(n1.3)。
稳定性:不稳定
#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;
}
第三 : 快速排序(suju——》lesson6——》3.c)
将 29 96 18 56 3 56 39 77 按由小到大排序
快速排序的代码
注意点:
稳定性:不稳定
平均时间复杂度: O(nlog2n)
#include <stdio.h>
void Sort(int array[], int low, int high)
{
int i, j;
int index;
if (low >= high)
{
return;
}
i = low;
j = high;
index = array[i];
while (i < j)
{
while (i < j && array[j] >= index)
{
j--;
}
if (i < j)
{
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;
}
第四 :简单选择排序(suju——》lesson6——》4.c)
将 29 18 87 56 3 27 按由小到大排序
简单选择排序的代码
注意点:
时间复杂度:总共比较 n(n-1)/2 次 ,移动次数最多n-1, 时间复杂度为O(n2)
稳定性:不稳定
#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;
}
第五: 堆排序(suju——》lesson6——》5.c)
堆排序思想:
- 将序列构造成一棵完全二叉树 ;
- 把这棵普通的完全二叉树改造成堆,便可获取最小值 ;
- 输出最小值 ;
- 删除根结点,继续改造剩余树成堆,便可获取次小值 ;
- 输出次小值 ;
- 重复改造,输出次次小值、次次次小值,直至所有结点均输出,便得到一个排序 。
堆排序的代码
注意点:
稳定性:不稳定
时间复杂度:O(nlogn)
#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;
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--)
{
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;
}
第六: 归并排序(suju——》lesson6——》6.c)
归并排序的代码
注意点:
平均时间复杂度: O(nlog2n)
稳定性: 稳定
#include <stdio.h>
#include <stdlib.h>
void Merge(int array[], int start, int middle, int end)
{
int i, j, k, n1, n2;
n1 = middle - start + 1;
n2 = end - middle;
int *L = (int *)malloc(n1 * sizeof(int));
int *R = (int *)malloc(n2 * sizeof(int));
for (i = 0, k = start; i < n1; i++, k++)
{
L[i] = array[k];
}
for (i = 0, k = middle + 1; i < n2; i++, k++)
{
R[i] = array[k];
}
for (k = start, i = 0, j = 0; i < n1 && j < n2; k++)
{
if (L[i] < R[j])
{
array[k] = L[i];
i++;
}
else
{
array[k] = R[j];
j++;
}
}
if (i < n1)
{
for (j = i; j < n1; j++, k++)
{
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;
}
第六:基数排序
基数排序(Radix Sorting)是一种借助多关键字排序的思想对单逻辑关键字进行关系的方法。基数排序不需要进行记录关键字间的比较。
主要分为两个过程:
(1)分配,先从个位开始,根据位值(0-9)分别放到0~9号桶中(比如53,个位为3,则放入3号桶中)
(2)收集,再将放置在0~9号桶中的数据按顺序放到数组中
基数排序的代码
注意点:
稳 定 性:稳定
时间复杂度:O(kn)(k表示整形的最高位)
空间复杂度:O(10n)
#include <stdio.h>
#include <stdlib.h>
int RadixCountSort(int *index, int *a, int len) //收集
{
int *count = (int *)malloc(sizeof(int) * 10);
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[cqdex[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 (a[i] / (radix_base / 10) > 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;
}