[Python+Java]-排序算法总结

参考链接

附:Java标准库已经内置了排序功能Arrays.sort(ns);

1.冒泡排序

思想:像气泡一样,小的冒上去

每一轮循环后,最小的一个数被交换到开始,因此,下一轮循环就可以“刨除”最开始的数,每一轮循环都比上一轮循环的结束位置靠后一位。

代码:

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[] ns = { 28, 12, 89, 73, 65, 18, 96, 50, 8, 36 };
        int tmp;
        // 排序前:
        System.out.println(Arrays.toString(ns));
        for(int i = 0; i < ns.length-1; i++) {//一共要进行n-1次比较
        	for(int j = ns.length-1; j > i; j--) {//每次要比较第ns.length-1到i的数
        		if(ns[j] < ns[j-1]){
        			tmp = ns[j];
        			ns[j] = ns[j-1];
        			ns[j-1] = tmp;
        		}
        	}
        }
        //排序后
        System.out.println(Arrays.toString(ns));
    }
}

算法分析:

  • 平均时间复杂度:o(n^2),嵌套双循环
  • 最好时间复杂度:o(n),如果数组有序,循环一次就可以了
  • 最坏时间复杂度:o(n^2)
  • 空间复杂度:o(1),只使用了常数空间
  • 稳定性:稳定(相同数字比较过程不会发生交换)

优化: 数据排好序后,冒泡算法仍会进行下一轮的比较,直到ns.length-1次结束。后面的比较是没有意义的。

可以设置标志位flag,如果发生了交换就设置flag为true,否则为false。

如果一轮交换后flag仍然为false说明数组已经有序,不需要再进行下去了。

public class Main {
    public static void main(String[] args) {
        int[] ns = { 28, 12, 89, 73, 65, 18, 96, 50, 8, 36 };
        int tmp;
        System.out.println(Arrays.toString(ns));
        for(int i = 0; i < ns.length-1; i++) {
        	boolean flag = false;//优化的地方[1]
        	for(int j = ns.length-1; j > i; j--) {
        		if(ns[j] < ns[j-1]){
        			tmp = ns[j];
        			ns[j] = ns[j-1];
        			ns[j-1] = tmp;
        			flag = true;
        		}
        	}
        	if(!flag) {//优化的地方[2]
        		System.out.println("数组在第"+(i+1)+"次排序后有序");
        		break;
        	}
        }
        System.out.println(Arrays.toString(ns));
    }
}

2.快速排序

思想(分治法):1.设置一个基准值(一般设置为数组第一个数),标签low和high。

2.从high开始,当high位置的书比基准值大,high--;比基准值小,把high位置的书放到low的位置,low++

low位置的数比基准值小,low++;比基准值大,把low 位置的数放到high,high--

直到low=high

(最后比基准值小的书都在它左边,比基准值大的数都在它右边)

3.对左右两个小数列重复第二步,直到各个区间都只有一个数

Java代码:

import java.util.Arrays;

public class Main {
	public static void main(String[] args) {
        int[] ns = { 28, 12, 89, 73, 65, 18, 96, 50, 8, 36 };
        // 排序前:
        System.out.println(Arrays.toString(ns));
        //排序
        QuickSort(0,ns.length-1,ns);
        //排序后
        System.out.println(Arrays.toString(ns));
	}
    public static void QuickSort(int low, int high, int[] ns) {
    	while(low < high) { //所以有传参的函数一定要先有个判断条件!!!!!
            int pivo = ns[low];//将第一个值作为基准赋给pivo暂存
            int slow = low;//记录本次排序的初始值(后面会发生改变)
            int shigh = high;
            while(low < high) {
                while(low < high && ns[high] >= pivo) {//左边
                	high--;     	
                }
                ns[low] = ns[high];
                while(low < high && ns[low] <= pivo) {//右边
                	low++;
                }
                ns[high] = ns[low];
            }
            ns[low] = pivo;
//            System.out.println("初始slow是 = "+slow+" , shigh是 = "+shigh+" ,基准值 = ns[" +slow+"] = "+pivo);
//            System.out.println("排序一趟后的基准位置low=high = ns["+low+"] = "+ns[high]);
//            System.out.println("最终排序结果: "+Arrays.toString(ns)+"\n");
//            System.out.println("上次排序结果: "+Arrays.toString(ns));
            QuickSort(slow,low-1,ns);
            QuickSort(low+1,shigh,ns);
    	}
    }
}

Python代码:

def partition(arr,low,high):
    pivot = arr[low]
    while (low < high):
        while arr[high] > pivot and low < high:
            high -=1
        arr[low] = arr[high]
        while arr[low] < pivot and low < high:
            low += 1
        arr[high] = arr[low]
    arr[high] = pivot
    return high
def quicksort(arr, low, high):
    if low < high:
        next = partition(arr, low, high);
        quicksort(arr, low, next-1)
        quicksort(arr, next+1, high)

arr = [8,6,1,9,4,5,10,14,3]
length = len(arr)-1
quicksort(arr, 0, length)
print(arr)

算法分析:

先说主定理:  T(n)=aT(\frac{n}{b})+f(n)

(a>=1,b>1) 其中a是划分后的子问题数,b是划分后问题的规模。对于快速排序,a=b=2

f(n)=O(n)是划分问题的时间复杂度,快速排序为n

所以快速排序公式T(n)=2T(\frac{n}{2})+n然后迭代计算,随后第\log _2 n次划分时 = 后的哪一项只有一个T(1)=1了,此时T(n)=n+n*\log _2

所以平均时间复杂度为O(n*\log _2 n)

 

参考链接

最好的情况:快速排序的性能取决于快速排序递归树。递归算法执行情况可以用递归树来描述。

下图是数组{50,10,90,30, 70,40,80,60,20}在快速排序的递归过程,枢轴值是50正好递归树是平衡的,性能比较好。

在最优情况下,Partition每次都划分得很均匀,如果排序n个关键字,其递归树的深度就为.log2n.+1

 

最坏情况:

在最坏的情况下,待排序的序列为正序或者逆序,每次划分只得到一个比上一次划分少一个记录的子序列,注意另一个为空。如果递归树画出来,它就是一棵斜树。此时需要执行n‐1次递归调用,且第i次划分需要经过n‐i次关键字的比较才能找到第i个记录,也就是枢轴的位置,因此比较次数为 ,最终其时间复杂度为O(n2)。

另一种说法:T[n] = T[n-1] + T[1] + O(n),

问题来了,这一次的划分白玩了,划分之后一边是一个,一边是n-1个,这种极端情况的时间复杂度就是O(n2).

 

3.堆排序

思想:

代码:

算法分析:

优化:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕业设计,基于SpringBoot+Vue+MySQL开发的公寓报修管理系统,源码+数据库+毕业论文+视频演示 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本公寓报修管理系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息,使用这种软件工具可以帮助管理人员提高事务处理效率,达到事半功倍的效果。此公寓报修管理系统利用当下成熟完善的Spring Boot框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的MySQL数据库进行程序开发。公寓报修管理系统有管理员,住户,维修人员。管理员可以管理住户信息和维修人员信息,可以审核维修人员的请假信息,住户可以申请维修,可以对维修结果评价,维修人员负责住户提交的维修信息,也可以请假。公寓报修管理系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。 关键词:公寓报修管理系统;Spring Boot框架;MySQL;自动化;VUE
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值