001-快速排序(C++实现)
快速排序的基本实现
快速排序算法是一种基于交换的高效的排序算法,它采用了分治法的思想:
1、从数列中取出一个数作为基准数(枢轴,pivot)。
2、将数组进行划分(partition),将比基准数大的元素都移至枢轴右边,将小于等于基准数的元素都移至枢轴左边。
3、再对左右的子区间重复第二步的划分操作,直至每个子区间只有一个元素。
快排最重要的一步就是划分了。划分的过程用通俗的语言讲就是“挖坑”和“填坑”。
快速排序时间复杂度
快速排序的时间复杂度在最坏情况下是O(N2),平均的时间复杂度是O(N*lgN)。
这句话很好理解:假设被排序的数列中有N个数。遍历一次的时间复杂度是O(N),需要遍历多少次呢?至少lg(N+1)次,最多N次。
(01) 为什么最少是lg(N+1)次?快速排序是采用的分治法进行遍历的,我们将它看作一棵二叉树,它需要遍历的次数就是二叉树的深度,而根据完全二叉树的定义,它的深度至少是lg(N+1)。
因此,快速排序的遍历次数最少是lg(N+1)次。
(02) 为什么最多是N次?这个应该非常简单,还是将快速排序看作一棵二叉树,它的深度最大是N。因此,快读排序的遍历次数最多是N次。
快速排序稳定性
快速排序是不稳定的算法,它不满足稳定算法的定义。
算法稳定性 -- 假设在数列中存在a[i]=a[j],若在排序之前,a[i]在a[j]前面;并且排序之后,a[i]仍然在a[j]前面。则这个排序算法是稳定的!
快速排序 实现一:
int partition(int arr[], int left, int right) //找基准数 划分
{
int i = left + ;
int j = right;
int temp = arr[left]; while(i <= j)
{
while (arr[i] < temp)
{
i++;
}
while (arr[j] > temp )
{
j--;
}
if (i < j)
swap(arr[i++], arr[j--]);
else i++;
}
swap(arr[j], arr[left]);
return j; } void quick_sort(int arr[], int left, int right)
{
if (left > right)
return;
int j = partition(arr, left, right);
quick_sort(arr, left, j - );
quick_sort(arr, j + , right);
}
快速排序 实现方法二:
void QuickSort(int array[], int start, int last)
{
int i = start;
int j = last;
int temp = array[i];
if (i < j)
{
while (i < j)
{
//
while (i < j && array[j]>=temp )
j--;
if (i < j)
{
array[i] = array[j];
i++;
} while (i < j && temp > array[i])
i++;
if (i < j)
{
array[j] = array[i];
j--;
} }
//把基准数放到i位置
array[i] = temp;
//递归方法
QuickSort(array, start, i - );
QuickSort(array, i + , last);
}
}
快速排序 用C++函数模板实现
template<typename T>
void quicksort(T data[], int first, int last)
{
int lower = first + ;
int upper = last;
swap(data[first], data[(first + last) / ]);
T bound = data[first];
while (lower <= upper)
{
while (data[lower] < bound)
lower++;
while (data[upper] > bound)
upper--;
if (lower < upper)
swap(data[lower++], data[upper--]);
else lower++;
}
swap(data[upper], data[first]);
if (first < upper - )
quicksort(data, first, upper - );
if (upper + < last)
quicksort(data, upper + , last);
} template<class T>
void quicksort(T data[], int n)
{
int i, max;
if (n < )
return;
for (i = , max = ; i < n; i++)
if (data[max] < data[i])
max = i;
swap(data[n - ], data[max]);
quicksort(data, , n - ); //
}
快速排序 主函数测试代码
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <time.h>
using namespace std; void PrintArray(int array[], int len)
{
for (int i = ; i < len; i++)
{
cout << array[i] << " ";
}
cout << endl;
} int main(void)
{
const int NUM = ;
int array[NUM] = { };
srand((unsigned int)time(nullptr));
for (int i = ; i < NUM; i++)
{
array[i] = rand() % + ;
}
cout << "排序前:" << endl;
PrintArray(array, NUM);
cout << "排序后:" << endl;
quicksort(array, , NUM - );
PrintArray(array, NUM); return ;
}
001-快速排序(C++实现)的更多相关文章
- [C#][算法] 用菜鸟的思维学习算法 -- 马桶排序、冒泡排序和快速排序
用菜鸟的思维学习算法 -- 马桶排序.冒泡排序和快速排序 [博主]反骨仔 [来源]http://www.cnblogs.com/liqingwen/p/4994261.html 目录 马桶排序(令人 ...
- 算法与数据结构(十六) 快速排序(Swift 3.0版)
上篇博客我们主要聊了比较高效的归并排序算法,本篇博客我们就来介绍另一种高效的排序算法:快速排序.快速排序的思想与归并排序类似,都是采用分而治之的方式进行排序的.快速排序的思想主要是取出无序序列中第一个 ...
- [算法]——快速排序(Quick Sort)
顾名思义,快速排序(quick sort)速度十分快,时间复杂度为O(nlogn).虽然从此角度讲,也有很多排序算法如归并排序.堆排序甚至希尔排序等,都能达到如此快速,但是快速排序使用更加广泛,以至于 ...
- 排序算法----调用库函数qsort进行快速排序
功 能: 快速排序 头文件:stdlib.h 用 法: void qsort(void *base,int nelem,int width,int (*fcmp)(const void *,const ...
- Html5 快速排序演示
快速排序(Quicksort)是对冒泡排序的一种改进.快速排序由C. A. R. Hoare在1962年提出. 它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另 ...
- Java 快速排序两种实现
快速排序,只要学习过编程的人肯定都听说过这个名词,但是有时候写的时候还真蒙住了,网上搜罗了下以及查阅了"introduction to algorithm",暂时找到两种实现快排的 ...
- java基础算法之快速排序
快速排序(Quicksort)是对冒泡排序的一种改进.在大学学过之后现在基本忘了,最近在好多地方都看到说快速排序在面试会问到,于是自己也准备重新拾起以前忘记的东西来,慢慢的积累自己的基础知识.figh ...
- PAT 1045. 快速排序(25)
著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它的左边,比主元大的元素放到它的右边. 给定划分后的N个互不相同的正整数的排列,请问有多 ...
- 快速排序中的partition函数的枢纽元选择,代码细节,以及其标准实现
很多笔试面试都喜欢考察快排,叫你手写一个也不是啥事.我很早之前就学了这个,对快速排序的过程是很清楚的.但是最近自己尝试手写,发现之前对算法的细节把握不够精准,很多地方甚至只是大脑中的一个映像,而没有理 ...
- php冒泡排序和快速排序
如有错误,请指出... //快速排序(array_merge整合数组)function quick_sort($arr){ $num=count($arr); if($num<=1){ retu ...
随机推荐
- ping -l 1000 -t 与ping -t的区别
windows -l 1000的意思是规定发送的包的大小是1000字节如果不加这个参数的话,就发送包默认为32字节还有-t就是一直发送,直到手动停止
- 32位 64位 获得进程peb的方法
基于上一篇文章,大概了解了peb的获取方法,但是那个方法只能获得当前进程的PEB,不能获得其他的进程的PEB.根据那个思想,获得其他进程PEB则需要注入,得到进程信息,然后进程间通信,将信息返回来,经 ...
- python UI自动化实战记录七:页面2用例编写
使用python自带的unittest测试框架,用例继承自unittest.TestCase类. 1 引入接口类和页面类 2 setUp函数中打开页面,定义接口对象 3 tearDown函数中关闭页面 ...
- PHP------数组的遍历
echo current($attr); //取当前元素的value值 echo key($attr); //取当前元素的key next($attr); //将数组里面的指针指向下一个(向下移)pr ...
- protected internal 和internal 区别
private:只能在本类中使用protected:在本类中及其子类中可以使用 可以跨程序集 internal:同一命名空间(程序集)中的类可以使用 限定的是只有在同一个程序集中才可以访问,可以跨 ...
- mint-ui 填坑之路
swipe组件 因为项目加载eslint的缘故也就没有像之前的项目一样引用swiper框架.这个轮播图的组件文档实在是不敢恭维(尽管其他的文档也好不到哪里去),官方给出的参数真是少的可怜,一些方法也并 ...
- @RequestParam和@PathVariable的区别及其应用场景
@RequestParam和@PathVariable这两者之间区别不大,主要是请求的URL不一样 用@RequestParam请求接口时,URL是:http://www.test.com/user/ ...
- MFC自定义消息的实现方法
一.概述: 消息机制是windows程序的典型运行机制,在MFC中有很多已经封装好了的消息,如WM_BTN**等.但是在有些特殊情况下我们需要自定义一些消息去完成一些我们所需要的功能,这时候MFC的向 ...
- CentOS7 安装配置备忘录
1. 安装 epel 源 $ sudo yum install epel-release.noarch 如果想强制服务器使用 tuna 的镜像,可以如下修改 /etc/yum.repos.d/epel ...
- iview(DatePicker)时间转入后台少一天 解决方案
后台注解 前台: 加个事件 @on-change @on-change="getStartTime" getStartTime(starTime) { this.leaveReco ...