• 快速排序的递归方式和非递归方式


    我们知道快递排序大部分的版本都是递归的方式来实现的:通过Pritation来实现划分,并递归实现前后的划分。由于同学上次百度二面面试官问起快速排序的非递归的实现方式,当时同学不会,因为我们大部分看到的都是递归方式来实现快速排序。并没有关注非递归的方式。但是仔细想想也是可以做的,因为递归的本质是栈,因此我们非递归实现的过程中,借助栈来保存中间变量就可以实现非递归了。在这里中间变量也就是通过Pritation函数划分之后分成左右两部分的首尾指针,只需要保存这两部分的首尾指针即可。

    递归的方式显现如下:

    首先贴出Pritation函数的实现,因为递归和非递归都需要用到该函数,该函数实现的版本有多种,这里采用我比较熟悉的。

     1 int Pritation(int* a, int left, int right)
     2 {
     3     if (a == NULL || left < 0 || right <= 0||left>=right)
     4         return -1;
     5     int priot = a[left];
     6     int i = left, j = right;
     7     while (i < j)
     8     {
     9         while (i > j&&a[j] >= priot)
    10             j--;
    11         if(i<j)
    12             a[i]=a[j];
    13         while (i < j&&a[i] <= priot)
    14             i++;
    15         if(i<j)
    16             a[j]=a[i];
    17     }
    18     a[i] = priot;
    19     return i;
    20 }

      然后贴出递归的代码:(代码简洁明了)

     1 void QuickSort(int *a, int left,int right)
     2 {
     3     if (a == NULL || left < 0 || right <= 0 || left>right)
     4         return;
     5     int k = Pritation(a, i, j);
     6     //下面是递归实现的代码
     7     if (k > left)
     8         QuickSort(a, left, k - 1);
     9     if (k < right)
    10         QuickSort(a, k + 1, right);
    11 }

    最后贴出非递归的实现方式:

     1 void QuickSort(int *a, int left,int right)
     2 {
     3     if (a == NULL || left < 0 || right <= 0 || left>right)
     4         return;
     5     stack<int>temp;
     6     int i, j;
     7     //(注意保存顺序)先将初始状态的左右指针压栈
     8     temp.push(right);//先存右指针
     9     temp.push(left);//再存左指针
    10     while (!temp.empty())
    11     {
    12         i = temp.top();//先弹出左指针
    13         temp.pop();
    14         j = temp.top();//再弹出右指针
    15         temp.pop();
    16         if (i < j)
    17         {
    18             int k = Pritation(a, i, j);
    19             if (k > i)
    20             {
    21                 temp.push(k - 1);//保存中间变量
    22                 temp.push(i);  //保存中间变量 
    23             }
    24             if (j > k)
    25             {
    26                 temp.push(j);
    27                 temp.push(k + 1);
    28             }
    29         }
    30 
    31     }
    32     
    33 }

    从上面的代码可以看出,保存中间变量的时候需要注意保存的顺序,因为栈是后进先出的方式。

  • 相关阅读:
    I hate it [HDU 1754]
    K Besk [POJ 3111]
    Little Pony and Alohomora Part 3 [HihoCoder 1075]
    Shuffle 洗牌 [AHOI 2005]
    Qt打包程序
    linux用户相关命令介绍_用户密码与用户组相关命令_yum软件包相关_编译安装
    find查找条件_find处理动作_正则表达式_linux压缩命令_tar追加文件
    linux文本相关工具_文件权限相关_vim命令介绍_vim帮助信息
    linux目录介绍_目录命令介绍_文件增删改查_输入和输出
    linux系统命令linux命令介绍_bash特性_基础命令介绍
  • 原文地址:https://www.cnblogs.com/ljy2013/p/4003412.html
Copyright © 2020-2023  润新知