各种排序算法思想复杂度及其java程序实现

Posted 林加欣

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了各种排序算法思想复杂度及其java程序实现相关的知识,希望对你有一定的参考价值。

一、冒泡排序(BubbleSort)
1. 基本思想:

设排序表长为n,从后向前或者从前向后两两比较相邻元素的值,如果两者的相对次序不对(A[i-1] > A[i]),则交换它们,

其结果是将最小的元素交换到待排序序列的第一个位置,我们称它为一趟冒泡。下一趟冒泡时,前一趟确定的最小元素

不再参与比较,待排序序列减少一个元素,每趟冒泡的结果把序列中最小的元素放到了序列的”最前面”。

 

2.算法实现

package 冒泡排序;
/**
 * 相邻数据两两比较,大的排上面,小的排下面 第一次可排出最小的值
 * 第二次排出第二小的值
 * 第三次排出第三小的值
 * 以此类推排出顺序
 * 
 * 	最优时间复杂度:O(n) (表示遍历一次发现没有任何可以交换的元素,排序结束。)
	最坏时间复杂度:O(n2)
	稳定性:稳定
 * @author Administrator
 *
 */
public class BubbleSort {
	//初级版(从左往右比较)
	/**
	 * 	第0次排序==0546897231
		第1次排序==0156897432
		第2次排序==0126897543
		第3次排序==0123897654
		第4次排序==0123498765
		第5次排序==0123459876
		第6次排序==0123456987
		第7次排序==0123456798
		第8次排序==0123456789
		第9次排序==0123456789
		最终排序==0123456789
	 *  最优时间复杂度:O(n) (表示遍历一次发现没有任何可以交换的元素,排序结束。)
		最坏时间复杂度:O(n2)
		稳定性:稳定
	 */
	public static void sort1(int[] num){
		int i,j,temp;
		for(i=0;i<num.length;i++){
			//第一次i=0,排出最小的值0
			//第二次i=1,排出第二小的值1
			for(j=i+1;j<num.length;j++){
				if (num[i]>num[j]) {
					temp=num[i];
					num[i]=num[j];
					num[j]=temp;
				}
			}
		}
	}
	//中级版(从右往左比较)
	public static void sort2(int[] num){
		int i,j,temp;
		for(i=0;i<num.length;i++){
			
			for(j=num.length-1;j>i;j--){
				if (num[j-1]>num[j]) {
					temp=num[j-1];
					num[j-1]=num[j];
					num[j]=temp;
				}
			}
			String str="";
			for (int k : num) {
				str+=k;
			}
			System.out.println("第"+i+"次排序=="+str);
		}
		String str2="";
		for (int k : num) {
			str2+=k;
		}
		System.out.println("最终排序=="+str2);
		
	}
	//终极版
	public static void sort3(int[] num){
		int i,j,temp;
		boolean flag=true;
		for(i=0;i<num.length&&flag;i++){
			flag=false;
			for(j=num.length-1;j>i;j--){
				//从右往左两两相比较,大于说明可以交换数值,小于使用flag=false直接跳过
				if (num[j-1]>num[j]) {
					temp=num[j-1];
					num[j-1]=num[j];
					num[j]=temp;
					flag=true;
				}
			}
		}
	}
	
	
	public static void main(String args[]){
		int[] num={5,2,4,6,8,9,7,1,3,0};
//		sort1(num);
//		sort2(num);
		sort3(num);
	}
	
}

二、选择排序
1. 基本思想:
从未排好的部分的第一个作为最小(最大)的,然后依次和剩余的比较,如果有更小(更大)的,记下下标,

以此作为新的最小(最大)值,继续比较,一趟结束后,可以得到最小值。

例如:初始序列:{49 27 65 97 76 12 38}
  第1趟:12与49交换:12{27 65 97 76 49 38}(选择第一个数与后面剩下的数两两比较,交互位置,排出第一个最小值)
  第2趟:27不动 :12 27{65 97 76 49 38}(第一个数已经排好,选择第二个数与后面剩下的数两两比较,交互位置,排出第二个最小值)
  第3趟:65与38交换:12 27 38{97 76 49 65}(第二个数已经排好,选择第三个数与后面剩下的数两两比较,交互位置,排出第三个最小值)
  第4趟:97与49交换:12 27 38 49{76 97 65}以此类推
  第5趟:76与65交换:12 27 38 49 65{97 76}
  第6趟:97与76交换:12 27 38 49 65 76 97 完成

2. 算法实现:

package 简单选择排序;
/**
 * 选择一个min做基准和其他的数据相互比较,如果比较的数大则把当前的数的赋值给min
 * 以此类推
 * @author Administrator
 *
 */
public class SelectSort {
	//简单选择排序,选择一个min做基准和其他的数据相互比较
	/**
	 * 最优时间复杂度:O(n2)
		最坏时间复杂度:O(n2)
		稳定性:不稳定(考虑升序每次选择最大的情况)
	 * @param num
	 */
	public static void sort(int[] num){
		int i,j,min,temp;
		for(i=0;i<num.length;i++){
			min=i;//将当前下标定义为最小值下标
			for(j=i+1;j<num.length;j++){
				if (num[min]>num[j]) {
					min=j;//如果有小于当前最小值的关键字,将此关键字的下标赋值给min
				}
			}
			if (i!=min) {//若min不等于i,说明min发生改变,即上面相互比较的为true,即有最小值,交换
				temp=num[i];
				num[i]=num[min];
				num[min]=temp;
			}
			String str="";
			for (int k : num) {
				str+=k;
			}
			System.out.println("第"+i+"次排序=="+str);
		}
		String str2="";
		for (int k : num) {
			str2+=k;
		}
		System.out.println("最终排序=="+str2);
		
	}
	
	public static void main(String args[]){
		int[] num={5,2,4,6,8,9,7,1,3,0};
		sort(num);

	}
}

三、插入排序(Insertion Sort)
1. 基本思想:

有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,

这个时候就要用到一种新的排序方法——插入排序法,插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,

从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。

  每次将一个待排序的数据元素,插入到前面已经排好序的数列中的适当位置,使数列依然有序;直到待排序数据元素全部插入完为止。
【示例】:
[初始关键字]    [49] 38 65 97 76 13 27 49(选择49)
    J=2(38)   [38 49] 65 97 76 13 27 49(选择38插入到49前面)
    J=3(65)   [38 49 65] 97 76 13 27 49(选择65插入到49前面)
    J=4(97)   [38 49 65 97] 76 13 27 49(选择97插入到65前面)
    J=5(76)   [38 49 65 76 97] 13 27 49(以此类推)
    J=6(13)   [13 38 49 65 76 97] 27 49
    J=7(27)   [13 27 38 49 65 76 97] 49
    J=8(49)   [13 27 38 49 49 65 76 97] 

2. 算法实现:

package 直接插入排序;

public class InsertSort {
	/**
	 * 插入排序
	 * 
	 * @paramarr
	 * @return
	 */
	public static void insert(int[] num)  
    {  
        for(int i=1;i<num.length;i++)     //n-1此扫描,依次向前插入n-1个元素  
        {  
            int temp=num[i];       //每趟将num[i]插入到前面的排序子序列中  
            int j;  
            for(j=i-1;j>=0&&temp<num[j];j--)  
            {  
            	num[j+1]=num[j];  //将前面较大的元素向后移动   
            }  
            num[j+1]=temp;      //temp值到达插入位置  
            String str="";
			for (int k : num) {
				str+=k;
			}
			System.out.println("第"+i+"次排序=="+str);
        }
        String str2="";
		for (int k : num) {
			str2+=k;
		}
		System.out.println("最终排序=="+str2);
    }  


	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		int[] num = { 5, 2, 4, 6, 8, 9, 7, 1, 3, 0 };
		insert(num);
	}
}

  

以上是关于各种排序算法思想复杂度及其java程序实现的主要内容,如果未能解决你的问题,请参考以下文章

算法排序02——归并排序介绍及其在分治算法思想上与快排的区别(含归并代码)

总结各种排序算法Java实现

十大经典排序算法的算法描述和代码实现

八大排序算法总结

7种基本排序算法的Java实现

八大排序算法实战:思想与实现