排序算法 2

136 阅读2分钟

常见的几种算法排序二 (学习笔记)

  • 冒泡排序
  • 选择排序
  • 插入排序
  • 希尔排序
  • 堆排序
希尔排序
  • 希尔排序(Shell's Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。该方法因 D.L.Shell 于 1959 年提出而得名。
  • 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至 1 时,整个文件恰被分成一组,算法便终止。 希尔排序原理图

image.png

image.png

void shellSort(int *L){
    int temp ,j;
    int increment = N;
    do{
        //定义增量
        increment = increment/2;
        for (int i = increment; i < N; i++) {
            if (L[i] < L[i - increment]) {
                temp = L[i];            
                //记录后移
                for (j = i-increment; j>=0 && temp < L[j]; j-=increment) {
                   L[j+increment] = L[j];
                }
                L[j + increment] = temp;
            }
        }             
    } while(increment > 1);
}
  • 堆排序

    堆结构体: 堆是具有下⾯面性质的完全⼆二叉树: 每个结点的值都⼤大于或等于其左右孩⼦子结点的值, 称为⼤大顶堆;如图; 或者每个结点的值都⼩小于等于其左右孩⼦子的结点的值,称为⼩小顶堆, 如图

image.png

如果按照层序遍历的⽅方式给结点从1开始编号,则结点之间的满⾜足如下关系

  • {Ki≥K2i Ki ≥ K2i+1

  • 或 {Ki≤K2i Ki ≤ K2i+1 1≤i≤n/2

  • 代码

//交换两个值

void swap(int *L,int i,int j){
    int temp;
    temp =L[i];
    L[i] = L[j];
    L[j] = temp;
}
//构成大顶堆
void HeapAjust(int *L,int s,int m){
    int temp = L[s];
    for (int i = s*2; i <= m; i*=2) {
        if (i < m&& L[i] < L[i+1]) {
            ++i;
        }
        if (temp >= L[i]) {
            break;
        }      
        L[s] = L[i];
        s = i;
    }
    L[s] = temp;
}
//堆排序
void HeapSort(int *L){
    int i;
    //将现有数据构成大顶堆
    for (i = N/2; i > 0; i--) {
        HeapAjust(L, i, N);
    }

    //将顶和最小值交换

    for (i = N ; i > 1 ; i--) {

        swap(L, 1, i);

        HeapAjust(L, 1, i-1);
    }
}