懒狗终于开始刷OJ题了,目前准备在洛谷和LeetCode上刷算法题。今天刷了基体排序,主要是快速排序,简单记一下思路和代码。快排的思想主要是分治,详细讲快排的博客有很多,具体思想、图示就暂且先略过了。直接讲讲代码实现的思路吧。
思路一
- 选取“支点”(pivote),默认选取数组的第0个元素为支点
- 选取指针low和high,初始时分别指向数组第一个元素和最后一个元素
- 从数组的第最后一个元素开始向前搜索,找到第一个比支点小的元素,将该元素放到数组的第low号处
- 从数组的第一个元素开始向后搜索,找到第一个比支点大的元素,将该元素放到数组的第high号处
- 继续分别向后和向前搜索直到low>=high
- 接下来放置支点元素的位置,上述循环跳出的条件一定是low=high,所以将支点元素放到low处即可
- 分别递归的排序支点左侧和支点右侧
代码:
int getKey(int* arr, int low, int high) {
int key = arr[low]; //default
while(low < high) {
while((low < high) && arr[high] >= key){//从后向前检索
high--;
}
arr[low] = arr[high];
while((low < high) && arr[low] <= key) {//从前向后检索
low++;
}
arr[high] = arr[low];
}
//跳出循环,此时low==high,low/high的位置就是基准值key的位置
arr[low] = key;
return low;
}
void quickSort(int* arr, int low, int high) {
if(low < high) {
int key = getKey(arr, low, high);
quickSort(arr, low, key - 1);
quickSort(arr, key + 1, high);
}
}
思路二
- 选取支点元素为数组最中间的元素
- 选取指针low和high,初始时分别指向数组第一个元素和最后一个元素
- 从数组最后一个元素向前搜索找到第一个比支点元素小的元素a[low],从数组第一个元素向后搜索找到第一个比支点元素大的元素a[high]
- 如果i<j,则交换上述两个元素
- 继续分别向前和向后搜索以及交换操作,直到i>j
- 分别递归的对左侧和右侧进行排序
代码:
void qSort(int* arr, int low, int high) {
int mid = arr[(low+high)/2];
int i = low;
int j = high;
while(i<=j){
while(arr[i] < mid)
i++;
while(arr[j] > mid)
j--;
if(i <= j) {
swap(arr[i], arr[j]);
i++;
j--;
}
}
if(j > low)
qSort(arr, low, j);
if(i < high)
qSort(arr, i, high);
}