快速排序(Java)

快速排序

单边循环排序原理

  1. 选择最右元素作为基准点元素
  2. j 指针负责找到比基准点小的元素,一旦找到则与 i 进行交换
  3. i 指针维护小于基准点元素的边界,也是每次交换的目标索引
  4. 最后基准点与 i 交换,i 即为分区位置

代码

public class QuickSort {
    public static void main(String []args) {
        int[] arr = new int[]{2,6,3,8,1,4,5,9,7};
		int base = arr.length-1;
		quickSort(arr,0,base);
		
		for(int i = 0; i<arr.length; ++i){
			System.out.print(arr[i]+" ");
		}
		System.out.println();
    }
	
	public static void quickSort(int[] arr,int i, int base){
		
		if(i >= base){
			return;
		}
		
		for(int j = i; j<base; ++j){
			if(arr[j] < arr[base]){
				int tmp = arr[j];
				arr[j] = arr[i];
				arr[i] = tmp;
				
				i++;
			}
		}
		
		int tmp = arr[base];
		arr[base] = arr[i];
		arr[i] = tmp;
		
		quickSort(arr,0,i-1);
		quickSort(arr,i+1,base);
	}
}

双边循环排序原理:

  1. .找一个基准值,用两个指针分别指向数组的头部和尾部;
  2. 先从尾部向头部开始搜索一个比基准值小的元素,搜索到即停止,并记录指针的位置;
  3. 再从头部向尾部开始搜索一个比基准值大的元素,搜索到即停止,并记录指针的位置;
  4. 交换当前左边指针位置和右边指针位置的元素;
  5. .重复2,3,4步骤,直到左边指针的值大于右边指针的值停止。

演示

快速排序

代码

public class QuickSort {

    public static void main(String[] args) {
        int[] arr = {14, 21, 2, 32, 29, 43, 43, 13, 12, 30, 19, 34, 38, 8, 48};
        sort(arr);
        for (int a : arr) {
            System.out.print(a + ", ");
        }
    }

    public static void sort(int[] arr) {
        sort(arr, 0, arr.length - 1);
    }

    public static void sort(int[] arr, int left, int right) {
        if (left < right) {
            int index = partition(arr, left, right);
            sort(arr, left, index - 1);
            sort(arr, index + 1, right);
        }
    }

    public static int partition(int[] a, int lo, int hi) {
        int key = a[lo];//把最左边的元素当做基准值
        int left = lo;//定义一个左侧指针,初始指向最左边的元素
        int right = hi + 1;//定义一个右侧指针,初始指向左右侧的元素下一个位置
        //进行切分
        while (true) {
            //先从右往左扫描,找到一个比基准值小的元素
            while (key < a[--right]) {//循环停止,证明找到了一个比基准值小的元素
                if (right == lo) {
                    break;//已经扫描到最左边了,无需继续扫描
                }
            }
            //再从左往右扫描,找一个比基准值大的元素
            while (a[++left] < key) {//循环停止,证明找到了一个比基准值大的元素
                if (left == hi) {
                    break;//已经扫描到了最右边了,无需继续扫描
                }
            }
            if (left >= right) {
                //扫描完了所有元素,结束循环
                break;
            } else {
                //交换left和right索引处的元素
                int tmp = a[left];
                a[left] = a[right];
                a[right] = tmp;
            }
        }
        //交换最后rigth索引处和基准值所在的索引处的值
        int tmp = a[lo];
        a[lo] = a[right];
        a[right] = tmp;
        return right;//right就是切分的界限
    }

}


```java
public class QuickSort {
    public static void main(String []args) {
        int[] arr = {14, 21, 2, 32, 29, 43, 43, 13, 12, 30, 19, 34, 38, 8, 48};
		quickSort(arr,0, arr.length -1);
		
		for(int i = 0; i<arr.length; ++i){
			System.out.print(arr[i]+" ");
		}
		System.out.println();
    }
	
	public static void quickSort(int[] arr, int l, int r){
		if(l>=r){
			return;
		}
		int key = arr[l];
		int i = l;
		int j = r;
		while(i < j){
			while(i<j && arr[j] > key){
				j--;
			}
			while(i<j && arr[i] <= key){
				++i;
			}
			
			int tmp = arr[i];
			arr[i] = arr[j];
			arr[j] = tmp;
		}
		arr[l] = arr[i];
		arr[i] = key;
		
		quickSort(arr,l,i-1);
		quickSort(arr,i+1,r);
	}
}

## 时间复杂度:O(nlogn)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值