用QuickSort快速查找中位数(median)

中位数(median)是一个排好序的元素中中间位置的元素,如果元素个数为偶数,则是中间两个元素的平均值。例如(3,1,5)的中位数是3,而 (2,1,3,5)的中位数是2.5。查找中位数属于Selection Algorithms的一种。用快速排序可以做到每次divide之后,只需要conquer一个分支,时间复杂度为O(nlogn)。

为便于比较,以下代码包含quicksort的算法实现:

  public static float findMedianByQuicksort(int[] A,int left,int right){
	  //if(right<left)
	  //  throw new IllegalArgumentException();
	  
	  int rp = sortPivot(A,left,right);
	  
	  int leftCnt = rp;
	  int rightCnt = A.length-rp-1;
	  if(A.length % 2 == 0) {
		  if(rightCnt == leftCnt+1){			 
			  if(right<rp+1){
				  return A[rp];
			  }else{
				  return (A[rp] + findMedianByQuicksort(A,rp+1,right))/2;
			  }
			  
		  }else if(rightCnt+1==leftCnt){
			  if(rp-1<left){
				  return A[rp];
			  }else{
				  return (findMedianByQuicksort(A,left,rp-1)+A[rp])/2;
			  }
		  }else if(rightCnt > leftCnt){
			  return findMedianByQuicksort(A,rp+1,right);			  
		  }else{
			  return findMedianByQuicksort(A,left,rp-1);
		  }
	  }else{
		  if(leftCnt==rightCnt){
			  return A[rp];
		  }else if(rightCnt > leftCnt){
			  return findMedianByQuicksort(A,rp+1,right);			  
		  }else{
			  return findMedianByQuicksort(A,left,rp-1);
		  }
	  }
  }
  
  
  public static void quickSort(int[] A,int left,int right){
	  if(right<=left)
		  return;
	  	  
	  int rp = sortPivot(A,left,right);
	  
	  quickSort(A,left,rp-1);
	  quickSort(A,rp+1,right);
  }
  private static int sortPivot(int[] A,int left,int right){
	  int pivot = A[left];
	  int lp=left+1;
	  int rp=right;
	  while(lp<=rp){//consider the "equal" case: e.g. [-4 0], -4 is pivot
		  for(;lp<=right;lp++){
			  if(A[lp]>pivot){
				  break;
			  }
		  }		  
		  for(;rp>=left+1;rp--){
			  if(A[rp]<pivot){
				  break;
			  }
		  }		  
		  if(lp < rp){
			  //swap
			  int tmp = A[lp];
			  A[lp]=A[rp];
			  A[rp] = tmp;
			  lp++;
			  rp--;
		  }		  
	  }
	  //swap pivot with the rp's value	  
	  A[left]=A[rp];
	  A[rp] = pivot;
	  return rp;
  }

posted @ 2011-06-05 22:02  ljsspace  阅读(1019)  评论(0编辑  收藏  举报