排序方法的分类:
按存储介质可分为
·内部排序:数据量不大,数据在内存,无需内外存交换数据
·外部排序:数据量较大,数据在外存
按比较器个数可分为
·串行排序:单处理机(同一时刻比较一对元素)
·并行排序:多处理机(同一时刻比较多对元素)
按主要操作可分为
·比较排序:
插入排序、交换排序、选择排序、归并排序
·基数排序:
不比较元素大小,仅仅根据元素本身的取值确定其有序位置
按稳定性可分为:
·稳定排序:数值相同的元素经过排序后相对位置不发生变化
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define MaxSize 20
typedef struct {
int key;//关键字
//···其他数据
}Data;
typedef struct {
int length;
Data arr[MaxSize + 1];//由于加入了哨兵,故数组元素个数加一
}Datalist;
/*直接插入法:令一顺序表分为有序和无序两部分,将无序部分依次按照顺序查找法插入进有序部分*/
Datalist InlineInsertionBySS(Datalist L) {//顺序排列
for (int i = 2; i <= L.length; i++) {
if (L.arr[i].key < L.arr[i - 1].key) {//首先判断数组关键字从哪开始无序
L.arr[0] = L.arr[i];
for (int j = i; L.arr[j].key < L.arr[j - 1].key; j--) {
L.arr[j] = L.arr[j - 1];
L.arr[j - 1] = L.arr[0];
}
}
}
return L;
}
/*通过折半查找的直接插入法*/
Datalist InlineInsertionByBS(Datalist L) {
for (int i = 2; i <= L.length; i++) {
if (L.arr[i].key < L.arr[i - 1].key) {
L.arr[0] = L.arr[i];
int low = 1, high = i - 1, mid;
while (low <= high) {
mid = (high + low) / 2;
if (L.arr[mid].key > L.arr[0].key)
high = mid - 1;
else
low = mid + 1;
}
for (int j = i - 1; j >= high + 1; j--) {//在开始插入前先将要插入位置后的元素依次后移
L.arr[j + 1] = L.arr[j];
}
L.arr[mid] = L.arr[0];
}
}
return L;
}
/*希尔排序*/
void ShellInsert(Datalist* L, int k) {
for (int i = k + 1; i < L->length; i++) {
if (L->arr[i].key < L->arr[i - k].key) {
L->arr[0] = L->arr[k];
for (int j = i; L->arr[j].key < L->arr[j - k].key && j > 0; j -= k) {
L->arr[j] = L->arr[j - k];
L->arr[j - k] = L->arr[0];
}
}
}
}
void ShellSort(Datalist* L, int dlta[], int k) {
for (k; k > 0; k--) {
ShellInsert(L, dlta[k]);
}
}
/*快速排序---交替式排序
特点:
不具备稳定性且不适于原本有序或基本有序的顺序表
*/
void QuickSort(Datalist* L, int start, int end) {
int low = start, high = end;
if (low >= high)
return;
L->arr[0] = L->arr[low];
int pivotkey = L->arr[low].key;
while (low < high) {
while (low < high && pivotkey <= L->arr[high].key)
high--;
while (low < high && pivotkey > L->arr[low].key)
low++;
}
L->arr[low] = L->arr[0];
QuickSort(L, low + 1, end);
QuickSort(L, start, high - 1);
}