快速排序的递归和非递归实现 -----C++代码实现

快速排序的基本思想是:通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,已达到整个序列有序.

快速排序是一种不稳定的排序方法,其平均时间复杂度为:O(NlogN),最坏的情况是O(N*N)

特别注意:快速排序中用到的Partition函数,它的作用是进行一趟快速排序,返回“参考目标”的最终位置p,经过Partition处理之后,p左边的记录关键字均不大于参考目标,p右边的记录关键字均不小于参考目标。 Partition函数在找出数组中最大或最小的k个记录也很有用.

C++代码如下:

#include <iostream>
#include <vector>
#include <stack>

using namespace std;

template <typename Comparable>

int partition(vector<Comparable> &vec,int low, int high){
    Comparable pivot = vec[low];
    while (low<high)
    {
        while (low<high && vec[high]>=pivot)
        {
            high--;
        }
        vec[low] = vec[high];
        while (low <high&&vec[low]<=pivot)
        {
            low++;
        }
        vec[high] = vec[low];
    }
    vec[low] = pivot;
    return low;
}

//使用递归快速排序
template<typename Comparable>
void quicksort1(vector<Comparable> &vec,int low ,int high){
    if (low <high)
    {
        int mid = partition(vec, low, high);
        quicksort1(vec, low, mid - 1);
        quicksort1(vec, mid + 1, high);
    }

}

//其实就是用栈保存每一个待排序子串的首尾元素下标,下一次while循环时取出这个范围,对这段子序列进行partition操作,
//每次得到的mid都是vector的最终位置,知道栈中不需要放入,也没有数据时,循环结束
template<typename Comparable>
void quicksort2(vector<Comparable> &vec, int low, int high){
    stack<int> st;
    if (low<high)
    {
        int mid = partition(vec, low, high);
        if (low<mid-1)
        {
            st.push(low);
            st.push(mid - 1);
        }
        if (mid+1<high)
        {
            st.push(mid + 1);
            st.push(high);
        }

        while (!st.empty())
        {
            int q = st.top();
            st.pop();
            int p = st.top();
            st.pop();
            mid = partition(vec, p, q);
            if (p<mid-1)
            {
                st.push(p);
                st.push(mid - 1);
            }
            if (mid+1<q)
            {
                st.push(mid + 1);
                st.push(q);
            }
        }
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    int a[10] = { 12, 21, 33, 4, 50, 62, 71, 52,111,9 };
    vector<int> vec(a, a + 10);
    int len = vec.size();
    //quicksort1(vec, 0, len - 1);
    quicksort2(vec, 0, len - 1);
    for (int i=0; i < len;i++)
    {
        cout << vec[i]<< endl;
    }
    system("pause");
    return 0;
}
时间: 2024-10-25 13:13:57

快速排序的递归和非递归实现 -----C++代码实现的相关文章

每天刷个算法题20160525:快速排序的递归转非递归解法

版权所有.所有权利保留. 欢迎转载,转载时请注明出处: http://blog.csdn.net/xiaofei_it/article/details/51524798 为了防止思维僵化,每天刷个算法题.已经刷了几天了,现在发点代码. 我已经建了一个开源项目,每天的题目都在里面: https://github.com/Xiaofei-it/Algorithms 绝大部分算法都是我自己写的,没有参考网上通用代码.读者可能会觉得有的代码晦涩难懂,因为那是我自己的理解. 最近几天都是在写一些原来的东西

递归与非递归及其相互转换

一.什么是递归 递归是指某个函数直接或间接的调用自身.问题的求解过程就是划分成许多相同性质的子问题的求解,而小问题的求解过程可以很容易的求出,这些子问题的解就构成里原问题的解了. 二.递归的几个特点 1.递归式,就是如何将原问题划分成子问题. 2.递归出口,递归终止的条件,即最小子问题的求解,可以允许多个出口. 3.界函数,问题规模变化的函数,它保证递归的规模向出口条件靠拢 三.递归的运做机制 很明显,很多问题本身固有的性质就决定此类问题是递归定义,所以递归程序很直接算法程序结构清晰.思路明了.

算法之归并排序的递归与非递归的实现

一.什么是归并排序 归并排序就是将多个有序的数据段合成一个有序的数据段,如果参与合并的只有两个有序的数据段,则称为二路归并.与快速排序和堆排序相比,其最大的特点是一种稳定的算法,算法的平均时间复杂度O(nlog2n). 二.归并排序的基本思路 (1).对于一个原始的待排序表,可以将R[1]到R[n]可以看做是n个长度为1的有序表,即分解. (2).进行第一趟归并,即将上述的n个子序两两合并,得到 n/2向上取整 个有序表,若n为奇数,则归并到最后一个子序列长度为1,即合并. (3).再将两个 n

数据结构——二叉树遍历之“递归与非递归遍历”

简述 二叉树的遍历分为先序遍历.中序遍历和后序遍历.如下图所示: 递归遍历 private void bianli1(List<Integer> list, TreeNode root) { // 先序遍历 if (root == null) { return; } list.add(root.val); bianli1(list, root.left); bianli1(list, root.right); } private void bianli2(List<Integer>

JAVA递归、非递归遍历二叉树(转)

原文链接: JAVA递归.非递归遍历二叉树 import java.util.Stack; import java.util.HashMap; public class BinTree { private char date; private BinTree lchild; private BinTree rchild; public BinTree(char c) { date = c; } // 先序遍历递归 public static void preOrder(BinTree t) {

Java数据结构系列之——树(4):二叉树的中序遍历的递归与非递归实现

package tree.binarytree; import java.util.Stack; /** * 二叉树的中序遍历:递归与非递归实现 * * @author wl * */ public class BiTreeInOrder { // 中序遍历的递归实现 public static void biTreeInOrderByRecursion(BiTreeNode root) { if (root == null) { return; } biTreeInOrderByRecursi

二叉树遍历递归与非递归实现

说明:本文仅供学习交流,转载请标明出处,欢迎转载! 二叉树遍历是二叉树中非常基础的部分,也是学习二叉树必须熟练掌握的部分,下面我们先给出二叉树三种遍历方式的定义,并通过举例来说明二叉树遍历的过程. 二叉树的遍历分为:前序遍历(也叫先序遍历).中序遍历.后序遍历.所谓前.中.后都是根据当前子树根结点相对左右孩子的位置而言,也就是说: 前序遍历:根结点在前,即:根 ----->左------->右: 中序遍历:根结点在中间,即:左------>根------>右: 后序遍历:根结点在最

树的递归与非递归遍历总结

树的递归遍历遍历很简单,非递归遍历要复杂一些,非递归先序.中序.后序遍历需要用一个辅助栈,而层次遍历则需要一个辅助队列. 树的结构: 1 public class Tree<T> { 2 private T data; 3 private Tree<T> left; 4 private Tree<T> right; 5 ... 6 } 用策略模式定义一个访问工具: 1 public interface Visitor<T> { 2 void process(

全排列(递归与非递归实现)

全排列问题在公司笔试的时候很常见,这里介绍其递归与非递归实现. 递归算法 1.算法简述 简单地说:就是第一个数分别以后面的数进行交换 E.g:E = (a , b , c),则 prem(E)= a.perm(b,c)+ b.perm(a,c)+ c.perm(a,b) 然后a.perm(b,c)= ab.perm(c)+ ac.perm(b)= abc + acb.依次递归进行. void swap(string &pszStr,int k,int m) { if(k==m) return ;

二叉树三种遍历(递归以及非递归实现)

package com.shiyeqiang.tree; import java.util.Stack; public class BiTree { public static void main(String[] args) { // 首先构造叶子节点 BiTree leafA1 = new BiTree(4); BiTree leafA2 = new BiTree(5); BiTree leafB1 = new BiTree(6); BiTree leafB2 = new BiTree(7)