使用JAVA泛型实现快速排序

本文介绍了快速排序的分治思想,详细阐述了快速排序的具体步骤,并通过使用JAVA泛型来实现,允许自定义比较类,实现了Comparable接口并定义compareTo方法。文中还给出了完整的快速排序代码实现。

一,快速排序介绍

①分治特性:快速排序是分治思想的一种体现,在进行每一轮排序前先选定枢轴(pivot)元素,经过一轮排序后,所有比枢轴元素小的元素在枢轴元素的左边,所有比枢轴元素大的元素在枢轴元素的右边。这样,经过一轮排序后,就把整个待排序数组的元素分成了两部分,然后再分别对这两部分元素按两样的方式进行排序----分治思想。


二,快速排序的具体步骤

为简单起见,总是选择第一个位置处的元素作为枢轴元素。初始时,9为枢轴,对 right 指针而言,若比9大,则right--;对left而言,若比9小,则left++。下面是经过第一轮的排序后,图三表示此时各个数组元素的位置。

图二表示:当left指针超过了right后,应该结束第一轮排序了,并将A[right]与枢轴元素a[lo](第一个元素)交换,从而得到图三。


三,使用泛型实现的好处就是可以定义自己需要比较的类的对象,该类 implements Comparable<T> 接口,并实现 compareTo方法来定义自己的比较标准。如下面的例子中,就可以根据Person类的String id 来比较Person对象。

public class Person implements Comparable<Person>{
	String id;
	
	public Person(String id){
		this.id = id;
	}
	public String getId(){
		return id;
	}
	@Override
	public int compareTo(Person o) {
		// TODO Auto-generated method stub
		return id.compareTo(o.getId());
	}
	
	public String toString(){
		return "id " + id;
	}
}


快速排序的完整实现代码如下: 有些具体的细节可以通过调试代码的方式来弄懂。

public class QuickSort {
	private QuickSort(){
		
	}
	
	public static <T extends Comparable<T>> void sort(T[] list){
		quick(list, 0, list.length - 1);
	}
	
	private static <T extends Comparable<T>> void quick(T[] list, int lo, int hi){
			if(lo < hi){//递归结束的条件
				int splitPoint = split(list, lo, hi);
				quick(list, lo, splitPoint - 1);
				quick(list, splitPoint + 1, hi);
			}
	}
	
	private static <T extends Comparable<T>> int split(T[] list, int lo, int hi){
		T pivot = list[lo];//总是将第一个元素先为枢轴元素
		T temp;
		int left = lo + 1;
		int right = hi;//排序过程中的遍历指针left、right
		while(left <= right){//等于号不能去掉
			while(right >= lo && left <= right){
				if(list[right].compareTo(pivot) < 0)
					break;
				right--;
			}//end inner while
			/*
			 * left <= hi([lo + 1(left), hi(right)]) 的原因:quicksort 在分割后,一部分比枢轴小一部分比枢轴大
			 * 比枢轴小的那部分元素进行排序时,它的指针不能超过枢轴元素的位置
			 * left <= right 代表这一轮排序还尚未结束
			 */
			while(left <= hi && left <= right){
				if(list[left].compareTo(pivot) > 0)
					break;
				left++;
			}//end inner while
			if(left < right){//在一轮排序中,左指针移动遇到了比枢轴大的元素,break.右指针移动遇到了比枢轴小的元素,break.此时交换这两个元素
				temp = list[left];
				list[left] = list[right];
				list[right] = temp;
				left++;
				right--;
			}
		}//end outwhile
		temp = list[right];
		list[right] = pivot;
		list[lo] = temp;
		return right;
	}
	
	public static void main(String[] args) {
		Integer[] arr = {9,3,14,7,5,19,12};
		sort(arr);
		for(int i : arr)
			System.out.println(i);
		
		Person[] arr1 = {
				new Person("123"), new Person("456"),
				new Person("234"), new Person("980"), 
				new Person("567"), new Person("853")
				};
		sort(arr1);
		for(Person p : arr1)
			System.out.println(p);
	}
}





评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值