前言
最近补了补数据结构和算法,想写几篇,一是为了总结,二是为了能和大家交流交流。毕竟算法是内功,不管是对于自我提升还是面试都是有帮助的。 同时也希望能起到抛砖引玉的作用,欢迎大佬们多多指教。-_-
☆☆☆ 算法目录导航页,包含基础算法、高级算法、机器学习算法等☆☆☆
1.快速排序
快速排序是一种基于交换的排序方式,整个排序过程围绕三点进行:
1.两个指针left和right。分别指向数组第一个和最后一个数字。
2.选中一个key作为参照。key值在【一次】排序过程中是【不变】的。
3.比较交换。每一步都和key去比较。如果left指向的数字比key大,则交换left和right对应的数字。同理,right指向的数字比key小,则交换。否则,移动left和right向数组中间靠拢。
2.一次排序过程完整图解
首先,选中key = 5,左指针left指向的数字先进行比较,right不变。若arr[left] < 5,left++;否则,交换左右指针对应的数字。交换完成后,则left指针不变,right指针开始移动。每次交换过后互换指针移动。
上面写的如果看着晕,建议先看下图解,然后跑一跑代码。
3.代码示例Java版本
/**
*
* @author wxq
*
*/
public class SortMy {
/**
* 测试
* @param args
*/
public static void main(String[] args) {
int [] arr = new int [] {1,8,6,4,2,3,5};
quickSort1(arr, 0, arr.length-1);
System.out.println(Arrays.toString(arr));
}
/**
* 一次排序过程
* @param arr
* @param left
* @param right
* @return
*/
static int oneSort(int [] arr , int left ,int right ){
//选择最后一个元素为key
int key = arr[right];
// System.out.println("key="+key);
//开始排序
while (left < right) {
//从左往右开始比较,右指针不变
while(left < right && arr[left] <= key){
left++;
}
//左边数小于key,交换
swap(arr,left,right);
//从右往左开始比较,左指针不变
while(left < right && arr[right] >= key){
right--;
}
//右边数小于key,交换
swap(arr,left,right);
}
//left 和 right相遇
return left;
}
/**
* 递归实现
* @param arr
* @param left
* @param right
*/
static void quickSort1(int[] arr,int left ,int right){
//参数校验
if(arr.length < 1 || left < 0 || right < 0) return;
if(left < right){
int index = oneSort(arr, left, right);
quickSort1(arr,left,index - 1); //左子序列 快速排序
quickSort1(arr,index + 1,right);//右子序列 快速排序
}
}
/**
* 交换
* @param arr
* @param a
* @param b
*/
static void swap(int[] arr, int a, int b) {
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
}
4.非递归实现
递归的本质是栈,所以我们用栈来实现快排。
/**
* 非递归实现
* @param arr
* @param left
* @param right
*/
static void quickSort2(int[] arr,int left ,int right){
Stack<Integer> s = new Stack<>();
s.push(left);
s.push(right);
//终止条件
while(!s.empty()){
right = s.pop();
left = s.pop();
//一次排序后左右指针相遇点
int index = oneSort(arr, left, right);
//左子序列 快速排序
if(left < (index-1)){
s.push(left);
s.push(index-1);
}
//右子序列 快速排序
if((index+1) < right){
s.push(index+1);
s.push(right);
}
}
}