Java 排序算法 介绍

常见排序 算法 包括以下七种:选择排序、冒泡排序、插入排序、快速排序、希尔排序、堆排序、归并排序。 
在学习具体算法实现并进行比较前,先来学习算法比较的几个维度。 
一是稳定性 
所谓稳定性,是指值相等的两个元素在排序前后是否会发生位置的交换。如果不会发生交换,则认为是稳定的算法;反之,则认为是不稳定的排序算法。 
二是时间复杂度,指执行算法所需的时间长短。简单说就是算法执行的快慢程序。 

三是空间复杂度,指执行算法所占用的内存大小。 


排序法

最差时间分析平均时间复杂度稳定度空间复杂度
选择排序O(n2)O(n2)稳定O(1)
插入排序O(n2)O(n2)稳定O(1)
冒泡排序O(n2)O(n2)稳定O(1)
快速排序O(n2)O(n*log2n)不稳定O(log2n)~O(n)
归并排序O(n^2)O(n*logn)稳定不一定
希尔排序O(n*(logn)2)O(n*(logn)2)不稳定O(1)
堆排序O(n*log2n)O(n*log2n)不稳定O(1)
基数排序O(kn)O (nlog(r)m)稳定O(kn)


有了这些基本概念,下面就来看以上七种排序算法的Java版实现


import java.util.ArrayList;
import java.util.Iterator;

public class sort {
	//选择排序
	public int[] sort1(int[] arr){
		for (int i = 0; i < arr.length; i++) {
			int temp,pos=i;
			int mininum=arr[i];
			for (int j = i; j < arr.length; j++) {
				if (mininum >arr[j]) {
					mininum=arr[j];
					pos=j;
				}
			}
			temp=arr[i];
			arr[i]=mininum;
			arr[pos]=temp;
		}
		return arr;
	}
	//冒泡排序
	public int[] sort2(int[] arr){
		for (int i = 0; i < arr.length-1; i++) {
			int temp;
			for (int j = 0; j < arr.length-1-i; j++) {
				if (j+1==arr.length-i) {
					break;
				}else {
					if(arr[j]>arr[j+1]){
						temp=arr[j];
						arr[j]=arr[j+1];
						arr[j+1]=temp;
					}
				}
			}
		}
		return arr;
	}
	//二分插入排序(递归)
	public int[] sort3(int[] arr,int begin,int end){
		if (end==1) {
			return arr;
		}else {
			arr=sort3(arr, begin, end/2);
			for (int i = end/2; i < end; i++) {
				int temp;
				for (int j = 0; j < i; j++) {
					if (arr[i]<=arr[j]) {
						temp=arr[i];
						for (int k = i-1; k >j-1; k--) {
							arr[k+1]=arr[k];
						}
						arr[j]=temp;
					}else {
						
					}
				}
			}
			
		}
		return arr;
	}
	//二分插入排序(递归)
	public static ArrayList<Integer> sort3integer(ArrayList<Integer> arr,int begin,int end){
		if (end==1) {
			return arr;
		}else {
			arr=sort3integer(arr, begin, end/2);
			for (int i = end/2; i < end; i++) {
				int temp;
				for (int j = 0; j < i; j++) {
					if (arr.get(i)<=arr.get(j)) {
						temp=arr.get(i);
						for (int k = i-1; k >j-1; k--) {
							arr.set(k+1,arr.get(k));
						}
						arr.set(j, temp);
					}else {
						
					}
				}
			}
			
		}
		return arr;
	}
	//直接插入排序
	public int[] sort4(int[] arr){
		for (int i = 1; i < arr.length; i++) {
			int temp;
			for (int j = 0; j < i; j++) {
				if (arr[i]>arr[j]) {

				}else {
					temp=arr[i];
					for (int k = i-1; k >j-1; k--) {
						arr[k+1]=arr[k];
					}
					arr[j]=temp;
				}
			}
		}
		return arr;
	}
	//希尔排序(递归)
	public int[] sort5(int[] arr,int gap){
		if(gap==1){
			arr=sort3(arr, 0, arr.length);
			return arr;
		}else {
			int gap1=(gap%2==1?gap/2+1:gap/2);
			ArrayList<Integer>list=new ArrayList<Integer>();
			ArrayList<Integer>poslist=new ArrayList<Integer>();
			for (int i = 0; i < gap; i++) {//对每一个子序列进行插入排序
				int temp2=i;
				while(temp2<arr.length){
					poslist.add(temp2);
					list.add(arr[temp2]);
					temp2+=gap;
				}
				list=sort3integer(list, 0, list.size());
				for (int j = 0; j < list.size(); j++) {
					arr[poslist.get(j).intValue()]=list.get(j);
				}
				list.clear();
				poslist.clear();
			}
			printlist(arr);
			System.out.println("-->");
			arr=sort5(arr, gap1);
		}
		return arr;
	}
	//归并排序
	public ArrayList<Integer> sort6(ArrayList<Integer> arr,int begin,int end){
		if (begin==end-1) {
			return arr;
		}else {
			int mid=(begin+end)/2;
			ArrayList<Integer>arr1=new ArrayList<Integer>();
			ArrayList<Integer>arr2=new ArrayList<Integer>();
			for(int i=begin;i<mid;i++){
				arr1.add(arr.get(i));
			}
			for(int i=mid;i<end;i++){
				arr2.add(arr.get(i));
			}
			arr=merge(sort6(arr1, begin, mid),sort6(arr2, 0, end-mid));
			return arr;
		}
	}
	//快速排序
	public ArrayList<Integer> sort7(ArrayList<Integer> arr,int begin,int end){
		if (begin==end-1||end==begin) {
			return arr;
		}else {
			int temp=0,key=arr.get(begin),i=begin,j=end-1;
			while (i!=j) {
				while(arr.get(j)>=key){
					if (j>begin) {
						j--;
					}
					if (i==j) {
						break;
					}
				}
				if (i==j) {
					break;
				}
				temp=arr.get(i);
				arr.set(i, arr.get(j));
				arr.set(j, temp);
				while(arr.get(i)<key){
					if (i<end-1) {
						i++;
					}
					if (i==j) {
						break;
					}
				}
				if (i==j) {
					break;
				}
				temp=arr.get(i);
				arr.set(i, arr.get(j));
				arr.set(j, temp);
			}
			sort7(arr,0,i);
			sort7(arr,i+1,end);
			return arr;
		}
	}
	//堆排序
	public int[] sort8(int[] arr){
		if (arr.length==1) {
			return arr;
		}else {
			for(int i=0;i<arr.length;i++){
				int temp=0,leftChild=-1,rightChild=-1,end=arr.length-i;
				if (end>1) {//有左孩子
					leftChild=1;
				}
				if (end>2) {//有右孩子
					rightChild=2;
				}
				getMaxHeap(arr, leftChild, rightChild, end);
				temp=arr[0];
				arr[0]=arr[end-1];
				arr[end-1]=temp;
			}
			return arr;
		}
	}
	//基数排序
	public ArrayList<Integer> sort9(ArrayList<Integer> arr,int radix){
		ArrayList<ArrayList<Integer>> binarr=new ArrayList<ArrayList<Integer>>();
		for (int i = 0; i < 10; i++) {
			ArrayList<Integer>tmpArrayList=new ArrayList<Integer>();
			binarr.add(tmpArrayList);
		}
		int rd=1,ra=1;
		while(true){
			rd*=10;
			if (ra>radix) {
				break;
			}
			for (int i = 0; i < arr.size(); i++) {
				switch((arr.get(i)%rd)/(rd/10)){
					case 0:
						binarr.get(0).add(arr.get(i));
						break;
					case 1:
						binarr.get(1).add(arr.get(i));
						break;
					case 2:
						binarr.get(2).add(arr.get(i));
						break;
					case 3:
						binarr.get(3).add(arr.get(i));
						break;
					case 4:
						binarr.get(4).add(arr.get(i));
						break;
					case 5:
						binarr.get(5).add(arr.get(i));
						break;
					case 6:
						binarr.get(6).add(arr.get(i));
						break;
					case 7:
						binarr.get(7).add(arr.get(i));
						break;
					case 8:
						binarr.get(8).add(arr.get(i));
						break;
					case 9:
						binarr.get(9).add(arr.get(i));
						break;
				}
			}
			arr.clear();
			for(int i=0;i<10;i++){
				for (int k = 0; k < binarr.get(i).size(); k++) {
					arr.add(binarr.get(i).get(k));
				}
				binarr.get(i).clear();
			}
			ra++;
		}
		return arr;
	}
	//构造最大堆
	public static int[] getMaxHeap(int[] arr,int leftChild,int rightChild,int end){
		if (leftChild==-1&&rightChild==-1||rightChild==0) {//rightChild==0防止把最终父节点作为一个右孩子处理
			return arr;
		}else {
			int lleftChild=-1,rrightChild=-1,rleftChild=-1,lrightChild=-1;
			//左孩子的子节点
			if (leftChild*2+1<end) {
				lleftChild=leftChild*2+1;
			}
			if (leftChild*2+2<end){
				lrightChild=leftChild*2+2;
			}
			//右孩子的子节点
			if (rightChild*2+1<end) {
				rleftChild=rightChild*2+1;
			}
			if (rightChild*2+2<end){
				rrightChild=rightChild*2+2;
			}
			if (leftChild!=-1&&rightChild!=-1) {
				int parent=(leftChild-1)/2,temp=0;
				while(parent>=0){
					temp=arr[parent];
					if (arr[leftChild]>arr[rightChild]) {
						if (arr[leftChild]>arr[parent]) {
							arr[parent]=arr[leftChild];
							arr[leftChild]=temp;
						}
					}else {
						if (arr[rightChild]>arr[parent]) {
							arr[parent]=arr[rightChild];
							arr[rightChild]=temp;
						}
					}
					if(parent%2==1){//位于父节点的左孩子处
						leftChild=parent;
						rightChild=parent+1;
					}else {//位于父节点的右孩子处
						leftChild=parent-1;
						rightChild=parent;
					}
					parent=(leftChild-1)/2;
				}
			}else {
				if (leftChild!=-1&&rightChild==-1) {//只会出现只有左孩子没有右孩子的情况,不会出现相反的情况
					int parent=(leftChild-1)/2,temp=0;
					temp=arr[parent];
					if (arr[leftChild]>arr[parent]) {
						arr[parent]=arr[leftChild];
						arr[leftChild]=temp;
					}
					if(parent%2==1){//位于上一个的左孩子处
						leftChild=parent;
						rightChild=parent+1;
					}else {
						leftChild=parent-1;
						rightChild=parent;
					}
					parent=(leftChild-1)/2;
					while(parent>=0){
						temp=arr[parent];
						if (arr[leftChild]>arr[rightChild]) {
							if (arr[leftChild]>arr[parent]) {
								arr[parent]=arr[leftChild];
								arr[leftChild]=temp;
							}
						}else {
							if (arr[rightChild]>arr[parent]) {
								arr[parent]=arr[rightChild];
								arr[rightChild]=temp;
							}
						}
						if(parent%2==1){//位于父节点的左孩子处
							leftChild=parent;
							rightChild=parent+1;
						}else {//位于父节点的右孩子处
							leftChild=parent-1;
							rightChild=parent;
						}
						parent=(leftChild-1)/2;
					}
				}else {
				}
			}
			getMaxHeap(arr, lleftChild, lrightChild, end);
			getMaxHeap(arr, rleftChild, rrightChild, end);
			return arr;
		}
	}
	//合并两个有序子序列并返回一个有序的序列
	public static ArrayList<Integer> merge(ArrayList<Integer>list1,ArrayList<Integer>list2){
		ArrayList<Integer>newList=new ArrayList<Integer>();
		if (list1==null||list1.size()==0) {
			return list2;
		}
		if (list2==null||list2.size()==0) {
			return list1;
		}
		if(list1.get(list1.size()-1)<=list2.get(0)){
			newList.addAll(list1);
			newList.addAll(list2);
		}else {
			if (list2.get(list2.size()-1)<=list1.get(0)) {
				newList.addAll(list2);
				newList.addAll(list1);
			}else {
				Iterator<Integer>iterator1=list1.iterator();
				Iterator<Integer>iterator2=list2.iterator();
				boolean flag=true;
				Integer num1=iterator1.next();
				Integer num2=iterator2.next();
				if (num1<num2) {
					newList.add(num1);
					flag=true;
				}else {
					newList.add(num2);
					flag=false;
				}
				while (true) {
					if (flag) {
						if (!iterator1.hasNext()) {
							break;
						}
						num1=iterator1.next();
					}else {
						if (!iterator2.hasNext()) {
							break;
						}
						num2=iterator2.next();
					}
					if (num1<num2) {
						newList.add(num1);
						flag=true;
					}else {
						newList.add(num2);
						flag=false;
					}
				}
				if (flag) {
					newList.add(num2);
				}else {
					newList.add(num1);
				}
				while (iterator1.hasNext()) {
					newList.add(iterator1.next());
				}
				while (iterator2.hasNext()) {
					newList.add(iterator2.next());
				}
			}
		}
		return newList;
	}
	//打印数组
	public void printlist(int [] arr){
		System.out.println("the result:");
		for (int i = 0; i < arr.length; i++) {
			System.out.print(arr[i]+"->");
		}
		System.out.println("END");
	}
	//打印list
	public void printlist2(ArrayList<Integer> arr){
		System.out.println("the result:");
		for (int i = 0; i < arr.size(); i++) {
			System.out.print(arr.get(i)+"->");
		}
		System.out.println("END");
	}
	public static void main(String args[]){
		sort mysort=new sort();
		int arr[]={4,3,22,565,2,566,77,5,3,9};
		ArrayList<Integer>list=new ArrayList<Integer>();
		list.add(4);list.add(3);list.add(22);list.add(565);list.add(2);list.add(566);list.add(77);list.add(5);list.add(3);list.add(9);
//		mysort.printlist(mysort.sort1(arr));
		
//		mysort.printlist(mysort.sort2(arr));
		
//		mysort.printlist(mysort.sort3(arr,0,arr.length));
		
//		mysort.printlist(mysort.sort4(arr));
		
//		mysort.printlist2(mysort.sort3integer(list, 0, list.size()));
		
//		int gap1=arr.length%2==1?arr.length/2+1:arr.length/2;
//		mysort.printlist(mysort.sort5(arr,gap1));
		
//		mysort.printlist2(mysort.sort6(list,0,list.size()));
		
		mysort.printlist2(mysort.sort7(list,0,list.size()));
		
//		mysort.printlist(mysort.sort8(arr));
		
//		mysort.printlist2(mysort.sort9((list),3));
	}
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值