算法总结--排序(快排未写)

 

  算法第四版的简化的笔记!给自己看的

  数据,一个长度为n的无序数组

  api

  exch([]a,i,j) 交换数组i与j位置的元素

  less(i,j) 判断大小:数组元素i<j?true:false

一 选择排序 selection

  i=0;从i~n中选取最小值与i交换位置;i++ ;循环;

特点

  运行时间与输入无关(无论多么乱,或者元素全部一样) 排序时间是一样的。

  数据移动是最少的,每个元素只交换一次。

复制代码
public static void sort(Comparable[] a) {
        int n = a.length;
        for (int i = 1; i < n; i++) {
            int min = i;
            for (int j = i; j < n; j++) {
                if (less(a[j], a[min])) {
                    min = j;
                }
            }
            exch(a, i, min);
        }
    }
View Code
复制代码

 

二插入排序 insertion

  将i插入已排序的0~i 中合适的位置,i++;循环 

  插入方法:将i与i-1比较,小于则交换i与i-1;i--;循环;直到插入合适位置

特点

  接近有序的数组比乱序或逆序的要快得多

  适合小规模数组,或大规模数组的局部优化

改进

  插入方法不总是交换位置,直接找到位置,后面元素全部右移

  

复制代码
/**
     * 将a中lf-rt元素排序 不包括rt位置
     * 
     * @param a
     * @param lf
     * @param rt
     */
    public static void sort(Comparable[] a, int lf, int rt) {
        for (int i = lf + 1; i < rt; i++) {
            for (int j = i; j > lf && less(a[j], a[j - 1]); j--) {
                exch(a, j, j - 1);
            }
        }
    }
View Code
复制代码

 

三 希尔排序 shell

  类似插入排序,插入排序可视为增量h=1的情况。

  参数:增量h递减至1 (h可选,例子增量约等于n/3)

  将h,2h,3h。。

  h+i,2h+i,3h+i..n

  ...分别按插入排序

  h递减(例子增量为h/=3)

  循环,直至h<=1;

复制代码
public static void sort(Comparable[] a) {
        int N = a.length;
        // 增量
        int h = 0;
        while (h < N / 3)
            h = h * 3 + 1;
        while (h >= 1) {
            for (int i = h; i < N; i++) {
                for (int j = i; j >= h && less(a[j], a[j - h]); j -= h) {
                    exch(a, i, j);
                }
            }
            h /= 3;
        }
    }
View Code
复制代码

 

四归并排序 merge

  对于两叠已排序的纸牌,只需依次比较两叠中最顶一张,不断取较小的就行了

  归并分为两种 链表排序适合自下而上

1自上而下

  将n不断二分,类似二叉树,最后一个节点一个元素

  1,1合为2

  2,2合为4

  直至合为n

复制代码
public static void sort(Comparable[] a) {
        int n = a.length;
        Comparable [] aux = new Comparable[n];
        sort(a, 0, n - 1,aux);
    }

    private static void sort(Comparable[] a, int lf, int rt, Comparable[] aux) {
        if (lf >= rt)
            return;
        if((rt-lf)<=15){
            new Insertion().sort(a,lf,rt+1);
        }
        int mid = lf + (rt - lf) / 2;
        sort(a, lf, mid, aux);
        sort(a, mid + 1, rt, aux);
        if (less(a[mid], a[mid + 1]))
            return;
        else
            merge(a, lf, mid, rt, aux);
    }

    /**
     * 将lf-mid 和 mid+1-rt归并
     * 
     * @param a
     * @param lf
     * @param mid
     * @param rt
     * @param aux 
     */
    private static void merge(Comparable[] a, int lf, int mid, int rt, Comparable[] aux) {
        for (int i = lf; i <= rt; i++) {
            aux[i] = a[i];
        }
        int i = lf;
        int j = mid + 1;
        for (int k = lf; k <= rt; k++) {
            if (i > mid)
                a[k] = aux[j++];
            else if (j > rt)
                a[k] = aux[i++];
            else if (less(aux[i], aux[j]))
                a[k] = a[i++];
            else
                a[k] = a[j++];
        }
    }
View Code
复制代码

 

2自下而上

  直接将n化为1,类似n叉树

  1,1合为2。。。。直至合为n

原始排序:即将已排序子序列合并,需要一个临时数组拷贝两个子序列,然后排序至原始数组对应位置

改进:1当子序列长度小于某个值时,使用插入排序 ,比如长度为15

   2原始排序需要不断拷贝临时数组,可以再开始就一次性拷贝到辅助数组,直接排序到排序数组?减少复制时间 但不能减少空间

五快速排序 

  待续。。。。

posted on   初开  阅读(236)  评论(0编辑  收藏  举报

编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示