排序算法之快速排序(java、python和C++实现)

快速排序的基本思想

快速排序是对起泡排序(冒泡排序)的改进,采用分治思想。在各种排序方法中,快速排序比较次数较少,速度较快。

给出一组待排序的数据记录。我们需要选择一个基准值作为分区标准,通常我们取第一个记录或者最后一个记录作为基准值。然后再将所有小于该基准值的记录移到左边,将所有大于该基准值得记录移到右边,中间放基准值记录,称为一趟排序。接着,对左右两个子序列分别重复上述过程。继续下去,直到所有的记录都排好序。

算法原理

例题:

待排序的数组:{5,7,2,9,1,4,6,8,10,3}

期望排好序后的数组:{1,2,3,4,5,6,7,8,9,10}

例题解析:

第一步:选择数组的第一个数据作为基准值,即 5

第二步:首先从左边开始,也就是从第二个数据开始与基准值比较。若小于基准值,则继续比较下一条数据;若大于基准值,则停止比较,并记录下大于基准值的数据的索引(下标)

第三步:从最右边的数据与比较起,若大于基准值,则继续比较下一条数据;若小于基准值,则停止比较,并记录下小于基准值的数据的索引(下标)

第四步:将左边大于基准值的数据与右边小于基准值的数据交换。

第五步:重复第二、三、四步,直到将数组中所有数据比较完。这时需要将第一个数据也就是基准值交换到左右分好的序列中间来。这时数组分成两边,左边的数据都小于基准,右边的数据都大于基准值。

第六步:将左右两边的数据分别重复以上五个步骤,直到所有数据排好序。注意,接下来的每一趟排序不是以5作为基准值了,而是以左右两边的数据的第一个数据作为基准值。

例题数组的每一趟排序的结果:

【】内是下一趟要比较的序列

第一趟后:{【1,3,2,4】,5,【9,6,8,10,7】}

第二趟后:{1,【3,2,4】,5,9,6,8,10,7}

第三趟后:{1,2,3,4,5,【9,6,8,10,7】 }

第四趟后:{1,2,3,4,5,【7,6,8】,9,【10】 }

第五趟后:{1,2,3,4,5,【6 】,7,【 8 】,9,10 }


java实现的代码:

public class QuickSort {
	public static void main(String[] args) {
		//要进行排序的数组
		int[] a = {5,7,2,9,1,4,6,8,10,3};
		
		//将数组a从小到大排序
		quickSort(a, 0, a.length-1);
		
		//打印数组
		printArray(a);
	}
	/**
	 * 快速排序
	 * 将数组a的某一段元素进行划分,小的在左边,大的在右边
	 * @param a
	 * @param left
	 * @param right
	 */
	private static void quickSort(int[] a, int left, int right) {
		//如果只有一个元素,就不用再排下去了
		if(left < right){
			
			int pivot = a[left];  //用序列最左边的记录作为基准值
			int i = left, j = right;
			
			while(i < j){
				//从左边开始遍历,如果比基准值小,就继续向右走 
				while(i < j && a[i] <= pivot) i++;
				//从右边开始遍历,如果比基准值大,就继续向左走
				while(i < j && a[j] > pivot) j--;
				
				//上面的while循环结束时,就说明当前的a[i]的值比基准值大,
				//当前的a[j]的值比基准值小,a[i]应与a[j]互换
				if(i < j){
					swap(a, i, j);
				}
			}
			//分组结束后,要将基准值交换到两组之间
			swap(a, left, i-1);
			//继续递归排序左边的序列
			quickSort(a, left, i-2);
			//继续递归排序右边的序列
			quickSort(a, i, right);
		}
		
	}
	
	/**
	 * 交换数组a中索引为 i 和 j 之间的数值
	 * @param a
	 * @param i
	 * @param j
	 */
	private static void swap(int[] a, int i, int j) {
		int temp = a[i];
		a[i] = a[j];
		a[j] = temp;
	}
	
	//打印数组
	private static void printArray(int[] a) {
		for(int i = 0;i < a.length;i++){
			System.out.print(a[i] + " ");
		}
	}
}

python实现的代码:

def quickSort(a, l, r):
    if l < r:
        pivot = a[l]
        i = l
        j = r
        while i < j:
            while i < j and a[i] <= pivot:
                i += 1
            while i < j and a[j] > pivot:
                j -= 1

            if i < j:
                swap(a, i, j)
        
        swap(a, l, i-1)
        quickSort(a, l, i-2)
        quickSort(a, i, r)

def swap(a,i,j):
    temp = a[i]
    a[i] = a[j]
    a[j] = temp


a = [5,7,2,9,1,4,6,8,10,3]
quickSort(a,0,len(a)-1)
print(a)


C++实现的代码与java的代码基本一样,只需要修改极少的部分:

#include <iostream>
using namespace std;
	
	/**
	 * 交换数组a中索引为 i 和 j 之间的数值
	 * @param a
	 * @param i
	 * @param j
	 */
void swap(int a[], int i, int j) 
{
	if(i != j)
	{
		int temp = a[i];
		a[i] = a[j];
		a[j] = temp;
	}
}
//打印数组
void printArray(int a[], int len)
{
	for(int i = 0;i < len;i++)
	{
		cout<<a[i]<<" ";
	}
}

void quickSort(int a[], int left, int right) {
		//如果只有一个元素,就不用再排下去了
		if(left < right){
			
			int pivot = a[left];  //用序列最左边的记录作为基准值
			int i = left, j = right;
			
			while(i < j){
				//从左边开始遍历,如果比基准值小,就继续向右走 
				while(i < j && a[i] <= pivot) i++;
				//从右边开始遍历,如果比基准值大,就继续向左走
				while(i < j && a[j] > pivot) j--;
				
				//上面的while循环结束时,就说明当前的a[i]的值比基准值大,
				//当前的a[j]的值比基准值小,a[i]应与a[j]互换
				if(i < j){
					swap(a, i, j);
				}
			}
			//分组结束后,要将基准值交换到两组之间
			swap(a, left, i-1);
			
			//继续递归排序左边的序列
			quickSort(a, left, i-2);
			//继续递归排序右边的序列
			quickSort(a, i, right);
		}
		
	}

	
	

int main(int argc, char* argv[])
{
	int a[] = {5,7,2,9,1,4,6,8,10,3};
	int len = sizeof(a)/sizeof(int);
	quickSort(a, 0 , len-1);
	printArray(a, len);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/thanours/article/details/79869336