包含:插入排序(直接插入排序)
插入排序
直接插入排序
void InsertSort(ElemType A[] , int n){
for(int i = 2 ; i <= n ; i ++){
if(A[i].key < A[i - 1].key){
A[0] = A[i]; // 先把数字放在A[0]里面
for(int j = i - 1 ; A[0].key < A[j].key ; j --){ // 从后往前查找,如果有数字比它大,那就把数字往后移//
A[j + 1] = A[j];
}
A[j + 1] = A[0]; // 在这个位置上把数字插进去//
}
}
}
折半插入排序
void InsertSort(ElemType A[] , int n){
for(int i = 2 ; i <= n ; i ++){
A[0] = A[i]; // 暂时把这个数值放在第0号位置上
int low = 1 ; high = i - 1;
//查找:把后半部分的数值往前插,只是前面的插入是用折半做的
while(low <= high){
int mid = (low + high) / 2;
if(A[mid].key > A[0].key)
high = mid - 1;
else
low = mid + 1;
}
for(int j = i - 1 ; j >= high + 1 ; j --){ // 从high + 1到 i - 1都向后移动一位
A[j + 1] = A[j];
}
A[high + 1] = A[0]; // 在high + 1的地方插入数据,不是mid
}
}
时间复杂度没变,只是比较次数变了。
希尔排序
void ShellSort(ElemType A[] , int n){
for(int d = n / 2 ; d >= 1 ; d /= 2){ // 每次d的数值都是原先的1/2,但是最后一次必须得是1
for(int i = d + 1 ; i <= n ; i ++){ // 依次循环
if(A[i].key > A[i - d].key){
A[0] = A[i]; // 相当于一个temp
int j;
for(j = i - d ; j > 0 && A[0].key < A[j].key ; j -= d){ // 确定移动的范围和长度
A[j + d] = A[j];
}
A[j + d] = A[0]; // 多减了一个d的值
}
}
}
}
交换排序
冒泡排序
void BubbleSort(ElemType A[] , int n){
for(int i = 0 ; i < n - 1 ; i ++){ // 只用循环n-1次,每次必有一个已经有序
bool flag = false;
for(int j = n - 1 ; j > i ; j --){ // [a , b]的数字个数是 b - a + 1
if(A[j - 1].key > A[j].key){
ElemType temp = A[j].key;
A[j].key = A[j - 1].key;
A[j - 1].key = temp;
flag = true; // 出现过变动
}
}
if(flag == false) // 未出现过变动,则已经有序
return ;
}
}
快速排序
int Part(ElemType A[] , int low , int high){
ElemType pivot = A[low];
while(low < high){
while(low < high && A[high] >= pivot){
high --; // 从右边开始,碰到比轴小的就和轴换位置
}
A[low] = A[high];
while(low <high && A[low] <= pivot){
low ++; // 从左边开始,碰到比轴大的就和轴换位置
}
A[high] = A[low];
}
A[low] = pivot; // 当轴位置确定好之后,再去将数字放进去
return low;
}
void QuickSort(ElemType A[] , int low , int high){
int p = Part(A , low , high);
QuickSort(A , low , p - 1); // 前半部分
QuickSort(A , p + 1 , low); // 后半部分
}
选择排序
简单选择排序
void SelectSort(ElemType A[] , int n){
for(int i = 0 ; i < n - 1 ; i ++){ // 与冒泡排序类似,最后一个值最后自然可以确定
min = i;
for(int j = i + 1 ; j < n ; j ++){ // 从当前排序的后面找到一个最小值进行交换
if(A[j] < min)
min = j; // 先将下标保存
}
if(min != i) // 如果不是当前的数值,则swap
swap(A[i] , A[min]);
}
}
堆排序
//占坑
归并排序
ElemType *B = (ElemType *)malloc((n + 1) * sizeof(*ElemType));
void Merge(ElemType A[] , int low , int mid , int high){
for(int i = 0 ; i < high ; i ++){ // 将所有的数据放在这个辅助数组中
B[i] = A[i];
}
for(int i = low , j = mid + 1 , k = i ; i <= mid && j <= high ; k ++){ // i和j分头开始搜索,当比另外一个大的时候就切换
if(B[i] <= B[j]){
A[k] = B[i ++];
}
else{
A[k] = B[j ++];
}
}
// 未填满的部分赋值下来
while(i <= mid) A[k ++] = A[i ++];
while(j <= high) A[k ++] = A[j ++];
}
void MergeSort(ElemType A[] , int low , int high){
if(low < high){
int mid = (low + high) / 2;
MergeSort(A , low , mid); // 先对前半部分做排序
MergeSort(A , mid + 1 , high); // 后半部分做排序
Merge(A , low , mid , high); // 再将两个部分合并
}
}