封装的一个sorted_vector示例,实现了stl::set的一部分接口

STL set能保证最坏情况下的查找和插入效率,logN。但是维护红黑树开销较大。set内的元素按照一定的逻辑顺序组织,查找、插入等操作的结果都和排序规则有关。

适合STL set的情况为: 1、集合很大,以至于O(N)远大于O(longN)。2、查找和插入的次数一样多,且需要考虑插入的效率。3、集合内的元素以随机顺序插入。4、查找和插入交叉进行。

在对插入效率要求不高,或者特定情况下插入效率可以接受时,使用sorted vector也可以实现O(longN)的查找。而且std的sort、lower_bound、upper_bound、binary_search方法,在支持随机存取的sorted vector上时间复杂度都是O(longN)。

封装了一个sorted vector的实现,不是很完善目前。

 1 #include <iterator>
 2 #include <iostream>
 3 #include "sorted_vector_algo.h"
 4 using namespace std;
 5
 6 using std::vector;
 7 using namespace sorted_vector_algo;  //将std的lower_bound等方法源码整理出来
 8 //using std::lower_bound; //二分查找,在有序数组上时间复杂度为O(logn)
 9 //using std::upper_bound;
10 /*
11  *std::sort采用的是成熟的"快速排序算法"(目前大部分STL版本已经不是采用简单的快速排序,而是结合内插排序算法)。
12  可以保证很好的平均性能、复杂度为n*log(n),由于单纯的快速排序在理论上有最差的情况,性能很低,其最坏算法复杂度为n*n,
13  但目前大部分的STL版本都已经在这方面做了优化。
14  std::stable_sort采用的是"归并排序",分派足够内存时,其算法复杂度为n*log(n), 否则其复杂度为n*log(n)*log(n),
15  其优点是会保持相等元素之间的相对位置在排序前后保持一致。
16  * */
17
18 template <class T, class Compare = std::less<T> >
19 struct sorted_vector {
20     vector<T> V;
21     Compare cmp;
22
23     typedef typename vector<T>::size_type size_type;
24     typedef typename vector<T>::iterator iterator;
25     typedef typename vector<T>::const_iterator const_iterator;
26     typedef typename vector<T>::reference reference;
27     typedef typename vector<T>::const_reference const_reference;
28     iterator begin() { return V.begin(); }
29     iterator end() { return V.end(); }
30     const_iterator begin() const { return V.begin(); }
31     const_iterator end() const { return V.end(); }
32
33     sorted_vector(const Compare& c = Compare()): V(), cmp(c) {}
34
35     template <class InputIterator>
36     sorted_vector(InputIterator first, InputIterator last,
37                 const Compare& c = Compare()): V(first, last), cmp(c)
38     {
39         std::sort(begin(), end(), cmp);
40     }
41
42     iterator insert(const T& t) {
43         iterator i = sorted_vector_algo::upper_bound(begin(), end(), t, cmp);
44         if (i == end() || cmp(t, *i))
45             V.insert(i, t);
46         return i;
47     }
48     iterator erase(const T& t) {
49         iterator i = std::lower_bound(begin(), end(), t, cmp);
50         iterator j = std::upper_bound(begin(), end(), t, cmp);
51
52         return V.erase(i, j);
53     }
54
55     //针对多维索引的属性值查找,需提供自定义的比较方法。只能查找当前容器中有序的属性值。
56     template <typename _Tp, class _Compare>
57     const_iterator find(const _Tp& t, _Compare cmp) {
58         const_iterator i = lower_bound(t, cmp);
59         return i == end() || cmp(t, *i) ? end() : i;
60     }
61
62     template <typename _Tp, typename _Compare>
63     iterator lower_bound (const _Tp& val, _Compare cmp) {
64         return  sorted_vector_algo::lower_bound(begin(), end(), val, cmp);
65     }
66
67     const_iterator find(const T& t) const {
68         const_iterator i =  sorted_vector_algo::lower_bound(begin(), end(), t, cmp);
69         return i == end() || cmp(t, *i) ? end() : i;
70     }
71
72     iterator lower_bound (const T& val) {
73         return  sorted_vector_algo::lower_bound(begin(), end(), val, cmp);
74     }
75     iterator upper_bound (const T& val) {
76         return  sorted_vector_algo::upper_bound(begin(), end(), val, cmp);
77     }
78
79     bool empty() const {
80         return V.empty();
81     }
82     reference operator[] (size_type n) {
83         return V[n];
84     }
85     const_reference operator[] (size_type n) const{
86         return V[n];
87     }
88
89     std::size_t size(){
90         return V.size();
91     }
92 };
时间: 2024-12-07 07:18:19

封装的一个sorted_vector示例,实现了stl::set的一部分接口的相关文章

自己封装的一个JS分享组件

因为工作的需求之前也封装过一个JS分享插件,集成了我们公司常用的几个分享平台. 但是总感觉之前的结构上很不理想,样式,行为揉成一起,心里想的做的完美,实际上总是很多的偏差,所以这次我对其进行了改版. 这次的核心就是:JS只负责事件+结构,也就是把功能实现出来,具体的外观样式,则使用者自己进行定义. 以下是新版分享插件的代码: 1 (function(root){ 2 'use strict'; 3 function share(params){ 4 5 this.params = params;

使用 ViewPager 和 RadioGroup 封装的一个导航控件

import android.animation.ObjectAnimator; import android.content.Context; import android.graphics.drawable.Drawable; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager;

JAVA套接字(Socket)101七天系列—第四天【一个简单示例】

一个简单示例  1. 背景 我们将在本部分讨论的示例将阐明在 Java 代码中如何使用 Socket 和 ServerSocket.客户机用Socket 连接到服务器.服务器用 ServerSocket 在端口 3000 侦听.客户机请求服务器 C: 驱动器上的文件内容. 为清楚起见,我们把示例分解成客户机端和服务器端.最后我们将把它们组合起来以使您能看到整体模样. 我们在使用 JDK 1.2 的 IBM VisualAge for Java 3.5 上开发这些代码.要自己创建这个示例,您应有完

文件操作的一个简单示例

在上文介绍了C中文件操作的一些基本函数,下面给一个简单例子,完成从控制台输入一段字符串,然后将其写入文件,然后从文件中读出刚刚写入的内容,代码如下: #include <stdio.h> #include <string.h> #include <stdlib.h> const int LENGTH=80; int main(void){ char mystr[LENGTH]; int lstr=0; int mychar=0; FILE * pfile=NULL; c

使用原生JS实现一个风箱式的demo,并封装了一个运动框架

声明,该DEMO依托于某个培训机构中,非常感谢这个培训结构.话不多说,现在开始改demo的制作. 首先,在前端的学习过程中,轮播图是我们一定要学习的,所以为了更加高效的实现各种轮播图,封装了一个运动的框架. 1 function getStyle(obj,attr) { 2 if(obj.currentStyle){ 3 return obj.currentStyle[attr];//为了获取IE下的属性值 4 }else{ 5 return window.getComputedStyle(ob

朋友封装的一个ASP.NET上传文件的方法

自我感觉封装得还不错!!! 代码如下: C#代码   #region 上传文件的方法 /// <summary> /// 上传文件方法 /// </summary> /// <param name="myFileUpload">上传控件ID</param> /// <param name="allowExtensions">允许上传的扩展文件名类型,如:string[] allowExtensions = 

在jsp提交表单的参数封装到一个方法里

建议去看一下孤傲苍狼写的Servlet+JSP+JavaBean开发模式(http://www.cnblogs.com/xdp-gacl/p/3902537.html), 最好把他JavaWeb学习总结全部看完会有很大的收获哦! 而把jsp专递的参数封装到一个方法里面也是从他那里学到的. 我觉得特别有用,尤其是在做项目的时候能省很多的代码  一: 需要的包 根据上一篇JDBC+Servlet+jsp(http://www.cnblogs.com/zhu520/p/6913650.html)的内容

自己封装的一个LoadRes组件

这两周一直太忙,没有好好处理上上上周遇到的一个让我加班到凌晨的问题,这个问题是判断flash的加载. 之前的思路是让flash的人在制作flash的时候,加入了一个回调方法,该方法再会回调我页面的方法. 想象虽然很丰满,但是现实确很骨感,由于页面资源的加载顺序问题,如果flash是通过缓存读取得到的,那么flash便会先于我的脚本加载,这时便会出现flash调不到我定义的方法.但是由于功能的原因以及考虑页面的整洁性,我又不能将脚本放入到head中,最终的解决思路就是在head中加入一个scrip

把XML文档中的每一本书封装到一个book对象,并把多个book对象放到一个list集合当中返回

1 package sax; 2 3 import java.awt.print.Book; 4 import java.io.IOException; 5 import java.util.ArrayList; 6 import java.util.List; 7 8 import javax.xml.parsers.ParserConfigurationException; 9 import javax.xml.parsers.SAXParser; 10 import javax.xml.p