Vector_h
#ifndef VECTOR_H
#define VECTOR_H #include <algorithm> template<typename Object>
class Vector
{
private:
int theSize; //实际数据大小
int theCapacity; //实际容器容量大小
Object *objects; //基本数组
public:
enum { SPACE_CAPACITY = }; //默认容量大小 explicit Vector(int initSize = ) //单参数构造函数要用explicit()避免类型在后台转换
: theSize(initSize), theCapacity(initSize + SPACE_CAPACITY) {
objects = new Object[theCapacity];
}
Vector(const Vector& rhs) : objects(NULL) { //复制构造函数--调用operator=对已有的Vector进行复制
operator = (rhs);
}
~Vector() {
delete[] objects;
} const Vector& operator = (const Vector& rhs) //重载赋值运算符
{
if (this != &rhs) //避免复制自身--混淆检验
{
delete []objects; //删除旧的内存空间
theSize = rhs.size(); //生成同样的样本大小
theCapacity = rhs.theCapacity; //生成同样的容量大小 objects = new Object[capacity()]; //生成与所复制的Vector同样容量的新数组
for (int k = ; k < size(); k++)
objects[k] = rhs.objects[k];
}
return *this;
} void resize(int newSize)
{
if (newSize > theCapacity) //重置大小
reserve(newSize * + ); //新大小
theSize = newSize;
} //扩容
void reserve(int newCapacity)
{
if (newCapacity < theSize) //至少和(样本大小)一样大
return; Object *oldArray = objects; //oldArray--用于复制旧数组内容
objects = new Object[newCapacity];
for (int k = ; k < theSize; k++)
objects[k] = oldArray[k]; theCapacity = newCapacity;
delete []oldArray;
} Object& operator[] (int index)
{
return objects[index];
}
const Object& operator[] (int index) const
{
return objects[index];
} bool empty() const {
return size() == ;
} int size() const {
return theSize;
}
int capacity() const {
return theCapacity;
}
//在数据尾端插入元素
void push_back(const Object& x) {
if (theSize == theCapacity)
reserve( * theCapacity + );
objects[theSize++] = x;
} //在index位置前端插入数据data
void insert(int index, const Object& data) {
if (theSize == theCapacity)
reserve( * theCapacity + );
for (int i = theSize; i >= index; i--) {
objects[i] = objects[i - ];
}
objects[index] = data;
theSize++;
} void pop_back() {
theSize--;
} //区间删除 [lo, hi) --- 左闭右开!! --- 删除索引从 1,2..k
int remove(int lo, int hi) {
if (lo == hi) return ;
while (hi < theSize) {
objects[lo++] = objects[hi++]; //[hi,theSize)顺次前移 hi-lo 位
}
theSize = lo;
return hi - lo; //返回被删除元素数目
}
//重载删除一个指定位置元素--删除r位置元素,[r,r+1). 如果先写删除单个元素函数,删除区间时会低效.
Object remove(int r) {
Object oldElem = objects[r];
remove(r, r + );
return oldElem; //返回删除的元素
} //order the vector
//二分查找--有序向量
int Search(Object &elem, int lo, int hi) {
while (lo < hi) { //不变性: A[0,lo) <= e < A[hi,n)
int mid = (lo + hi) >> ; // 以中点为轴
(elem < objects[mid]) ? hi = mid : lo = mid + ; // [lo,mi) 或 (mi,hi)
} // 出口时,A[lo = hi]为大于elem的最小元素
return --lo; // lo-1即为不大于elem的元素的最大秩
} /*mergesort()归并排序
/*无序向量的递归分解,两个有序的子序列合成大的子序列*/
void mergeSort(int lo, int hi) {
if (hi - lo < ) return;
int mid = (lo + hi) >> ;
mergeSort(lo, mid); //对前半段排序
mergeSort(mid, hi); //对后半段排序
merge(lo, mid, hi); //归并
} //归并---O(nlogn), T(n) = 2T(n/2) + O(n)
void merge(int lo, int mid, int hi) {
//A用来存放合并后的向量,B,C进行比较(前后子向量比较)
Object *A = objects + lo; //合并后的向量A[0,hi-lo) = objects[lo,hi)
int lb = mid - lo;
Object *B = new Object[lb]; //前子向量 B[0,lb) = objects[lo,mi)
for (int i = ; i < lb; B[i] = A[i++]); //复制前子向量
int lc = hi - mid;
Object *C = objects + mid; //后子向量
for (int i = , j = , k = ; (j < lb || k < lc);) {
//B[i], C[k]中小者转至A的末尾.
//因为C本来就占据A中,不需要考虑提前耗尽情况
if ((j < lb) && (k >= lc || C[k] >= B[j])) //C[k]已无或不小
A[i++] = B[j++];
if ((k < lc) && (j >= lb || B[j] >= C[k])) //B[k]已无或不小
A[i++] = C[k++];
}
delete []B;
} //有序向量的去重, 重复的元素必定紧邻,每个区间只保留单个---每次常数,累计O(n)
int uniquify() {
int i = , j = ; //各对互异,"相邻"元素的秩,逐一扫描,直至末元素
while (++j < theSize) {
//跳过雷同者,发现不同元素时,向前移至紧邻元素
if (objects[i] != objects[j]) objects[++i] = objects[j];
}
theSize = ++i;
return j - i; //返回被删除元素总数
} //得到尾元素
const Object& back() const {
return objects[theSize - ];
} typedef Object * iterator;
typedef const Object * const_iterator; iterator begin() {
return &objects[];
}
const_iterator begin() const {
return &objects[];
}
iterator end() { //尾后的不存在的指针
return &objects[size()];
}
const_iterator end() const {
return &objects[size()];
} }; #endif // VECTOR_H
/************************************************************************/
/* Vs2013, c++11标准编写 测试vector.h */
/************************************************************************/
#include <iostream>
#include <cstring>
#include "Vector.h"
using namespace std; int test[] = { }; void Merge(int *test, int lo, int mid, int hi);
void MergeSort(int *test, int lo, int hi) {
if (hi - lo < ) return;
int mid = (lo + hi) >> ;
MergeSort(test, lo, mid); //对前半段排序
MergeSort(test, mid, hi); //对后半段排序
Merge(test, lo, mid, hi); //归并
} //归并---O(nlogn), T(n) = 2T(n/2) + O(n)
void Merge(int *test, int lo, int mid, int hi) {
//A用来存放合并后的向量,B,C进行比较(前后子向量比较)
int *A = test + lo; //合并后的向量A[0,hi-lo) = int s[lo,hi)
int lb = mid - lo;
int *B = new int [lb]; //前子向量 B[0,lb) = int s[lo,mi)
for (int i = ; i < lb; B[i] = A[i++]); //复制前子向量
int lc = hi - mid;
int *C = test + mid; //后子向量
for (int i = , j = , k = ; (j < lb || k < lc);) {
//B[i], C[k]中小者转至A的末尾.
//因为C本来就占据A中,不需要考虑提前耗尽情况
if ((j < lb) && (k >= lc || C[k] >= B[j])) //C[k]已无或不小
A[i++] = B[j++];
if ((k < lc) && (j >= lb || B[j] >= C[k])) //B[k]已无或不小
A[i++] = C[k++];
}
delete[]B;
} int main()
{
//用来测试 非模板写的 归并排序 算法
/*int Test[13] = { 1, 5, 2, 3, 6, 8, 9, 10, 13, 12, 4, 7, 11 };
MergeSort(Test, 0, 13);
for (int i = 0; i < 13; i++)
cout << Test[i] << " ";
cout << endl;*/ Vector<int> testOne;
int testData, cnt, index;
cout << "输入数字数目: ";
cin >> cnt;
cout << "输入 " << cnt << "个数: ";
while (cnt-- && cin >> testData)
{
testOne.push_back(testData);
} cout << "显示所有元素: ";
for (int i = ; i < testOne.size(); i++) {
cout << testOne[i] << " ";
}
cout << endl; cout << "\n输入插入元素位置(0...k)和插入的数值: ";
cin >> index >> testData;
testOne.insert(index, testData);
cout << "显示所有元素: ";
for (int i = ; i < testOne.size(); i++) {
cout << testOne[i] << " ";
}
cout << endl; cout << "\n输入删除元素位置(0...k): ";
cin >> index;
testOne.remove(index);
cout << "显示所有元素: ";
for (int i = ; i < testOne.size(); i++) {
cout << testOne[i] << " ";
}
cout << endl; cout << "\n归并排序向量元素: \n"; testOne.mergeSort(, testOne.size());
cout << "显示所有元素: ";
for (int i = ; i < testOne.size(); i++) {
cout << testOne[i] << " ";
}
cout << endl; cout << "\n(有序向量)(二分查找:)输入查找元素: ";
cin >> testData;
cout << "查找位置返回(不大于查找元素的最大的秩): "
<< testOne.Search(testData, , testOne.size()) << endl; cout << "\n(有序向量)去除重复元素: \n"; testOne.uniquify();
cout << "显示所有元素: ";
for (int i = ; i < testOne.size(); i++) {
cout << testOne[i] << " ";
}
cout << endl; return ; }
Vector_h的更多相关文章
- C++中vector的实现
注意几点: 分配内存不要使用new和delete,由于new的同一时候就把对象构造了.而我们须要的是原始内存. 所以应该使用标准库提供的allocator类来实现内存的控制.当然也能够重载ope ...
- vector的简易实现
vector的简易实现整理自<数据结构与算法分析–C++描述(第3版)>3.4节“向量的实现”.详细可参考<STL源码分析>4.2节. 具体实现代码如下: #ifndef VE ...
- Implementing a Dynamic Vector (Array) in C(使用c实现动态数组Vector)
An array (vector) is a common-place data type, used to hold and describe a collection of elements. T ...
- 纯C语言(C89)实现动态数组
起因 工作很少接触纯C项目,业余写着玩玩,不断雕琢 目标 纯C实现动态数组,提供方便易用泛型接口,避免依赖 实现 完全封装,隐藏结构体细节,不支持栈创建 拷贝存储,轻微性能代价换来易用性 vector ...
随机推荐
- 【C语言入门教程】7.1 结构体类型变量的定义和引用
前面学习了变量和数组这些简单的数据结构,它们的特点是必须使用规定的数据类型.例如数组被定义为整型后,它的所有存储单元都是由整型构成.现实生活中某一类事物的共同属性可能是由不同的数据类型组成的集合,或者 ...
- 15天学会jquery
第二章 15 Days of jQuery 比window.onload 更快一些的载入 window.onload()是传统javascript 里一个能吃苦耐劳的家伙.它长久以来一直 被程序员们作 ...
- 应用alter index ××× monitoring usage;语句监控索引使用与否
随着时间的累积,在没有很好的规划的情况下,数据库中也许会存在大量长期不被使用的索引,如果快速的定位这些索引以便清理便摆在案头.我们可以使用"alter index ××× monitorin ...
- (原创)android中使用相机的两种方式
在社交类应用或扫描二维码的场合都需要用到手机上的摄像头 在程序中启用这一硬件主要有两类方法 1.发送intent启动系统自带的摄像应用 此应用的AndroidManifest中的intent-filt ...
- windows下vim编辑器,字符编码设置。
在windows下的vim默认字符集修改 之前使用vim编辑器的时候碰到乱码的问题,后来在网上看了记下了:在vim编辑器中按esc进入命令模式 1.修改vim内部编码 set encoding= ...
- [RouterOS] ROS对接碧海威或PA等流控实现完美流控详细教程(附脚本全免费)
前言: 经常在群里看到不少朋友争论海蜘蛛 ROS 维盟 爱快 碧海威 流控大师 Woyos等等软路由,哪个好.实际上,网络产品是复杂的,现在的软路由功能上已经远远不是单独的路由了.每种产品都有他本身的 ...
- dp题目列表
此文转载别人,希望自己能够做完这些题目! 1.POJ动态规划题目列表 容易:1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 11 ...
- 搭建JavaWeb服务器
JDK安装可以参考 http://www.cnblogs.com/a2211009/p/4265225.html Tomcat安装可参考 1.由于服务器配置比较低综合考虑,选择ubuntu系统进行搭建 ...
- sql server 2008笔记
sql server 2008开启远程访问数据库 1.以windows验证模式进入数据库管理器. 第二步:右击sa,选择属性: 在常规选项卡中,重新填写密码和确认密码(改成个好记的).把强制实施密码策 ...
- struts2 配置 struts.xml 提示
1.这个提示通常是在 连网络的时候才可以看到 2.当没有网路的时候我们该如何配置呢? window -->preferences -->xml catelog -->user.... ...