简单排序算法

     

目录

选择排序

冒泡排序

插入排序

三种简单排序算法的总结

       排序是计算机程序设计中的一种重要操作,它的功能是将一个数据元素(或记录)的cha任意序列,重新排列成一个关键字有序的序列。

选择排序

       选择排序就是对于一个任意的序列,从第一个元素开始,寻找整个序列中最小的元素放在第一个,然后从第二个元素开始,选取从第二个元素开始,到最后一个元素其中的最小值放在第二个位置,依次类推,对于n个元素,执行n-1次后,最后一个元素已经是最大值,不需要继续选择,所以这个过程一共执行了n-1次。

   public static void selectionSort(int[] arr) {
		if (arr == null || arr.length < 2) {//对于数组为空或者只有一个元素的数组直接返回
			return;
		}
		for (int i = 0; i < arr.length - 1; i++) {//外层循环为一共执行的次数,为n-1次
			int minIndex = i;//先定义每次循环的第一个开始元素为最小值
			for (int j = i + 1; j < arr.length; j++) {//在arr[i,n-1]中选择最小的元素
				minIndex = arr[j] < arr[minIndex] ? j : minIndex;//更新最小元素的位置
			}//其中那个三目运算符的含义为,如果?前面的表达式成立,结果就是后面冒号前面的值,否则就是冒号后面的值。
			swap(arr, i, minIndex);//找到最小值以后,交换二者位置。
		}
	}

	public static void swap(int[] arr, int i, int j) {
		int tmp = arr[i];
		arr[i] = arr[j];
		arr[j] = tmp;
	}//交换

       对于这个程序的时间复杂度进行分析,关注最深层循环的语句,两层循环,数量级达到O\left ( n^{2} \right ),而对于空间复杂度,不需要额外的空间,即空间复杂度为O\left ( 1 \right )。 

冒泡排序

      冒泡排序就是对于一个任意的序列,从第一个元素开始,两两比较,第一个和第二个元素比较,小的放在前面,第二个元素和第三个元素比较,小的放在前面,依次类推,经过第一轮比较,最大的元素排在最后一个位置,下次继续从第一个元素开始进行两两比较,最后一个元素不用比较,依次进行下去,进行n-1次后,第一个元素自然是最小的元素,故程序只需要执行n-1次。

public static void bubbleSort(int[] arr) {
	if (arr == null || arr.length < 2) {//处理数组元素为空或者只有一个元素的情况,直接返回
		return;
	}
	for (int i = 0;i < arr.length-1 i++) {//一共执行n-1次
		for (int j=0; j < arr.length-i-1; j++) {//比较次数,第一次循环比较n-1次,第二次循环比较n-2次,故而第m次循环比较n-m次
			if (arr[j] > arr[j + 1]) {//如果后面的元素比前面的元素小,进行交换
				swap(arr, j, j + 1);
			}
		}
	}
}

public static void swap(int[] arr, int i, int j) {
		int tmp = arr[i];
		arr[i] = arr[j];
		arr[j] = tmp;
}//交换两个位置的值

        对于这个程序的时间复杂度进行分析,关注最深层循环的语句,两层循环,数量级达到O\left ( n^{2} \right ),而对于空间复杂度,不需要额外的空间,即空间复杂度为O\left ( 1 \right )。 

       而对于这个过程,可以思考一下,如果经过仅有的几次排序已经达到有序,但是上面的这个程序依然还是会执行完所有的过程,浪费时间,所以我们可以对这个算法进行改进,即增加一个标志量,当某一次循环中没有执行比较,那么表示此时的序列已经有序,不需要继续执行后面的循环,此时对冒泡排序算法进行了优化。

        优化后的代码如下

public static void bubbleSort(int[] arr) {
	if (arr == null || arr.length < 2) {//处理数组元素为空或者只有一个元素的情况,直接返回
		return;
	}
	for (int i = 0;i < arr.length-1 i++) {//一共执行n-1次
        boolean flag=false;//对程序的比较过程进行标记
		for (int j=0; j < arr.length-i-1; j++) {//比较次数,第一次循环比较n-1次,第二次循环比较n-2次,故而第m次循环比较n-m次
			if (arr[j] > arr[j + 1]) {//如果后面的元素比前面的元素小,进行交换
				swap(arr, j, j + 1);
                flag=ture;
			}
		}
        if(flag==false){//如果没有进行交换,表示此时序列已经有序,直接返回
            return;
        }
	}
}

public static void swap(int[] arr, int i, int j) {
	int tmp = arr[i];
	arr[i] = arr[j];
	arr[j] = tmp;
}//交换两个位置的值

       对于改进后的程序,在实际应用中运行时间会有所降低,但是时间复杂度通常指的是最坏情况下需要的时间,所以时间复杂度并不会受到影响。

插入排序

       插入排序是对于一个任意的序列,从0~0开始使序列有序,0~0只有一个数字有序,然后是让0~1有序,第二个数字和前一个数字比较,如果比它小,那么和它交换,不小,那么有序,然后让0~2有序,让第三个数字依次与前一个数字比较,按照这个操作,对数组中的数字进行操作,最后0~n-1个数字全部有序。

public static void insertionSort(int[] arr) {
	if (arr == null || arr.length < 2) {
		return;
	}//对数组为空和只有一个元素的情况直接返回
    //0~0有序的
    //0~i想有序
	for (int i = 1; i < arr.length; i++) {//0~i做到有序
		for (int j = i - 1; j >= 0 && arr[j] > arr[j + 1]; j--) {
			swap(arr, j, j + 1);//对于刚进入循环,将i-1位置的数字,也就是i位置的前一个数字和它进行比较,如果比它大,那么两者交换,然后j-1,往前继续比较,直到新比较的i位置的数字找到比它小的数字,或者走到第一个位置前面没有数字,循环结束。
		}
	}
}

public static void swap(int[] arr, int i, int j) {
	int tmp = arr[i];
	arr[i] = arr[j];
	arr[j] = tmp;
}//交换两个位置的数

       这个程序的时间复杂度为O\left ( n^{2} \right ),间复杂度为O\left ( 1 \right )

       插入排序当新比较的数字和前一个进行比较时,如果比前一个数字大,那么已经有序,不会再往前面进行比较。在实际应用中算法的运行时间,会优于上面两种排序算法,使用更广泛。

三种简单排序算法的总结

        对于上面的三种排序算法,时间复杂度均为O\left ( n^{2} \right ),空间复杂度均为O\left ( 1 \right ),在使用中如果没有特殊要求优先使用插入排序。 

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

互联网的猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值