排序算法简单涉及

1、算法复杂度

2、稳定性

3、适用场景

4、对应的Java代码

分析来源:以下面几个排序为例

一、冒泡排序

特点:简单的排序算法;它会遍历若干次要排序的数列,每次遍历时,它都会从前往后依次比较相邻两个数的大小;判定--如果前者比后者大,则交换它们的位置(升序)。这样一次遍历之后,最大的元素在数列末尾!循环--采用相同的方法再次遍历时,第二大元素被排列在最大元素之前。目标--重复此操作,直到整个数列都有序为止!

理解:冒泡(由于气压原因,相邻的两个气泡,后者比前者大);遍历若干次(得到最终结果需要重复执行多次);

Java代码--以函数的形式(优化)--优化

package sort;

import java.util.Random;

public class Bubbling {

	public static void main(String[] args) {

		bubling();
	}

	private static void bubling() {
		Random rd = new Random();// Random普通的类(不是工具类)

		// 测试:函数的形式

		int[] array = new int[10];
		// 随机产生整数

		for (int i = 0; i < array.length; i++) {

			array[i] = rd.nextInt(100);// [0,100)
			// 遍历结果
			System.out.print(array[i] + " ");
		}
		
		System.out.println();

		for (int i = array.length - 1; i > 0; i--) { //每次都是确定最后一个


			// 定义标示位--每次遍历(一趟)都可能发生变化
			boolean flag = true;

			// 开始进行一次排序
			for (int j = 0; j < i; j++) {

				int temp = 0;// 临时变量
				// 体现相邻
				if (array[j] > array[j + 1]) {
					// 互换位置--三种方式(最常用的)
					temp = array[j];
					array[j] = array[j + 1];
					array[j + 1] = temp;
					// 交换位置说明次序变化了(只要有一次就OK)
					flag = false;
				}
			}

			// 若无交换,说明数据已经有序,直接跳出冒泡排序算法
			if (flag == true) {
				break;
			}
		}
		for (int i = 0; i < array.length; i++) {

			System.out.print(array[i] + " ");
		}
	}
}

时间复杂度:O(n^2);理解--被排序的数列中有n个数。遍历一趟的算法复杂度为O(n),需要遍历(n-1)次!因此,冒泡排序的时间复杂度为O(n^2)

算法的稳定性:稳定

算法稳定性的解释:一个数列中有两个相等的数a[i]=a[j],在排序前,a[i]在a[j]前面,经过排序后a[i]仍然在a[j]前,排序算法稳定

思考:如果是降序呢?--简单修改

二、选择排序

基本思想:起始--在未排序的数列中找到最大(小)值,然后将其存放到数列的起始位置;过程--接着再从剩余未排序的元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。目标--以此类推,直到所有的元素均排序完毕

注意:并未提到相邻的元素

代码

package sort;

import java.util.Random;

public class Select {

	public static void main(String[] args) {
		
		select();
		
	}

	
	private static void select() {
		//产生数据
		Random rd = new Random();
		int [] array=new int[20];
		for(int i=0;i<array.length;i++){
			array[i]=rd.nextInt(20);
			System.out.print(array[i]+" ");
		}
		
		System.out.println();
		
		//升序排列(注意一些细节)--只剩最后一个则无需排序了,所以是array.length-1
		for(int i=0;i<array.length-1;i++){
			for(int j=i+1;j<array.length;j++){
				//比较,互换位置
				int temp=0;
				if(array[i]>array[j]){
					temp=array[i];
					array[i]=array[j];
					array[j]=temp;
				}
			}
		}
		//查看结果
		for(int i=0;i<array.length;i++){
			System.out.print(array[i]+" ");
		}
	}
}

时间复杂度:O(n^2);理解--被排序的数列中有n个数,遍历一趟的算法复杂度为O(n),需要遍历(n-1)次!因此,冒泡排序的时间

复杂度为O(n^2)。

算法的稳定性:稳定

思考:降序呢?

三、快速排序

 基本思想:使用分冶法策略;选择一个基数,通过一趟排序将要排序的数据分割成独立的两部分;其中一部分的所有数据比另外一部分的所有数据都要小。然后,再按此方法对这两部分的数据进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

分冶法的思想:点击打开链接

一次排序的图解:

一次排序的过程:

1)设置两个变量(指针)i、j,排序开始的时候:i=0,j=N-1; 
2)以第一个数组元素作为基准点(一般),注意:基准元素会影响 算法的效率
3)从j开始向前搜索,即由后开始向前搜索(j - -),找到第一个小于A[i](此时基准点)的值A[j],将A[i]与A[j]交换; 
4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于A[j](此时基准点)的值A[i],将A[j]与A[i]交换; 
5)重复第3步 
6)重复第3、4、5步,直到i=j; (3,4步中,没找到符合条件的值,即3中A[j]不小于key,4中A[j]不大于key的时候改变j、i的值,使得j=j-1,i=i+1,直至找到为止。找到符合条件的值,进行交换的时候i, j指针位置不变。另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束),到此找到基准点的下标,作为分治下标 
7)重复1-6步骤递归排序前半部分 
8 ) 重复1-6步骤递归排序后半部分 

算法的实现

Java递归:点击打开链接--第一种方法的问题(没有进行判断)

猜你喜欢

转载自blog.csdn.net/wzj_110/article/details/79831614