刚把快速排序重新看了一下,赶紧拿个小本本记下来
原理
思想
- 快排用的主要思想就是分治,也就是大问题化成小问题
- 比如说,要对10个排序,我先用一个方法将10个元素分成前后两组
- 这样依次递归当最后前后两组各只剩一个元素的时候,也就是排序完成的时候
实现思路
- 接下来说说快排的思路吧
- 先选一个标志数,在第一次快排的时候将比标志数大的放在标志数的左边,比标志数小的放到右边
- 这样,在第一次完成的时候这个标志数就会在他的最终位置了
- 接下来对这个标志数的左边和右边两个子数组分别对其进行快排
- 这样,当发现标志数的左边和右边都只剩一个数的时候,排序也就完成了
- 那么接下来问题来了,怎么在每一次将标志数放到最终的位置呢?也就是说怎么才能让比标志数大的放在标志数的左边,比标志数小的放到右边呢
- 先来说说怎么选择标志数
- 标志数一般选择数组首元素即可,然后定义第二个元素下标为 i ,最后一个元素下标为 j
- 然后先从数组的第 j 个元素向前开始遍历,直到找到第一个比标注数大的数
- 再从数组的第 i 个元素向后遍历,直到找到第一个比标志数小的元素
- 然后交换 i 处的数和 j 处的数
- 然后重复上述过程,直到 i 和 j 相遇
- 这个时候除了标志数之外,其他数都放在了应该的位置
- 然后再将标志数和 i 位置( 此时 i = j )的元素相换
- 这个时候需要注意的是 i 位置的元素不一定是比标志数大的,那么我们就人为的将 i 值减一,这个数一定是比标志数大的,具体东西下面的代码会说到
实现代码
void quicksort(int array[],int begin, int end){
int i = begin, j = end;
if( i >= j ){
return;
}
i++;
while( i != j){
while( array[j] <= array[begin] && j > i){
j--;
}
while( array[i] >= array[begin] && j > i){
i++;
}
if( i < j ){
swap(&array[i],&array[j]);
}
}
if(array[begin] <= array[j] ){
swap(&array[begin],&array[j]);
}else{
swap(&array[begin],&array[i-1]);
i--;
}
quicksort(array,begin,i-1);
quicksort(array,i+1,end);
}
注意事项
- 需要注意的是,在每一遍完成之后放置标志数的时候需要注意 i 位置的数如果不满足要求,则要将交换的元素换成 i - - 位置上的元素
- 再一个就是每次递归调用的时候需要注意传入的参数