快速排序partition过程常见的两种写法+快速排序非递归实现

简介:

这里不详细说明快速排序的原理,具体可参考here

快速排序主要是partition的过程,partition最常用有以下两种写法

第一种:

1
2
3
4
5
6
7
8
9
10
11
12
13
int  mypartition(vector< int >&arr, int  low, int  high)
{
     int  pivot = arr[low]; //选第一个元素作为枢纽元
     while (low < high)
     {
         while (low < high && arr[high] >= pivot)high--;
         arr[low] = arr[high]; //从后面开始找到第一个小于pivot的元素,放到low位置
         while (low < high && arr[low] <= pivot)low++;
         arr[high] = arr[low]; //从前面开始找到第一个大于pivot的元素,放到high位置
     }
     arr[low] = pivot; //最后枢纽元放到low的位置
     return  low;
}

 

 

第二种:

1
2
3
4
5
6
7
8
9
10
int  mypartition(vector< int >&arr, int  low, int  high)
{
     int  pivot = arr[high]; //选最后一个元素作为枢纽元
     int  location = low-1; //location指向比pivot小的元素段的尾部
     for ( int  i = low; i < high; i++) //比枢纽元小的元素依次放在前半部分
        if (arr[i] < pivot)
            swap(arr[i], arr[++location]);
     swap(arr[high], arr[location+1]);
     return  location+1;
}

 

当第二种方法也可以选择第一个元素作为枢纽(当我们对链表进行快排时选用这种做法),对上面代码稍作改动即可,具体改动见注释                         本文地址

1
2
3
4
5
6
7
8
9
10
11
int  mypartition(vector< int >&arr, int  low, int  high)
  {
      int  pivot = arr[low]; //选第一个元素作为枢纽元
      int  location = low; //location指向比pivot小的元素段的尾部
      for ( int  i = low+1; i <= high; i++) //比枢纽元小的元素依次放在前半部分
      if (arr[i] < pivot)
          swap(arr[i], arr[++location]);
      swap(arr[low], arr[location]); //注意和前面的区别,是为了保证交换到头部的元素比pivot小
      return  location;
 
  }

 

快排主函数如下:

1
2
3
4
5
6
7
8
9
void  quicksort(vector< int >&arr, int  low, int  high)
{
     if (low < high)
     {
         int  middle = mypartition(arr, low, high);
         quicksort(arr, low, middle-1);
         quicksort(arr, middle+1, high);
     }
}

 

快排非递归实现

主要思想是用栈来保存子数组的左右边界,一下代码中用数组模拟栈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void  quicksort_unrecursion(vector< int >&arr) //快速排序非递归
  {
      int  mystack[2000]; //假设递归不超过1000层
      //栈中保存下次需要排序的子数组的开始位置和结束位置
      int  top = -1;
      mystack[++top] = 0;
      mystack[++top] = arr.size() - 1;
      while (top > 0) //栈非空
      {
          int  high = mystack[top--], low = mystack[top--];
          int  middle = mypartition(arr, low, high);
          if (middle+1 < high) //右边子数组入栈
          {
              mystack[++top] = middle+1;
              mystack[++top] = high;
          }
          if (low < middle-1) //左边子数组入栈
          {
              mystack[++top] = low;
              mystack[++top] = middle-1;
          }
      }
  }





本文转自tenos博客园博客,原文链接:http://www.cnblogs.com/TenosDoIt/p/3665038.html,如需转载请自行联系原作者

目录
相关文章
|
Java 数据库连接 Spring
如何在Spring Boot中使用`@Retryable`注解来实现重试机制?
如何在Spring Boot中使用`@Retryable`注解来实现重试机制?
1243 0
如何在Spring Boot中使用`@Retryable`注解来实现重试机制?
|
11月前
|
存储 SQL 分布式计算
大数据-95 Spark 集群 SparkSQL Action与Transformation操作 详细解释与测试案例(一)
大数据-95 Spark 集群 SparkSQL Action与Transformation操作 详细解释与测试案例(一)
132 0
|
运维 监控 关系型数据库
全局事物服务GTS
【8月更文挑战第22天】
319 0
|
运维 架构师 安全
架构师养成手册:架构师职责
小米是一名热情的技术爱好者和架构师,他探讨了架构师的角色和职责。主要涉及六个方面:顶层设计,需与企业战略目标对齐,制定架构原则;规划可适应未来变化的企业架构,分析需求并关注技术趋势;全局视角制定可落地的架构方案,兼顾全局与局部优化;技术选型与难题解决,选择合适技术并解决实际问题;关注方案与代码的广度与深度,确保宏观设计与微观实现的统一;同时,架构师还需具备管理能力,包括团队协作、资源调配和风险管理。
381 11
|
机器学习/深度学习 Ubuntu PyTorch
Docker | 使用docker配置深度学习pytorch环境
Docker | 使用docker配置深度学习pytorch环境
3587 1
Docker | 使用docker配置深度学习pytorch环境
|
JavaScript 前端开发 UED
JavaScript中重排与重绘的区别及触发条件
JavaScript中重排与重绘的区别及触发条件
238 1
|
Linux Python
CentOS7下安装python3.8
环境的搭建是进行开发的第一步,python因为存在python2和python3两个版本,让在建立python环境时造成不便,并且由于在Linux环境下不像Window环境安装那么友好,存在一些小坑。本教程记录了CentOS7下安装python3.8的过程和注意事项。
2553 0
|
Web App开发 数据采集 JavaScript
面试官:请用纯 JS 实现,将 HTML 网页转换为图像
在工作时,需要实现一个功能:把一个HTML网页的转换为图像。我想到的第一个想法是使用第三方库,但像dom-to-image或使用Chrome Headless,如Puppeteer。那如何使用纯Javascript解决这种需求呢?
409 0
|
Web App开发 缓存 监控