博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++ STL 排序源码详解(一)
阅读量:2353 次
发布时间:2019-05-10

本文共 3659 字,大约阅读时间需要 12 分钟。

(全部以int类型的vector为处理对象)

     STL有关排序的几个函数如下所示,需要更少资源(时间和空间)的算法列在需要更多的前面,需要指出的是他们完成的工作是不一样的。

1. partition                  4. partial_sort

2. stable_partition      5. sort
3. nth_element           6. stable_sort

个人笔记:

        在快速排序中,切分函数是基本操作,那么在往后和往前移动的过程中存在边界判断的需要,由于排序中的这种边界判断,处在底层,如果能够取消,将极大提升效率,对此要有一定认识。特别注意,low<len-1 这样的边界判断有时是不需要的。之所以判断边界,是因为有可能容器中所有的元素都小于(或不小于)枢轴,也即都满足判断条件,会导致越界。这跟枢轴选取的方式有关系,如果可以断定枢轴会在待排序区出现,那么很大可能不会越界,这取决于等于枢轴是否满足调整条件。

一、partition

主要功能是将数据分成两部分,一部分满足条件,另一部分不满足条件。满足与否,是通过一个返回bool量的单参数函数实现的。

#include
#include
using namespace std;void swap(int &a,int &b){ int temp; temp = a; a = b; b = temp;}bool fun(int a) //判别函数{ int key = 5; return a < key;}int partition(vector
&vec,bool (*pred)(int)) //通过函数指针传入{ int len = vec.size(); if (len < 2) return 0; int low = 0; int hi = len - 1; while (true) { while ((low
0) && !((*pred)(vec[hi]))) { hi--; } if (low >= hi) break; swap(vec[low],vec[hi]); } return low;}void myprint(const vector
a){ for (int i = 0; i < a.size(); i++) { cout << a[i] << " "; } cout << endl;}int main(){ vector
data = {2,4,7,8,1}; myprint(data); partition(data,fun); myprint(data); system("pause"); return 0;}

二、nth_element

     void nth_element(vector<int> &vec, int num)   将最小(或最大)的num个数放在数组的开始处。注意num个数是无序的。

     主要是利用快速排序的切分操作,源码针对枢轴的选取了优化措施(取待处理区间首、中间、尾3个值中的中间值作为枢轴,防止切分操作退化),这里为了简化,没有对枢轴的选取进行优化。

      根据切分函数的返回值,判断是否达到了找出了num个满足要求的数,如果不满足,判断下一处理区间。

#include
#include
using namespace std;void swap(int &a, int &b){ int temp; temp = a; a = b; b = temp;}int partition(vector
&vec,int low,int hi){ int mid = (hi - low) / 2 + low; int pivot = vec[low]; int i = low + 1; int j = hi; while (true) { while (i < hi && vec[i] < pivot) i++; while (j>low && vec[j]>pivot) j--; if (i >= j) break; swap(vec[i], vec[j]); i++; j--; } swap(vec[low],vec[j]); return j;}void nth_element(vector
&vec, int num){ int len = vec.size(); int low = 0; int hi = len - 1; while (low
a){ for (int i = 0; i < a.size(); i++) { cout << a[i] << " "; } cout << endl;}int main(){ vector
data = { 11,5, 4, 7, 6, 8, 1,10 }; myprint(data); nth_element(data,2); myprint(data); system("pause"); return 0;}

三、partial_sort

void partial_sort(vector<int> &vec,int len)    将最小的前len个数放到数组最前面,并保持有序

局部排序的原理是,建立一个len大小的堆,初始时堆中数据就是数组的前len个数据,将剩余的数据逐个与堆顶的数据比较,如果小于堆顶数据,则交换,并调整堆,最后对堆进行排序。此方案可以实现nth_element函数,差别仅在于有没有最后一步排序。

#include
#include
using namespace std;void swap(int &a, int &b){ int temp; temp = a; a = b; b = temp;}void adjustHeap(vector
&vec,int len,int i){ int max = i; int left = 2 * i + 1; int right = 2 * i + 2; if (left
vec[max]) max = left; if (right
vec[max]) max = right; if (max != i) { swap(vec[i],vec[max]); adjustHeap(vec, len, max); }}void buildHeap(vector
&vec,int len){ if (len < 2) return; for (int i = len / 2 - 1; i >= 0; i--) { adjustHeap(vec, len, i); }}void sortHeap(vector
&vec,int len){ for (int i = len - 1; i>0; i--) { swap(vec[0],vec[i]); adjustHeap(vec,i,0); }}void partial_sort(vector
&vec,int len){ buildHeap(vec,len); for (int i = len; i < vec.size(); i++) { if (vec[0]>vec[i]) swap(vec[0], vec[i]); adjustHeap(vec,len,0); } sortHeap(vec,len);}void myprint(const vector
a){ for (int i = 0; i < a.size(); i++) { cout << a[i] << " "; } cout << endl;}int main(){ vector
data = { 11,5, 4, 7, 6, 8, 1,10 }; myprint(data); partial_sort(data, 4); myprint(data); system("pause"); return 0;}

转载地址:http://axwtb.baihongyu.com/

你可能感兴趣的文章
虚拟机性能监控与故障处理工具
查看>>
GIT的一些操作
查看>>
ZooKeeper 四字命令
查看>>
Mysql InnoDB锁问题
查看>>
ZooKeeper编程 基础教程
查看>>
Java 集合框架
查看>>
kafka 操作
查看>>
Java 集合框架 算法
查看>>
Java 集合框架 Set实现
查看>>
Java 集合框架 List实现
查看>>
Java 集合框架 Map 实现
查看>>
kafka 简单入门
查看>>
maven常用命令汇总
查看>>
Redis 方案
查看>>
ZooKeeper 数据与存储配置
查看>>
ZooKeeper 安装部署
查看>>
ZooKeeper 配置
查看>>
11.组合模式--Composite
查看>>
12.轻量模式--Flyweight
查看>>
13.外观模式--Facade
查看>>