排序算法

排序算法

排序是计算机程序设计中的一种重要操作,它的功能是将一个数据元素的任意序列,重新排列成一个按关键字有序的序列。根据排序过程中涉及的存储器不同,可以将排序算法分为内部排序,外部排序。在排序算法中,通常涉及两种操作,一比较关键字大小,二是移动。下面主要讨论下内部排序的几种常见算法。

一 冒泡排序

  1. 冒泡排序的过程是首先将第一个记录的关键字和第二个记录的关键字比较,如果两个关键字逆序L.r[1].key > L.r[2].key.交换位置。然后依次类推。直到n-1 和 n 和记录比较。上面的过程称为第一趟排序,结果是Key 值最大的记录项放到最后
  2. 然后进行第二趟排序。第二趟排序是从第1个记录项到第n-1个。第i趟排序是从第一个到第n-i个。
  3. 判断排序完成的标记是在第i趟排序中没有发生记录位置的改变。这样每趟排序比较了最多n-1 次,一共进行了n次。算法时间复杂度为O(n*n).在排序的过程中,从竖直方向上看,最小的像气泡一样的浮出来,最大的像石块一样沉入水底。因此称之为冒泡排序。
Java 代码实现整形数组排序。
    static void BubbleSort(int args[]){
        int len = args.length;
        for (int j = 0; j < len; j++) {
            for (int i = 0; i < len - j - 1; i++) {
                System.out.println(i);

                if (args[i] > args[i + 1]) {
                    int temp = args[i];
                    args[i] = args[i + 1];
                    args[i + 1] = temp;
                }
            }
        }
        for(int k = 0; k < len; k++){
            System.out.print(args[k] + " ");
        }
        System.out.println();
    }

    根据排序完成的条件,如果排序已经完成,不再循环。优化的排序

    static void BubbleSort(int args[]){
        int len = args.length;
        boolean change = false;
        for (int j = 0; j < len - 1; j++) {
            change = false;
            for (int i = 0; i < len - j - 1; i++) {
                System.out.println(i);

                if (args[i] > args[i + 1]) {
                    int temp = args[i];
                    args[i] = args[i + 1];
                    args[i + 1] = temp;
                    change = true;
                }
            }

            if(change == false)
                break;
        }
        for(int k = 0; k < len; k++){
            System.out.print(args[k] + " ");
        }
        System.out.println();
    }

二 快速排序

1.选择一个基准元素,通常选择第一个元素
2.通过一趟排序将待排序的记录分割成独立的两部分,其中一部分记录的元素值均比基准元素值小。另一部分记录的 元素值比基准值大。
3. 然后分别对这两部分记录用同样的方法继续进行排序,直到剩余一个子序列无法排序。

static int parpation(int[] array, int l, int h){
        int temp = array[l];
        while(l < h){
            while (l < h && array[h] >= temp)
                h--;

            array[l] = array[h];
            array[h] = temp;


            while(l < h && array[l] <= temp)
                l++;

            array[h] = array[l];
            array[l] = temp;    
        }

        return l;

    }

    static void quickSort(int [] array, int l, int h){
        if (l < h) {
            int cursor = parpation(array, l, h);
            quickSort(array, l, cursor - 1);
            quickSort(array, cursor + 1, h);
        }

        for (int k = l; k < h - l + 1; k++) {
            System.out.print(array[k] + " ");
        }
        System.out.println();

    }

三 直接插入插入排序

  1. 插入排序是将一个记录插入到前面已经排好的有序序列中。
  2. 第一步首先第一个记录为一个有序序列。从第二个元素开始,将第二个元素插入到前面的序列中。
  3. 第i元素 首先比较下 第i个记录和第i-1个记录的大小,i-1 < i。不用交换,如果i-1 > i ,则将i 插入到前面的有序队列中.插入操作首先临时记录第i个元素temp,同时记录j=i,然后第j-1个元素大于temp,j-1 后移, 否则插入。时间复杂度O(n*n)
static void insertionSort(int[] array){
    int len = array.length;
    for(int i = 1; i < len; i++){
        if(array[i-1] > array[i]){
            int j = i;
            int temp = array[i];
            for(j = i;j > 0 && array[j-1] > temp; j--){
                array[j] = array[j-1];
            }
            array[j] = temp;
        }
    }

    for(int k = 0; k <  array.length; k++){
        System.out.print(array[k] + " ");
    }
    System.out.println();
}

四 希尔排序

整体思想是:在直接插入排序的时候如果序列为有序的,那么一次插入排序循环即可完成排序,时间复杂度为:O(n),也就是说如果序列的混乱度比较低,那么直接排序可以大大提高性能;直接插入排序在n比较小的时候,效率也比较高。因此希尔排序是 先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。

  1. 选择一个增量序列t1,t2,…,tk,其中ti>t(i-1),tk=1;需要注意:增量因子中除1 外没有公因子,且最后一个增量因子必须为1。。
  2. 每趟排序,根据对应的增量因子ti,将待排序列分割成若干长度为ti 的子序列,分别对各子序列进行直接插入排序。仅增量因子为1 时,整个序列作为一个序列来处理,直接插入排序一次完成排序。
  3. 根据增量因子做循环
static void shellInsert(int[] array, int dl){
        for(int i = dl; i < array.length; i++){
            if(array[i - dl] > array[i]){
                int j = 0;
                int temp = array[i];
                for(j = i; j - dl >= 0 && array[j-dl] > temp; j -= dl){
                    array[j] = array[j-dl];
                }   
                array[j] = temp;
            }   
        }

    }

    static void shellSort(int[] array, int[]dl){
        for(int i = 0; i < dl.length; i ++){
            shellInsert(array, dl[i]);
        }

        for (int k = 0; k < array.length; k++) {
            System.out.print(array[k] + " ");
        }
        System.out.println();
    }

五 简单选择排序

选择排序的基本思想是:每一趟在后边n-i+1 的个记录中选出最小的元素,和n-i+1 的第一个元素交换。算法复杂度为O(n*n)

    public static void selectionSort(int[] array) {  
        for(int i = 0; i < array.length - 1; i++) {  
            int min = i;  
            for(int j = i + 1; j < array.length; j++) {  
                if(array[j] < array[min]) {  
                    min = j;  
                }  
            }  
            if(min != i) {  
                int temp = array[min];  
                array[min] = array[i];  
                array[i] = temp;  
            }  
        }

        for(int k = 0; k <  array.length; k++){
            System.out.print(array[k] + " ");
        }
        System.out.println();
    }

六 堆排序

堆的原理就是完全二叉树。设计到两个问题:
1. 如何将无序序列建成堆;
2. 输出堆顶元素后,怎样调整剩余n-1 个元素,使其成为一个新堆。

无序序列建堆采用渗透法反复渗透,在完全二叉树中,最后一个有子节点的节点为 n/2。
首先在这个节点建堆,然后依次向上渗透。

输出堆顶元素后,就是把堆顶元素和刚调整的堆的最后一个元素交换,这样最大的元素在栈顶,进行依次渗透排序即可。

 static void headAdjust(int[] array, int node, int len){

        int temp = array[node];
        for(int j = 2*node+1 ; j < len; j = j*2 +1){
            if( j + 1 < len && array[j] < array[j+1]) j++;
            if(array[node] > array[j]) break;
            array[node] = array[j];
            array[j] = temp;
            node = j;
        }
    }

    static void heapSort(int[] array){
        int len = array.length;
        for(int i = (len -1) / 2; i >= 0; i-- ){
            headAdjust(array, i, len);
        }

        for(int i = len -1; i > 0; i--){
            int temp = array[0];
            array[0] = array[i];
            array[i] = temp;

            headAdjust(array, 0, i);    
        }

        for (int k = 0; k < array.length; k++) {
            System.out.print(array[k] + " ");
        }
        System.out.println();
    }
基于开源大模型的教学实训智能体软件,帮助教师生成课前备课设计、课后检测问答,提升效率与效果,提供学生全时在线练习与指导,实现教学相长。 智能教学辅助系统 这是一个智能教学辅助系统的前端项目,基于 Vue3+TypeScript 开发,使用 Ant Design Vue 作为 UI 组件库。 功能模块 用户模块 登录/注册功能,支持学生和教师角色 毛玻璃效果的登录界面 教师模块 备课与设计:根据课程大纲自动设计教学内容 考核内容生成:自动生成多样化考核题目及参考答案 学情数据分析:自动化检测学生答案,提供数据分析 学生模块 在线学习助手:结合教学内容解答问题 实时练习评测助手:生成随练题目并纠错 管理模块 用户管理:管理员/教师/学生等用户基本管理 课件资源管理:按学科列表管理教师备课资源 大屏概览:使用统计、效率指数、学习效果等 技术栈 Vue3 TypeScript Pinia 状态管理 Ant Design Vue 组件库 Axios 请求库 ByteMD 编辑器 ECharts 图表库 Monaco 编辑器 双主题支持(专业科技风/暗黑风) 开发指南 # 安装依赖 npm install # 启动开发服务器 npm run dev # 构建生产版本 npm run build 简介 本项目旨在开发一个基于开源大模型的教学实训智能体软件,帮助教师生成课前备课设计、课后检测问答,提升效率与效果,提供学生全时在线练习与指导,实现教学相长。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值