JAVA中各种排序算法

写在半年后:

回头再看自己总结的这个排序实在是太挫了,可以用惨不忍睹来形容。于是就想重新整理一下。然而在整理思路的时候,发现了这么一篇博客:(点击可以打开)

各种排序算法的分析及java实现   

我最多也就写成这个样。。不转载了。。

 

本文下面就常用的 冒泡排序、快速排序、简单选择排序、直接插入排序给出代码示例。

排序大的分类可以分为两种:内排序和外排序。在排序过程中,全部记录存放在内存,则称为内排序,如果排序过程中需要使用外存,则称为外排序。下面讲的排序都是属于内排序。

  内排序有可以分为以下几类:

  (1)、插入排序:直接插入排序、二分法插入排序、希尔排序。

  (2)、选择排序:简单选择排序、堆排序。

  (3)、交换排序:冒泡排序、快速排序。

  (4)、归并排序

  (5)、基数排序

 


关于各种排序算法的稳定性:

选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法,

冒泡排序、插入排序、归并排序和基数排序都是稳定的排序算法。



各排序法的时间复杂度:(此表转载)

排序法 平均时间 最差情形 稳定度 额外空间 备注
冒泡 O(n2) O(n2) 稳定 O(1) n小时较好
交换 O(n2) O(n2) 不稳定 O(1) n小时较好
选择 O(n2) O(n2) 不稳定 O(1) n小时较好
插入 O(n2) O(n2) 稳定 O(1) 大部分已排序时较好
基数 O(logRB) O(logRB) 稳定 O(n)

B是真数(0-9),

R是基数(个十百)

Shell

O(nlogn)

O(n^1.25)

???

O(ns) 1<s<2 不稳定 O(1) s是所选分组
快速 O(nlogn) O(n2) 不稳定 O(nlogn) n大时较好
归并 O(nlogn) O(nlogn) 稳定 O(1) n大时较好
O(nlogn) O(nlogn) 不稳定 O(1) n大时较好


例:

冒泡排序法:

 
import java.util.ArrayList;
import java.util.Random;

public class AllSort {
	public static void main(String []args){
		ArrayList<Integer> a=new ArrayList<Integer>();
		Bubble bubble=new Bubble();
		bubble.sort(a);
		//Select select=new Select();
		//select.sort(a);
		for(int l=1;l<=a.size();l++){
			System.out.print(a.get(l-1)+" ");
			if(l%10==0){
				System.out.println();
			}
		}
	}
}

class Bubble{
	public void sort(ArrayList<Integer> ar){
		Random rd=new Random(100);
		for(int i=0;i<100;i++){
			ar.add(rd.nextInt(1000));
		}
		//System.out.println(a.get(0));
		for(int j=0;j<ar.size()-1;j++){
			for(int k=0;k<ar.size()-j-1;k++){
				//将最小的数冒泡到最后
				if(ar.get(k+1)>ar.get(k)){
					int temp=ar.get(k+1);
					ar.set(k+1, ar.get(k));
					ar.set(k, temp);
				}
			}
		}
		
	}
}

快速排序法:

package problemSet0326;

public class QuickSort {
	public static void main(String []args){
		int a[]=new int[100];
		for(int i=0;i<100;i++){
			a[i]=(int)(Math.random()*1000);
		}
		Quick quick=new Quick();
		quick.sort(a,0,a.length-1);
		for(int l=1;l<=100;l++){
			System.out.print(a[l-1]+" ");
			if(l%10==0){
				System.out.println();
			}
		}
	}
}

class Quick{
	public int partition(int arr[],int l, int r){
		int i=l,j=r,key=arr[i];
		while(i<j){
			while(i<j&&key<=arr[j])j--;
			if(i<j){
				int temp=arr[i];
				arr[i]=arr[j];
				arr[j]=temp;
				i++;
			}
			while(i<j&&arr[i]<=arr[j])i++;
			if(i<j){
				int temp=arr[i];
				arr[i]=arr[j];
				arr[j]=temp;
				j--;
			}
		}
		return i;
	}
	public void sort(int[]a,int l,int r){
		if(l<r){
			int key=partition(a, l, r);
			sort(a,l,key-1);
			sort(a,key+1,r);
		}
	}
}



选择排序法分为选择排序法和堆排序法。

选择排序法:

class Select{
	public void sort(ArrayList<Integer> ar){
		Random rd=new Random(47);
		for(int i=0;i<100;i++){
			ar.add(rd.nextInt(1000));
		}
		for(int j=0;j<ar.size()-1;j++){
			int minIndex=j;
			for(int k=j+1;k<ar.size();k++){
				
				if(ar.get(k)<ar.get(minIndex)){
					minIndex=k;
				}
			}
			int temp=ar.get(j);
			ar.set(j, ar.get(minIndex));
			ar.set(minIndex, temp);
		}
		
	}
}

插入排序法分为插入排序法,谢耳排序法,二叉树排序法。

插入排序法:

class Insert{
	public void sort(ArrayList<Integer> ar){
		//Random rd=new Random(100);
		for(int i=0;i<100;i++){
			ar.add((int)(Math.random()*1000));
		}
		for(int j=1;j<ar.size();j++){
			int insertVal=ar.get(j);
			int index=j-1;
			while(index>=0&&ar.get(index)>insertVal){
				//将index处的值向后移动
				ar.set(index+1, ar.get(index));
				index--;
			}
			//将insertVal插入到适当位置(如果有变动即向前变动)
			ar.set(index+1, insertVal);
		}
	}
}

插入排序的另一种写法:

//插入排序
class InsertSort {
	public void sort(int[] a){
		for(int i=1;i<a.length;i++){
			int temp=a[i];
			int j;
			for(j=i-1;j>=0;j--){
				if(a[j]>temp){
					a[j+1]=a[j];
				}else{
					break;
				}
			}
			a[j+1]=temp;
		}
	}
}
虽然只有两层循环,但是其中的思路还是略有点复杂的。

1.temp这个变量不能少,也就是说不能直接把a[i]拿去和a[j]比较,因为a[i]的值在内层循环的过程中是变化不固定的,所以要有个临时变量来存储a[i]处的初始值,即要寻找插入位置元素的值。

2.int j需要再外层循环中声明,因为每次i加一,即为将a[i]插入到此次循环应当的位置,最后一步应为a[j+1]的值temp插入到应当位置。

3.外层循环从1开始,因为插入排序的思想是每次外层循环均默认左侧的值已排好序。那么一个元素自然是排好序的无需再排。


排序算法的选择

  1.数据规模较小

    (1)待排序列基本序的情况下,可以选择直接插入排序

    (2)对稳定性不作要求宜用简单选择排序,对稳定性有要求宜用插入或冒泡

  2.数据规模不是很大

  (1)完全可以用内存空间,序列杂乱无序,对稳定性没有要求,快速排序,此时要付出log(N)的额外空间。

  (2)序列本身可能有序,对稳定性有要求,空间允许下,宜用归并排序

  3.数据规模很大

     (1)对稳定性有求,则可考虑归并排序

      (2)对稳定性没要求,宜用堆排序

  4.序列初始基本有序(正序),宜用直接插入,冒泡


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值