快排的非递归实现

http://www.360doc.com/content/14/0516/13/17064216_378214717.shtml


#include<iostream>
#include<stack>
using namespace std;
int partion(int* a, int low, int high){
int temp=a[low];
while(low<high){
while(low<high && a[high]>temp)
--high;
a[low]=a[high];
while(low<high && a[low]<temp)
++low;
a[high]=a[low];
}
a[low]=temp;
return low;
}

void qsort(int* a, int low, int high){
if(!a|| low>=high)
return;
stack<int> q;
if(low<high){
int mid=partion(a,low,high);
if(mid>low){
q.push(low);
q.push(mid-1);
}
if(mid<high){
q.push(mid+1);
q.push(high);
}
while(!q.empty()){
int p1=q.top();
q.pop();
int p2=q.top();
q.pop();
mid=partion(a,p2,p1);
if(mid>p2){
q.push(p2);
q.push(mid-1);
}
if(mid<p1){
q.push(mid+1);
q.push(p1);
}
}

}

}

int main(){
int a[]={1,3,5,2,0,8};
qsort(a,0,5);
for(int i=0;i<6;++i)
cout<<a[i]<<' ';
cout<<endl;
return 0;
}

注意:这里非递归算法的速度低于递归算法,由于stl 栈的效率低

<think>好的,用户想了解如何用Java实现速排序算法。首先,我需要回忆一下速排序的基本原理。速排序是基于分治法的,选择一个基准元素,将数组分成两部分,一部分比基准小,另一部分比基准大,然后递归地对这两部分进行排序。 接下来,我得考虑Java的具体实现。通常,速排序有递归和非递归两种方式,但用户可能更关注递归实现,因为这是基础。根据引用[2]和[4],基准的选择可以是最后一个元素或者第一个元素,这里可能需要说明不同的选择方式对性能的影响,比如基准选择不当可能导致最坏情况的时间复杂度。 然后,分区的实现是关键。需要遍历数组,将小于基准的元素移到左边,大于的移到右边。这个过程中,双指针法比较常见,比如i和j指针,i记录小于基准的边界,j遍历数组,交换元素的位置。这个过程需要详细解释,可能用户会困惑如何具体移动指针。 另外,引用[1]提到优化方法,比如三数取中法选择基准,或者在小数组时切换成插入排序。虽然用户主要问的是实现,但可能后续问题会涉及优化,这里可以简要提及,但重点放在基础实现上。 考虑到用户给出的示例中有Python代码,Java的实现需要结构清晰,包含递归函数和分区函数。代码注释也很重要,帮助用户理解每一步的作用。例如,引用[2]中的代码选择最后一个元素作为基准,然后进行分区,再递归处理左右子数组。 可能需要注意边界条件,比如数组长度为0或1的情况,递归终止条件是否正确。同时,测试用例也是必要的,用户可能想知道如何验证代码的正确性,比如使用示例数组进行排序测试。 最后,用户可能对时间复杂度和稳定性感兴趣,需要简要说明速排序的平均时间复杂度是$O(n \log n)$,最坏情况是$O(n^2)$,以及如何通过优化避免最坏情况。不过根据用户的问题,这部分可能属于后续的相关问题,但可以在回答中稍微提及,以展示全面性。 总结步骤:1. 确定基准;2. 分区操作;3. 递归排序左右子数组。代码结构包括主函数、递归函数和分区函数。需要确保代码正确,并解释关键步骤,比如分区的逻辑和指针移动。</think>以下是用Java实现速排序算法的分步讲解: ### 一、基础实现 ```java public class QuickSort { public static void sort(int[] arr) { quickSort(arr, 0, arr.length - 1); } private static void quickSort(int[] arr, int low, int high) { if (low < high) { int pivotIndex = partition(arr, low, high); quickSort(arr, low, pivotIndex - 1); // 排序左半区 quickSort(arr, pivotIndex + 1, high); // 排序右半区 } } private static int partition(int[] arr, int low, int high) { int pivot = arr[high]; // 选择最后一个元素作为基准 int i = low - 1; // 小于基准元素的边界指针 for (int j = low; j < high; j++) { if (arr[j] < pivot) { i++; swap(arr, i, j); // 将小于基准的元素交换到左侧 } } swap(arr, i + 1, high); // 将基准元素放到正确位置 return i + 1; } private static void swap(int[] arr, int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } ``` ### 二、关键步骤解析 1. **基准选择**:示例代码选择数组最后一个元素作为基准(`arr[high]`)[^2] 2. **分区过程**: - 使用双指针`i`和`j`遍历数组 - `i`标记小于基准元素的边界位置 - 当`arr[j] < pivot`时,将元素交换到左半区 3. **递归排序**:将数组分为基准左侧(较小元素)和右侧(较大元素)后,分别递归处理 ### 三、优化建议 1. **三数取中法**:选择首、中、尾三个元素的中值作为基准,避免最坏情况$O(n^2)$时间复杂度[^1] 2. **小数组优化**:当子数组长度小于设定阈值(如10)时,改用插入排序 3. **尾递归优化**:减少递归调用栈深度 ### 四、使用示例 ```java public static void main(String[] args) { int[] arr = {9, 7, 5, 11, 12, 2, 14, 3, 10, 6}; QuickSort.sort(arr); System.out.println(Arrays.toString(arr)); // 输出: [2, 3, 5, 6, 7, 9, 10, 11, 12, 14] } ``` ### 五、复杂度分析 - 平均时间复杂度:$O(n \log n)$ - 空间复杂度:$O(\log n)$(递归调用栈) - 不稳定排序算法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值