算法--快速排序递归和非递归实现方式--排序

快速排序主要思想,选取一个基准,进行一趟排序,调整数组使基准左边的数都小于基准,使基准右边的数都大于基准。然后对于基准划分的两个子数组依次进行递归划分调整。

1.递归版本

public static void quickSort(int[] arr, int lo, int hi){
		if(lo>=hi) return;
		int q = partition(arr, lo, hi);
		quickSort(arr, lo, q-1);
		quickSort(arr, q+1, hi);
	}

	//算法导论版本
	//   lo---i----j----hi
	//lo--i之间存放小于r  i---j存放等于r的值    j---hi存放大于r
	private static int partition(int[] arr, int lo, int hi) {
		//选取基准
		int r = arr[hi];
		int i = lo-1;
		for(int j=lo; j<hi; j++){
			//当比基准小,放到左边
			if(arr[j]<r){
				i++;
				swap(arr, i, j);
			}
		}
		swap(arr, i+1, hi);
		return i+1;
	}

	private static void swap(int[] arr, int i, int j) {
		int tmp = arr[i];
		arr[i] = arr[j];
		arr[j] = tmp;
	}

2. 非递归版本

public static void quickSort2(int[] arr, int lo, int hi){
		Stack<Integer> s = new Stack<>();
		int q = partition(arr, lo, hi);
		if(q-1>lo){
			s.push(lo);
			s.push(q-1);
		}
		if(q+1<hi){
			s.push(q+1);
			s.push(hi);
		}
		while(!s.isEmpty()){
			int high = s.pop();
			int low = s.pop();
			int qq = partition(arr, low, high);
			if(qq-1>low){
				s.push(low);
				s.push(qq-1);
			}
			if(qq+1<high){
				s.push(qq+1);
				s.push(high);
			}
		}
	}

非递归主要利用栈来保存需要递归划分的数字坐标

3.partition函数的其他实现方式

选取最小数作为基准r,维护两个指针,分别找到左边第一个比r小的数  右边第一个比r大的数,交换位置。最后调整基准位置。

//算法第四版
	private static int partition2(int[] arr, int lo, int hi){
		int i = lo;
		int j = hi+1;
		int r = arr[lo];         //选取arr[lo]作为基准
		while(true){
			while(arr[++i]<=r)   //左边找到第一个比r小的数
				if(i==hi) break;
			while(arr[--j]>=r)   //右边找到第一个比r大的数
				if(j==lo) break;
			if(i>=j) break;
			swap(arr, i, j);
		}
		swap(arr, lo, j);
		return j;
	}
private static int partition3(int[] arr, int low, int high){
	    int pivot = arr[low]; //选第一个元素作为枢纽元
	    while(low < high)
	    {
	        while(low < high && arr[high] >= pivot)high--;
	        arr[low] = arr[high];   //从后面开始找到第一个小于pivot的元素,放到low位置
	        while(low < high && arr[low] <= pivot)low++;
	        arr[high] = arr[low];   //从前面开始找到第一个大于pivot的元素,放到high位置
	    }
	    arr[low] = pivot;           //最后枢纽元放到low的位置
	    return low;
	}

快速排序时间复杂度平均O(NlogN),当数组基本有序时,时间复杂度变为O(N2);

猜你喜欢

转载自blog.csdn.net/u014106644/article/details/83269173
今日推荐