快速排序法 (quick sort)是运用分治思想(divide and conquer)对一个数组进行排序的比较排序算法。它主要思想是:以某个数为轴,将这个数组划分成两部分:不大于这个轴的一部分和大于这个轴的一部分;然后在分别对剩下的两部分进行同样的操作;一直分下去,直到每部分只有一个元素位置为止。
如何划分成两部分?严蔚敏的《数据结构》和《算法导论》有两种不同的具体实现
【严】的描述如下:设置两个数组下标low,high,low从前向后移动,high从后往前移动,保证low之前的部分都是不大于轴,high之后的部分都是大于轴; 每次low找到一个大于轴的元素,high找到一个不大于轴的元素,交换这两个元素的位置。如果low等于high了,则把这个位置和轴所在地位置交换。
《算法导论》上的划分是这样的:也是给定两个数组下标i和j,i和j都从前往后移动; 保证i之前的部分都不大于轴,j之后的部分(包含j)都未知; j向后滑动中如果某个元素不大于轴,这把这个元素的位置和i交换,并且i向前移动一个位置. 当j到达末尾后,把轴的位置与i位置上的元素交换,i即为分界点。
如何非递归实现?一般书上的快速排序法都是用递归实现的,递归是编译器自动用栈来实现的。当递归层次比较深时,需要占用比较大的进程栈空间,还有进程栈溢出的危险。很多时候将递归转化为非递归算法,更省时间和空间。
其实原理很简单,即自己用栈来模拟递归的过程。每次从栈顶取出一部分做划分后,都把新的两部分的起始位置分别入栈。
c++算法实现如下(采用《算法导论》上的方法):
#ifndef MAX_STACK_DEPTH
#define MAX_STACK_DEPTH 1000
#endif
template <typename T>
void NonrecursiveQuickSort(T arr[], size_t size)
{
// typedef vector<int> Stack_t;
int stack[MAX_STACK_DEPTH];
int top = 0;
int low,high,i,j,pivot;
T temp;
//首先把整个数组入栈
stack[top++] = size-1;
stack[top++] = 0;
while(top != 0)
{
//取出栈顶元素,进行划分
low = stack[--top];
high = stack[--top];
pivot = high; //将最后一个元素作为轴
i = low; //保证i之前的元素的不大于轴
//j从前往后滑动
for(j=low; j < high; j++)
{
//如果碰到某个元素不大于轴,则与arr[i]交换
if(arr[j]<=arr[pivot])
{
temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
i++;
}
}
//i为分界点,交换arr[i]和轴
if(i != pivot)
{
/*swap arr[i] and arr[pivot]*/
temp = arr[i];
arr[i] = arr[pivot];
arr[pivot] = temp;
}
//判断小于轴的部分元素如果多于一个的话, 则入栈
if(i-low > 1)
{
stack[top++] = i-1;
stack[top++] = low;
}
//判断大于轴的部分元素如果多于一个的话, 则入栈
if(high-i > 1)
{
stack[top++] = high;
stack[top++] = i+1;
}
}
}
分享到:
相关推荐
快速排序是一种高效的排序算法,由英国计算机科学家C.A.R....总的来说,这个压缩包提供了一个非递归实现快速排序的完整示例,通过自定义栈的数据结构,实现了快速排序算法,适用于理解和学习快速排序的非递归实现方式。
总的来说,非递归快速排序是一种利用栈来实现的高效排序方法,它通过模拟递归过程,避免了递归调用的开销,适用于处理大规模数据。理解并熟练掌握这种算法,对于提升编程能力尤其是算法设计与分析能力非常有帮助。
### JAVA快速排序(递归实现与非递归堆栈模拟实现) #### 一、递归实现的快速排序 快速排序是一种非常高效的排序算法,它的基本思想是通过一趟排序将待排记录分隔成独立的两部分,其中一部分的所有记录都比另一...
用栈实现的快速排序,避免了原来的递归算法
在本主题中,我们将深入探讨快速选择的非递归和递归实现。 ### 快速选择的基本思想 快速选择的核心在于“分区”操作。首先,我们随机选择一个基准元素,然后将数组分为两部分:小于基准的元素和大于或等于基准的...
在C#中,实现非递归快速排序可以分为以下几个步骤: 1. **选择枢轴**:常见的方法是随机选择数组中的一个元素作为枢轴,这有助于避免最坏情况的发生,即数组已经有序。 2. **分区操作**:从数组的两端开始,一个...
快速排序算法设计与分析总结 二叉树与树的转换前序、后序的递归、非递归算法,层次序的非递归算法的实现 二叉树与树的转换前序、后序的递归、非递归算法,层次序的非递归算法的实现,应包含建树的实现 实现树与...
快速排序是一种高效的排序算法,由英国计算机科学家C.A.R. Hoare在1960年提出。它的基本思想是分治法,通过一趟排序将待排序的数据分割...但是,由于没有递归调用的开销,非递归快速排序在平均性能上通常优于递归版本。
用非递归算法实现quicksort快速排序,高效
此文档是快速排序的递归与非递归的具体实现代码
以下是关于"插入排序、选择排序、希尔排序、堆排序、冒泡、双向冒泡、快速排序、归并排序、递归的归并排序、基数排序"这十大经典排序算法的详细解释: 1. 插入排序:插入排序是一种简单的排序算法,它通过构建有序...
在众多的排序算法中,有的采用递归方式实现,如快速排序、归并排序等,而有的则避免了递归,采用迭代的方式来完成。本主题探讨的是如何利用队列这种数据结构来实现非递归的排序方法。 队列是一种先进先出(FIFO,...
3. **递归排序**:对基准元素左右两边的子数组,分别调用快速排序方法,直到子数组只有一个或零个元素,递归结束。 下面是一个简单的Java实现: ```java public class QuickSort { public static void quickSort...
运用MATLAB实现的快速排序,作为自己的库函数,使用起来更为快速。
本主题聚焦于如何使用非递归方法实现这些功能,这通常能带来更好的性能和更低的内存消耗。 **插入函数** 插入函数的主要任务是在适当的位置插入一个元素到已有的数据结构中。常见的数据结构如数组、链表、栈、队列...
快速排序(Quick Sort)与二分查找...综上所述,快速排序和二分查找是两种基础且实用的算法,它们的递归和非递归实现各有特点。理解并掌握这两种算法及其不同实现方式,对于提升编程技能和解决实际问题具有重要意义。
二分搜索,也被称为折半查找,是一种在...通过理解二分搜索的递归和非递归实现,我们可以更好地掌握分治策略,并将其应用到其他算法中,如快速排序、归并排序等。同时,这也是提升编程能力,理解和解决问题的重要步骤。
常见的四种排序算法是:简单选择排序、冒泡排序...其中的快速排序的优势明显,一般使用递归方式实现,但遇到数据量大的情况则无法适用。实际工程中一般使用“非递归”方式实现。实际工程中一般使用“非递归”方式实现。
Hoare提出的分治策略,选取一个基准值,将数组分为小于基准值和大于基准值的两部分,然后递归地对这两部分进行快速排序。C#实现中,关键在于划分操作。快速排序平均时间复杂度为O(n log n),但在最坏情况下(输入...