7种排序算法

118 阅读2分钟

首先定义一些辅助代码,结构体,方法等

#define status int
#define MAXSIZE 10000
typedef struct {
    int r[MAXSIZE+1]; //r[0] 哨兵
    int length;
}Sqlist;

void swap(Sqlist *L,int i,int j){
    int temp = L->r[i];
    L->r[i] = L->r[j];
    L->r[j] = temp;
}
void print(Sqlist L){
    int i;
    for (i = 1; i<L.length; i++) {
        printf("%d\n",L.r[i]);
    }
}

一:冒泡排序

void BubbleSort1(Sqlist *L){
    int i,j;
    status flag = 1;
    for (int i = 1; i<L->length && flag; i++) {
        flag = 0;
        for (j = i; j<L->length; j++) {
            if (L->r[j] > L->r[j+1]) {
                swap(L, j, j+1);
                flag = 1;// 当做了交换说明下一轮可以继续比较,一旦没有进行交换 说明已经有序 flag = 0,不需要进入该循环
            }
        }
    }
}

二:选择排序

void selectSort(Sqlist *L){
    int i,j,min;
    for (i = 1; i<L->length; i++) {
        min = i;
        for (j=i+1; j<L->length; j++) {
            if (L->r[min]>L->r[j]) {
                min = j; //记录下标 循环过后再交换
            }
        }
        if (i!=min) {
            swap(L, i, min);
        }
    }
}

三:直接插入排序

void insertsort(Sqlist *L){
    int i,j;
    int temp = 0; //保存中间变量
    for (i = 2; i<L->length; i++) {
        if (L->r[i] < L->r[i-1]) { // 才进行插入,否则不需要改变顺序
            temp = L->r[i];
            // 因为是循序表 需要移动位置
            for (j = i-1; L->r[j] > temp; j--) {
                L->r[j+1] = L->r[j];// 依次向右移动
            }
            L->r[j+1] = temp; // 把temp 放在正确的位置上
        }
    }
}

四:希尔排序

void shellSort(Sqlist *L){
    int i,j;
    int increment = L->length;
    // 0 9 8 3 4 6 2 1 5 7
    do {
        increment = increment/3+1; // 增量
        // 插入排序
        for (i = increment + 1; i <= L->length; i++) {
            if (L->r[i] < L->r[i-increment]) {
                L->r[0] = L->r[i]; //L->r[0] 哨兵 相当于临时变量 temp
                for (j = i-increment; j>0 && L->r[0] <L->r[j]; j-= increment) {
                    L->r[j+increment] = L->r[j];
                }
                L->r[j+increment] = L->r[0];
            }
        }
    } while (increment > 1);
}

五:堆排序

// 将一个无序序列构建一个大顶堆
void HeapAjust(Sqlist *L,int s,int m){
    // 类似于选择排序
    int temp,j;
    temp = L->r[s];
    for (j = 2*s; j<= m; j*=2) {
        //2s 左孩子
        if(j<m && L->r[j] < L->r[j+1]){
            ++j; //右孩子大
        }
        if (temp >= L->r[j]) {
            break; //如果定点大于左孩子/右孩子
        }
        L->r[s] = L->r[j];
    }
    L->r[j] = temp;
}
// 大顶堆排序
// 时间复杂度 o(nlogn)
void HeapSort(Sqlist *L){
    int i;
    //构建大顶堆
    for (i = L->length/2; i>0; i--) {
        HeapAjust(L, i, L->length);
    }
    // 找到最后一个元素,和 1 进行交换
    for (i = L->length; i>1; i--) {
        swap(L, 1, i);
        HeapAjust(L,1,i-1); //构建大顶堆
    }
}

六:归并排序

// 归并
//SR[] 待排序
//TR[] 已排序
// i:low
// m:中间值
// n:high
void Merge(int SR[],int TR[], int i,int m, int n){
    int j=0,k=0,l=0;
    for (j = m+1,k = i; j<=n && i<=m; k++) {
        if (SR[i]<SR[j]) {
            TR[k] = SR[i++]; //先赋值后 i进行 +1
        } else
            TR[k] = SR[j++];
    }
    // 如果两个数组不一样长
    if(i<m){
        for (l=0; l<=m-i; l++) {
            TR[k+1] = SR[i+1];
        }
    }
    if (j<=n) {
        for (l=0; l<=n-j; l++) {
            TR[k+1] = SR[j+1];
        }
    }
}

//SR 待排序数组
//TR1 排序后的有序数组
//low 低位
//high 高位
// 拆分
void MSort(int SR[],int TR1[], int low, int high) {
    int mid;
    int SR2[MAXSIZE +1];
    if (low == high) {
        TR1[low]=SR[high];
    } else {
        mid = (low+high)/2;
        MSort(SR, SR2, low, mid); //递归
        MSort(SR, SR2, mid+1, high);
        // 归并
        Merge(SR2, TR1, low, mid, high);
    }
}

七:快速排序

int Partition(SqList *L,int low,int high){
    int pivotkey;
    //pivokey 中轴
    pivotkey = L->r[low];
    while (low < high) {
        while (low < high &&  L->r[high] >= pivotkey)
            high--;
        swap(L, low, high);
        while (low < high && L->r[low] <= pivotkey)
            low++;
        swap(L, low, high);
    }
    //返回枢轴pivokey 所在位置;
    return low;
}

// 对顺序表L的子序列L->r[low,high]做快速排序;
void QSort(SqList *L,int low,int high){
    int pivot;
    if(low < high){
        pivot = Partition(L, low, high);
        printf("pivot = %d L->r[%d] = %d\n",pivot,pivot,L->r[pivot]);
        QSort(L, low, pivot-1);
        QSort(L, pivot+1, high);
    }
}