2.4 插入、删除、唯一化和遍历

插入,不赘述,代码如下:

template <typename T>

Rank Vector<T>::insert(Rank r,T const& e) {

expand();

for (int i = _size; i > r; i--)

_elem[i] = elem[i-1];//复制原向量内容

_elem[r] = e;

_size++;

return r;

}

插入前,要使用expand()算法核实是否即将溢出,然后为了保证数组元素物理地址的连续性,将后缀_elem[r,_size)整体后移一个单位,这一步也是时间的主要消耗来源。后缀长度与所费时间是成线性正比的关系。一般地,若插入位置等概率分布,则平均运行时间为O(_size)=O(n)。

删除操作有两个接口:1.remove(r),即删除秩为r的单个元素;2.remove[lo,hi),删除区间为[lo,hi)的元素。所以我们免不了的要有这两个思考角度。删除一定区间范围的元素,是直接使用第二个接口呢?还是说对第一钟删除的接口操作进行重复调用从而达到异曲同工的目的。实际上,第二种做法是不可取的。因为数组中的元素地址是必须连续的,故而每次删除一个元素,都需要将所有后继元素向前移动一个单元,若后继元素共有m=_size-hi个,则对remove(r)的每次调用都需要移动m次;对于整个区间,移动的次数将会累计达到m*(hi-lo)个,既是后缀长度和待删除区间宽度的乘积。

那么,我们能否通过删除区间元素的接口来删除单个元素呢?即将删除单个元素作为删除整个区间元素的特例。答案是肯定的。这样做可以将移动操作的次数控制在O(m)以内。

区间删除即remoove[lo,hi)以及单元素删除即remove(r)的代码如下:

template <typename T> int Vector<T>::remove(Rank lo,Rank hi) {

if (lo == hi)

return 0;

while (hi <= _size)

_elem[lo++] = _elem[hi++];

_size = lo;

shrink();

return hi - lo;

}

template <typename T> T Vector<T>::remove(Rank r) {

T e = _elem[r];

remove(r,r + 1);

return e;

}

唯一化,使唯一,剔除重复元素。首先介绍无序向量的唯一化代码:

template <typename T> int Vector<T>::deduplicate() {

int oldSize = _size;

Rank i = 1;

while (i < _size)

(find(_elem[i], 0, i) < 0) ? i++ : remove(i);

return oldsize - _size;

}

简单易懂,故而跳过讲解。

无序向量的唯一化复杂度具有明显的单调性:随着循环的不断进行,当前元素的后继持续地严格减少。也就是说,经过n-2步迭代之后该算法必然终止。而该算法所主要消耗的时间在于find()和remove()两个接口。总体复杂度为O(n*n)。

遍历

遍历即使将向量作为一个整体,对其中所有元素实施某种统一的操作,比如输出向量中的所有元素,或者按照某种运算流程统一修改所有元素的数值。代码入下:

template <typename T> void Vector<T>::traverse(void (*visit)(T&)) {//借助函数指针机制遍历向量

for (int i = 0; i < _size; i++)

visit(_elem[i];)

}

template <typename T> template <typename VST>//元素类型、操作器

void Vector<T>::traverse(VST& visit) {//借助函数对象机制,遍历向量

for (int i = 0; i < _size; i++)

visit(_elem[i]);

}

前一种方法借助函数指针*visit()指定某一函数。该函数只有一个参数。其类型为对向量元素的引用。可以通过该函数即可直接访问或修改向量元素。

后一种方法借助函数对象的形式,指定具体的遍历操作。这类对象的操作符“()”经重载后,在形式上等效于一个函数接口。这种方式功能更强,使用范围更广。

原文地址:https://www.cnblogs.com/NK-007/p/9195789.html

时间: 2024-07-30 17:07:18

2.4 插入、删除、唯一化和遍历的相关文章

转 :asp教程.net c#数组遍历、排序、删除元素、插入、随机元素 数组遍历

asp教程.net c#数组遍历.排序.删除元素.插入.随机元素数组遍历 short[] sts={0,1,100,200};for(int i=0;i<sts.lenght;i++){  if(sts[i]>50) {  .....  }} 数组随机元素 public  hashtable  noorder(int count)         {             arraylist mylist = new arraylist();             hashtable ha

JavaScript之jQuery-3 jQuery操作DOM(查询、样式操作、遍历节点、创建插入删除、替换、复制)

一.jQuery操作DOM - 查询 html操作 - html(): 读取或修改节点的HTML内容,类似于JavaScript中的innerHTML属性 文本操作 - text(): 读取或修改节点的文本内容,类似于JavaScript中的textContent属性 值操作 - val(): 读取或修改节点的value属性值,类似于 JavaScript 中的value值 属性操作 - attr(): 读取或者修改节点的属性 - removeAttr(): 删除节点的属性 二.jQuery操作

双向循环链表 初始化 插入 删除

#include <stdio.h> #include <stdlib.h> #define OK 1 #define ERROR -1 #define TRUE 1 #define FALSE -1 #define NULL 0 #define OVERFLOW -2 #define ElemType int #define Status int typedef int ElemType typedef int Status #define LEN sizeof(DuLNode)

顺序表 初始化 插入 删除 查找 合并 交换 判断为空 求长度

#include <stdio.h> #include <stdlib.h> #define OK 1 #define TRUE 1 #define ERROR -1 #define FALSE -1 #define OVERFLOW -2 #define ElemType int #define Status int typedef int ElemType typedef int Status #define LEN sizeof(SqList) #define MLC (Li

静态链表 初始化 定位 Malloc Free 插入 删除

#include <stdio.h> #include <stdlib.h> #define OK 1 #define TRUE 1 #define ERROR -1 #define FALSE -1 #define OVERFLOW -2 #define ElemType int #define Status int typedef int ElemType typedef int Status #define MAX_SIZE 1000;//表最大空间 /* //线性表的基本操

单链表 初始化 创建 头插法 尾插法 插入 删除 查找 合并 长度

#include <stdio.h> #include <stdlib.h> #define OK 1 #define ERROR -1 #define TRUE 1 #define FALSE -1 #define NULL 0 #define OVERFLOW -2 #define ElemType int #define Status int typedef int ElemType typedef int Status #define LEN sizeof(LNode) #

leveldb源码分析--插入删除流程

由于网络上对leveldb的分析文章都比较丰富,一些基础概念和模型都介绍得比较多,所以本人就不再对这些概念以专门的篇幅进行介绍,本文主要以代码流程注释的方式. 首先我们从db的插入和删除开始以对整个体系有一个感性的认识,首先看插入: Status DB::Put(const WriteOptions& opt, const Slice& key, const Slice& value) { WriteBatch batch; //leveldb中不管单个插入还是多个插入都是以Wri

红黑树、插入删除操作

二叉排序树 一棵自平衡的二叉排序树(二叉搜索树) 生成二叉排序树的过程是非常容易失衡的,最坏的情况就是一边倒(只有右/左子树),这样会导致二叉树的检索效率大大降低(O(n)). 为了维持二叉树的平衡,有各种的算法,如:AVL,SBT,伸展树,TREAP ,红黑树等等. 红黑树 红黑树需要满足5条性质: - 节点非红即黑 - 根节点是黑色 - 所有NULL结点称为叶子节点,且认为颜色为黑 - 所有红节点的子节点都为黑色,一条路径上不能出现相邻的两个红色结点 - 从任一节点到其叶子节点的所有路径上都

2.5 有序向量的唯一化实现

有序向量的唯一化和无序向量不同,分为低效版和高效版.低效版代码如下: template <typename T> int Vector<T>::uniquify() { int oldSize = _size; int i = 1; while (i < _size) { _elem[i - 1] == _elem[i] ? remove(i) : i++; } return oldSize - _size; } 该算法的正确性在于有序算法中的重复元素必然是紧邻的,所以只要自