快速排序详解及JAVA/C++实现

5 篇文章 0 订阅
5 篇文章 0 订阅

快速排序(Quicksort)的主要思想是,通过某种O(n)的方法,将乱序数组分为左右两部分,使得左边的元素小于右边的元素,然后进行递归。平均来说,复杂度是O(nlog(n)).

方法一(比较繁琐):

快速排序的关键在于如何用O(n)的时间将数组分为左右两部分。不妨设临界元素pivot=array[0],将数组分为比pivot大和小两部分。我们利用两个指针left_index以及right_index,使得下标小于left_index的元素小于等于pivot,下标大于right_index的元素大于pivot。

首先,left_index右移,当遇到大于pivot的元素时,停止右移,将该元素与right_index的元素置换,此时可以将right_index向左移一位。

然后,right_index左移,当遇到小于等于pivot的元素时,停止左移,将该元素与left_index的元素置换,此时可以将left_index向右移一位。

然后,left_index右移 ...

直到left_index < right_index + 1,此时,数组的分割过程结束。(注意:两个指针左右移动的次数是O(n)的)

此时,可以将pivot元素(array[0])与左右的临界点交换。使得数组左边小于pivot,右边大于pivot,可以进行递归了。

方法二(比较简单,详见函数quick_sort_2):

思路:从左边找到第一个大于pivot的元素(下标为left_index),从右边找到第一个小于pivot的元素(下标为right_index),如果left_index<right_index,则交换两个元素。

代码如下

public class import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class QuickSort {
	public static int [] random_order_array(int len){  
        List 
  
  
   
    list = new ArrayList
   
   
    
    ();  
        for (int i = 0; i < len; i ++){  
            list.add(i);  
        }  
        Collections.shuffle(list);  
        int [] array = new int [len];  
        for (int i = 0; i < len; i ++)  
            array[i] = list.get(i);  
        return array;  
    }  
	
	public static void quick_sort(int [] array, int start, int end){
		if (start == end) return;
		if (start == end - 1){
			if (array[start] > array[end])
				swap(array, start, end);
			return;
		}
		int pivot = array[start];
		int left_index = start + 1; // array[left_index] 左边的元素(不包含),都小于或者等于pivot
		int right_index = end; // array[end_index] 右边的元素(不包含),都严格大于pivot
		while (left_index < right_index + 1){
			while (left_index < right_index + 1){
				if (array[left_index] > pivot){
					swap(array, left_index, right_index);
					right_index --;
					break;
				}
				left_index ++;
			}
			while (left_index < right_index + 1){
				if (array [right_index] <= pivot){
					swap(array, left_index, right_index);
					left_index ++;
					break;
				}
				right_index --;
			}
		}
		swap(array, start, left_index - 1);
		if (start < left_index - 1) quick_sort(array, start, left_index - 2);
		if (end > right_index + 1) quick_sort(array, right_index + 1, end);
		
	}
	
	public static void quick_sort_2(int [] array, int start, int end){
		if (start == end) return;
		if (start == end - 1){
			if (array[start] > array[end])
				swap(array, start, end);
			return;
		}
		int pivot = array[start];
		int left_index = start + 1;
		int right_index = end;
		while (true){
			while (left_index <= end && array[left_index] < pivot)
				left_index ++;
			while (right_index > start && array[right_index] > pivot)
				right_index --;		
			if (left_index >= right_index)
				break;
			swap(array, left_index, right_index);
		}
		swap(array, start, left_index - 1);
		if (start < left_index - 1) quick_sort(array, start, left_index - 2);
		if (end > right_index + 1) quick_sort(array, right_index + 1, end);
	}
	
	public static final void swap(int [] array, int i, int j){	//内联函数,更快
		if (i != j){
			array[i] = array[i] ^ array[j];
			array[j] = array[i] ^ array[j];
			array[i] = array[i] ^ array[j];
		}
	}
	
	public static void print_array(int [] array){
		for (int i = 0; i < array.length; i ++){
			System.out.print(array[i] + " ");
		}
		System.out.println();
	}
	
	public static void main(String [] args){
		int len = 20;
		int [] array = random_order_array(len);
		//int [] array = {8, 4, 0, 6, 1, 9, 3, 7, 2, 5 };
		System.out.println("乱序数组:");
		print_array(array);
		//quick_sort(array, 0, len - 1);
		quick_sort_2(array, 0, len - 1);
		System.out.println("排序后数组:");
		print_array(array);
	}
}



   
   
  
  

另外,C++的实现如下:

# include <iostream>
# include <ctime>
# include <cstdlib>
using namespace std;
int rand_int(int start, int end);
void print_array(int * array, int len);
void quick_sort(int * array, int len);
void swap(int * array, int i, int j);
int * rand_array(int n);
int main(){
	srand(time(0));
	int len = 20;
	int * array = rand_array(len);
	print_array(array, len);
	quick_sort(array, len);
	print_array(array, len);
	return 0;
}

void print_array(int * array, int len){
	int * temp = array;
	for (int i = 0; i < len; i ++){
		cout << * (temp ++) << " ";
	}
	cout << endl;
}

int rand_int(int start, int end){
	return start + rand() % (end - start + 1);
}

void quick_sort(int * array, int len){
	if (len <= 1) return;
	int left_index = 0;
	int right_index = len - 1;
	for (int w = 0; w < len; w ++){
		while (array[left_index] <= array[0] && left_index <= right_index) left_index ++;
		while (array[right_index] > array[0] && right_index > left_index) right_index --;
		
		if (left_index >= right_index)	break;
		swap(array, left_index, right_index);
	}
	
	swap(array, 0, left_index - 1);
	
	quick_sort(array, left_index - 1);
	quick_sort(array + right_index, len - left_index);
}

void swap(int * array, int i, int j){
	int temp = array[i];
	array[i] = array[j];
	array[j] = temp;
}

int * rand_array(int n){
	//生成随机的长度为n的数组
	//原理参考了http://blog.csdn.net/taobao755624068/article/details/8522953
	int * array = new int[n]; 
	for (int i = 0; i < n; i ++)
		array[i] = i;
	for (int i = 0; i < n; i ++){
		int p = rand_int(0, i);
		swap(array, p, i);
	}
	return array;
}




  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值