1、分类
2、时间复杂度
3、详细阐述
(1) 冒泡排序
从下往上两两比较,如果有n个元素需要比较n-1次,每一轮减少1次比较。
void BubbleSort(int k[], int n) {
for (int i = 0; i < n - 1; i++)
for (int j = i + 1; j < n; j++)
if (k[i] > k[j]) {
int temp = k[i];
k[i] = k[j];
k[j] = temp;
}
}
void BubbleSort(int k[], int n) {
for (int i = 0; i < n - 1; i++)
for (int j = n - 1; j > i; j--)
if (k[j - 1] > k[j]) {
int temp = k[j - 1];
k[j - 1] = k[j];
k[j] = temp;
}
}
void BubbleSort(int k[], int n) {
int flag = 1;
for (int i = 0; i < n - 1 && flag; i++)
for (int j = n - 1; j > i; j--) {
flag = 0;
int temp = k[j - 1];
k[j - 1] = k[j];
k[j] = temp;
}
}
(2) 选择排序:比较第一个元素与后续元素做比较,小放前面
void SelectSort(int k[], int n) {
for (int i = 0; i < n - 1; i++) {
int min = i;
for (int j = i + 1; j < n; j++) {
if (k[j] < k[min]) min = j;
}
if (min != i) {
int temp = k[min];
k[min] = k[i];
k[i] = temp;
}
}
}
(3) 直接插入排序:假定前i个构成的子序列是处于已排序的情况下进行排序的,然后将第i个元素与前i构成的子序列逆序进行比较,如果是要升序排序,则比较第i个元素是否比j=i-1(i-1需要>=0)的元素大,如果是则第i个元素的位置(即j+1的位置上)保持不动,反之则将j=i-1的元素放置到i的位置,再进行第i个元素与j=i-2(i-2需要>=0)的,依次进行,如果第i个元素刚好比j=i-3大,则将第i个元素插入到j=i-2(即j+1的位置)上。
void InsertSort(int k[], int n) {
for (int i = 1; i < n; i++)
if (k[i] < k[i - 1]) {
int temp = k[i];
for (j = i - 1; k[j] > temp; j--) k[j + 1] = k[j];
k[j + 1] = temp;
}
}
(4) 希尔排序
把记录按步长gap分组,对每组记录采用直接插入顺序方法进行排序。随着步长逐渐减少,所分成的组包含的记录越來越多,当步长的值减少到1时,整个数据合成为一组,构成一组有序记录,则完成排序。
void InsertSort(int k[], int n) {
int i, j, temp;
int gap = n;
do {
gap = gap / 3 + 1;
for (i = gap; i < n; i++) {
if (k[i] < k[i - gap]) {
temp = k[i];
for (j = i - gap; k[j] > temp; j -= gap) k[j + gap] = k[j];
k[j + gap] = temp;
}
}
} while (gap > 1);
}
(5) 堆排序
根结点一定是堆中所有结点最大或最小者,如果按照层序遍历的方式给结点从1开始编号。
ki >=k2i且ki>=k2i+1、ki<=k2i且ki<=k2i+1;下标i与2i和2i+1是双亲和子女关系。
void swap(int k[], int i, int j) {
int temp;
temp = k[i];
k[i] = k[j];
k[j] = temp;
}
void HeapAdjust(int k[], int s, int n) {
int i, temp;
temp = k[s];
for (i = 2 * s; i <= n; i *= 2) {
if (i < n && k[i] < k[i + 1]) i++;
if (temp >= k[i]) break;
k[s] = k[i];
s = i;
}
k[s] = temp;
}
void HeapSort(int k[], int n) {
int i;
for (i = n / 2; i > 0; i--) HeapAdjust(k, i, n);
for (i = n; i > 1; i--) {
swap(k, 1, i);
HeapAdjust(k, 1, i - 1);
}
}
(6) 归并排序
利用归并的思想实现的排序方法。假设初始序列有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,如此重复,直至得到一个长度为n的有序序列为止,这种排序方法称为2路归并排序。
#define MAXSIZE 10
void merging(int *list1, int list1_size, int *list2, int list2_size) {
int i, j, k, m;
int temp[MAXSIZE];
i = j = k = 0;
while (i < list1_size && j < list2_size) {
if (list1[i] < list2[j])
temp[k++] = list1[i++];
else
temp[k++] = list2[j++];
}
while (i < list1_size) temp[k++] = list1[i++];
while (j < list2_size) temp[k++] = list2[j++];
for (m = 0; m < (list1_size + list2_size); m++) list1[m] = temp[m];
}
void MergeSort(int k[], int n) {
if (n > 1) {
int *list1 = k;
int list1_size = n / 2;
int *list2 = k + n / 2;
int list2_size = n - list1_size;
MergeSort(list1, list1_size);
MergeSort(list2, list2_size);
merging(list1, list1_size, list2, list2_size);
}
}
(7) 快速排序
首先在要排序的序列a中选取一个中轴值,而后将序列分成两个部分,其中左边的部分b中的元素均小于或者等于中轴值,右边的部分c的元素均大于或者等于中轴值,而后通过递归调用快速排序的过程分别对两个部分进行排序,最后将两部分产生的结果合并即可得到最后的排序序列。
void swap(int k[], int low, int high) {
int temp;
temp = k[low];
k[low] = k[high];
k[high] = temp;
}
int Partition(int k[], int low, int high) {
int point;
point = k[low];
while (low < high) {
while (low < high && k[high] >= point) high--;
swap(k, low, high);
while (low < high && k[low] <= point) low++;
swap(k, low, high);
}
return low;
}
void QSort(int k[], int low, int high) {
int point;
if (low < high) {
point = Partition(k, low, high);
QSort(k, low, point - 1);
QSort(k, point + 1, high);
}
}
void QuickSort(int k[], int n) { QSort(k, 0, n - 1); }