- 浏览: 128648 次
- 性别:
- 来自: 成都
最新评论
-
yi_chao_jiang:
你好,多谢分享,问个问题,在上传数据的时候判断文件是否有上传记 ...
断点续传和下载原理分析 -
a41606709:
为什么我的tabhost显示不出来? 怎么设置在全部页面中让他 ...
TabActivity中的Tab标签详细设置 -
Zero颴:
大神篇,思路,配图都很清晰,perfect!
Android事件模型之interceptTouchEvnet ,onTouchEvent关系正解 -
QAZ503602501:
牛死人了!!!
B-树 -
mengsina:
很牛的文档。数学功底好啊
Android Matrix理论与应用详解
1.Set的简单实现
set是利用二叉查找树来实现的,而且为了查找方便,添加了另外两个指针,一个指向下一个最小结点,一个指向上一个最大结点。
iset.h
//利用二叉查找树实现set #ifndef ISET_H #define ISET_H template<class T> struct Node{ T data; Node<T> *rchild, *lchild; //左右孩子 Node<T> *parent; //父结点 Node<T> *next, *pre; //下一个最小和上一个最大的结点 Node(){ rchild = lchild = parent = 0; next = pre = 0; } }; template<class T> class ISet{ public: ISet(); ISet(T a[], int n); ~ISet(); int size(); bool isEmpty(); bool contains(T t); T* toArray(); void add(T t); void remove(T t); void addAll(T a[], int n); void removeAll(); void clear(); void print(); //下面实现迭代器 typedef Node<T>* iterator; typedef const Node<T>* const_iterator; iterator Iterator(); const_iterator Iterator() const; iterator next(); const_iterator next() const; iterator pre(); const_iterator pre() const; bool hasNext(); bool hasPre(); //还可以操作符重载,++,--,+实现通用的迭代器 private: Node<T>* root; Node<T> *head, *tail; //头(最小)和尾(最大) void clear(Node<T>* &root); int size(Node<T>* root); void print(Node<T>* root); void toArray(Node<T>* root, T* &a, int *i); void deleteNode(Node<T>* &root, Node<T>* r, Node<T>* pre);//删除结点p void preSet(Node<T>* t); void nextSet(Node<T>* t); }; #endif
iset.cpp
#include <iostream> #include "iset.h" using namespace std; template<class T> ISet<T>::ISet(){ head = tail = root = NULL; } template<class T> ISet<T>::ISet(T a[], int n){ head = tail = root = NULL; addAll(a, n); } template<class T> ISet<T>::~ISet(){ clear(); } template<class T> int ISet<T>::size(){ return size(root); } template<class T> bool ISet<T>::isEmpty(){ if(!root) return true; return false; } template<class T> bool ISet<T>::contains(T t){ Node<T>* r = root; while(r){ if(r->data == t) break; r = (r->data > t)?r->lchild:r->rchild; } //如果没找到,返回false if(!r) return false; return true; } template<class T> T* ISet<T>::toArray(){ T *a = new T[size()]; int i = 0; toArray(root, a, &i); return a; } template<class T> void ISet<T>::add(T x){ Node<T>* r = root, *m = NULL, *n = NULL; if(r == NULL){ Node<T>* t = new Node<T>; t->data = x; root = t;//必须设置新的root结点,因为t和root在内存指向位置不同 }else{ Node<T>* p = r; //查找待插入结点位置 while(r){ if(r->data == x){ return; } p = r; if(r->data > x){ n = r; r = r->lchild; }else{ m = r; r = r->rchild; } } Node<T>* t = new Node<T>; t->data = x; if(p->data > x){//插入左 p->lchild = t; p->pre = t; }else{ p->rchild = t; p->next = t; } t->parent = p; preSet(t); nextSet(t); if(m && m!=p) nextSet(m); if(n && n!=p) preSet(n); } } template<class T> void ISet<T>::remove(T x){ if(!root) return; Node<T>* pre = NULL, *r = root; //查找待删除结点位置(pre是r的前序结点) while(r){ if(r->data == x){ break; } pre = r; r = (r->data > x)?r->lchild:r->rchild; } //没找到 if(!r){ cout<<"没有待删除的值:"<<x<<endl; return;} //如果pre == NULL说明是root结点 deleteNode(root, r, pre); } template<class T> void ISet<T>::addAll(T a[], int n){ if(n <= 0) return; for(int i=0; i<n; i++){ add(a[i]); } } template<class T> void ISet<T>::removeAll(){ clear(); } template<class T> void ISet<T>::clear(){ clear(root); //注:当clear之后,root也被delete,故而重新置为NULL root = NULL; } template<class T> void ISet<T>::print(){ print(root); } template<class T> void ISet<T>::print(Node<T>* root){ if(root){ cout<<root->data<<" "; print(root->lchild); print(root->rchild); } } template<class T> void ISet<T>::clear(Node<T>* &root){ if(root){ clear(root->lchild); clear(root->rchild); delete root; } } template<class T> int ISet<T>::size(Node<T>* root){ if(!root) return 0; else{ return size(root->lchild)+size(root->rchild)+1; } } template<class T> void ISet<T>::toArray(Node<T>* root, T* &a, int *i){ if(root){ a[(*i)++] = root->data; toArray(root->lchild, a, i); toArray(root->rchild, a, i); } } //r为待删除结点,pre为r的双亲 template<class T> void ISet<T>::deleteNode(Node<T>* &root, Node<T>* r, Node<T>* pre){ Node<T>* p; //先修改待删除r的pre,next结点指针 if(r->pre){ r->pre->next = r->next; } if(r->next){ r->next->pre = r->pre; } if(!r->rchild && !r->lchild){ //如果是叶子结点 if(pre){ if(pre->lchild == r){ pre->lchild = NULL; }else{ pre->rchild = NULL; } }else{ root = NULL; } delete r; }else if(r->rchild && r->lchild){ //如果左右子树都有(还有一种处理办法就是用右子树的最左结点替换待删除结点,然后删除最左结点) p = r; //寻找右子树的最左结点 r = r->rchild; while(r->lchild){ r = r->lchild; } //将删除结点的左结点接到找到的最左结点之后 r->lchild = p->lchild; r->lchild->parent = r; //删除结点(如果pre是空,说明删除结点是根结点,不用改变前序结点指针) if(pre){ if(pre->lchild == p){ pre->lchild = p->rchild; }else{ pre->rchild = p->rchild; } p->rchild->parent = pre; }else{ p->rchild->parent = NULL; root = p->rchild; } delete p; }else if(r->lchild){ //如果只有左子树 p = r; if(pre){ if(pre->lchild == p) pre->lchild = r->lchild; else pre->rchild = r->lchild; r->lchild->parent = pre; }else{ r->lchild->parent = NULL; root = r->lchild; } delete p; }else{ //如果只有右子树 p = r; if(pre){ if(pre->lchild == p) pre->lchild = r->rchild; else pre->rchild = r->rchild; r->rchild->parent = pre; }else{ r->rchild->parent = NULL; root = r->rchild; } delete p; } } template<class T> void ISet<T>::preSet(Node<T>* t){ if(!t) return; Node<T>* p; //如果t有左孩子,则pre就是左孩子的最右结点 p = t->lchild; if(p){ while(p->rchild){ p = p->rchild; } t->pre = p; }else{//p是空 p = t; if(!t->parent){ t->pre = NULL; }else if(t->parent->lchild == t){//若p为左孩子,则回朔,直到遇到结点是右孩子 while(p->parent){ if(p->parent->rchild == p) break; p = p->parent; } t->pre = p->parent; }else{ //若p为右孩子,则pre是其父 t->pre = t->parent; } } } template<class T> void ISet<T>::nextSet(Node<T>* t){ if(!t) return; Node<T>* p; //如果t有右孩子,则next就是有孩子的最左结点 p = t->rchild; if(p){ while(p->lchild){ p = p->lchild; } t->next = p; }else{ p = t; if(!t->parent){ t->next = NULL; }else if(t->parent->rchild == t){ while(p->parent){ if(p->parent->lchild == p) break; p = p->parent; } t->next = p->parent; }else{ t->next = p->parent; } } } template<class T> typename ISet<T>::iterator ISet<T>::Iterator(){ if(!root) return NULL; Node<T>* p = root; while(p->lchild){ p = p->lchild; } head = p; p = root; while(p->rchild){ p = p->rchild; } tail = p; return head; } template<class T> typename ISet<T>::const_iterator ISet<T>::Iterator() const{ if(!root) return NULL; Node<T>* p = root; while(p->lchild){ p = p->lchild; } head = p; p = root; while(p->rchild){ p = p->rchild; } tail = p; return head; } template<class T> typename ISet<T>::iterator ISet<T>::next(){ Node<T>* t; if(head){ t = head; head = head->next; return t; } return NULL; } template<class T> typename ISet<T>::const_iterator ISet<T>::next() const{ Node<T>* t; if(head){ t = head; head = head->next; return t; } return NULL; } template<class T> typename ISet<T>::iterator ISet<T>::pre(){ Node<T>* t; if(tail){ t = tail; tail = tail->pre; return t; } return NULL; } template<class T> typename ISet<T>::const_iterator ISet<T>::pre() const{ Node<T>* t; if(tail){ t = tail; tail = tail->pre; return t; } return NULL; } template<class T> bool ISet<T>::hasNext(){ if(head) return true; return false; } template<class T> bool ISet<T>::hasPre(){ if(tail) return true; return false; }
main.cpp
#include <iostream> #include "iset.cpp" using namespace std; int main(){ int a[] = {19, 38,1,41,39,54,6,3}; ISet<int> s(a, 8); s.print(); cout<<endl; /* int n = s.size(); cout<<"size:"<<n<<endl; cout<<"isEmpty:"<<s.isEmpty()<<endl; cout<<"contains 4:"<<s.contains(4)<<endl; cout<<"contains 90:"<<s.contains(90)<<endl; int *k = new int[n]; k = s.toArray(); for(int i=0; i<n; i++){ cout<<k[i]<<" ";} cout<<endl; delete k; cout<<"添加5\n"; s.add(5); cout<<"size:"<<s.size()<<endl; s.print(); cout<<"\n添加10\n"; s.add(10); cout<<"size:"<<s.size()<<endl; s.print(); cout<<"\n删除10\n"; s.remove(10); s.print(); cout<<"\n添加三个集合(一个重合)"; int m[] = {4,12,6}; s.addAll(m, 3); cout<<"\nsize:"<<s.size()<<endl; s.print(); s.removeAll(); cout<<"\nsize:"<<s.size()<<endl; s.print(); */ ISet<int>::iterator ite = s.Iterator(); while(s.hasNext()){ cout<<s.next()->data<<" "; } s.remove(41); cout<<endl; ite = s.Iterator(); while(s.hasNext()){ cout<<s.next()->data<<" "; } s.add(10); cout<<endl; while(s.hasPre()){ cout<<s.pre()->data<<" "; } cout<<endl; return 0; }
2.Map的简单实现
map也是利用二叉树实现
imap.h
//二叉排序树 #ifndef IMAP_H #define IMAP_H //数据域,里面存放结点数据 template<class K, class V> struct Data{ K key; //结点数据 V value; }; template<class K, class V> struct Node{ Data<K, V> data; Node<K, V> *rchild, *lchild; Node(){ rchild = lchild = 0; } }; template<class K, class V> class IMap{ public: IMap(); ~IMap(); int size(); bool isEmpty(); bool containsKey(K key); bool containsValue(V value); V get(K key); void put(K key, V value); //若插入的值已经存在,则更新value V remove(K key); void clear(); void print(); private: Node<K, V>* root; Node<K, V>* pre;//用于递归插入时,记录前序结点 void print(Node<K, V>* root); void clear(Node<K, V>* &root); int size(Node<K, V>* root); void containsValue(Node<K, V>* root, V value, bool *b); void deleteNode(Node<K, V>* &root, Node<K, V>* r, Node<K, V>* pre);//删除结点p }; #endif
imap.cpp
#include <iostream> #include "imap.h" using namespace std; template<class K, class V> IMap<K, V>::IMap(){ pre = NULL; root = NULL; } template<class K, class V> IMap<K, V>::~IMap(){ clear(); } template<class K, class V> int IMap<K, V>::size(){ return size(root); } template<class K, class V> bool IMap<K, V>::isEmpty(){ if(!root) return true; return false; } template<class K, class V> bool IMap<K, V>::containsKey(K key){ Node<K, V>* r = root; while(r){ if(r->data.key == key) break; r = (r->data.key > key)?r->lchild:r->rchild; } //如果没找到,返回false if(!r) return false; return true; } template<class K, class V> bool IMap<K, V>::containsValue(V value){ bool b = false; containsValue(root, value, &b); return b; } template<class K, class V> V IMap<K, V>::get(K key){ Node<K, V>* r = root; while(r){ if(r->data.key == key) break; r = (r->data.key > key)?r->lchild:r->rchild; } if(!r) return 0; return r->data.value; } template<class K, class V> void IMap<K, V>::put(K key, V value){ cout<<"插入<"<<key<<", "<<value<<">\n"; Node<K, V>* r = root; if(r == NULL){ Node<K, V>* t = new Node<K, V>; t->data.key = key; t->data.value = value; t->lchild = t->rchild = NULL; root = t;//必须设置新的root结点,因为t和root在内存指向位置不同 }else{ Node<K, V>* p = r; //查找待插入结点位置 while(r){ //如果已经存在,则更新value if(r->data.key == key){ r->data.value = value; return; } p = r; r = (r->data.key > key)?r->lchild:r->rchild; } Node<K, V>* t = new Node<K, V>; t->data.key = key; t->data.value = value; t->lchild = t->rchild = NULL; if((p->data).key > key){//插入左 p->lchild = t; }else{ p->rchild = t; } } } template<class K, class V> V IMap<K, V>::remove(K key){ if(!root) return 0; Node<K, V>* pre = NULL, *r = root; //查找待删除结点位置(pre是r的前序结点) while(r){ if(r->data.key == key){ break; } pre = r; r = (r->data.key > key)?r->lchild:r->rchild; } //没找到 if(!r) return 0; //如果pre == NULL说明是root结点 deleteNode(root, r, pre); return r->data.value; } template<class K, class V> void IMap<K, V>::clear(){ clear(root); root = NULL; } template<class K, class V> void IMap<K, V>::print(){ print(root); } template<class K, class V> void IMap<K, V>::print(Node<K, V>* root){ if(root){ cout<<root->data.value<<" "; print(root->lchild); print(root->rchild); } } template<class K, class V> void IMap<K, V>::clear(Node<K, V>* &root){ if(root){ clear(root->lchild); clear(root->rchild); delete root; } } template<class K, class V> int IMap<K, V>::size(Node<K, V>* root){ if(!root) return 0; else{ return size(root->lchild)+size(root->rchild)+1; } } template<class K, class V> void IMap<K, V>::containsValue(Node<K, V>* root, V value, bool *b){ if(root){ if(root->data.value == value){ *b = true; return; } containsValue(root->lchild, value, b); containsValue(root->rchild, value, b); } } template<class K, class V> void IMap<K, V>::deleteNode(Node<K, V>* &root, Node<K, V>* r, Node<K, V>* pre){ Node<K, V>* p; if(!r->rchild && !r->lchild){ //如果是叶子结点 if(pre){ if(pre->lchild == r){ pre->lchild = NULL; }else{ pre->rchild = NULL; } }else{ root = NULL; } delete r; }else if(r->rchild && r->lchild){ //如果左右子树都有(还有一种处理办法就是用右子树的最左结点替换待删除结点,然后删除最左结点) p = r; //寻找右子树的最左结点 r = r->rchild; while(r->lchild){ r = r->lchild; } //将删除结点的左结点接到找到的最左结点之后 r->lchild = p->lchild; //删除结点(如果pre是空,说明删除结点是根结点,不用改变前序结点指针) if(pre){ if(pre->lchild == p) pre->lchild = p->rchild; else pre->rchild = p->rchild; }else{ root = p->rchild; } delete p; }else if(r->lchild){ //如果只有左子树 p = r; if(pre){ if(pre->lchild == p) pre->lchild = r->lchild; else pre->rchild = r->lchild; }else{ root = r->lchild; } delete p; }else{ //如果只有右子树 p = r; if(pre){ if(pre->lchild == p) pre->lchild = r->rchild; else pre->rchild = r->rchild; }else{ root = r->rchild; } delete p; } }
main.cpp
#include <iostream> #include "imap.cpp" using namespace std; int main(){ IMap<int, int> map; cout<<"当前map:"<<map.isEmpty()<<endl; cout<<"当前map长度:"<<map.size()<<endl; map.print(); int key[] = {0,1,2,3,4,5,6,7,8,9}; int value[] = {21,34,32,34,56,6,78,76,111,13}; for(int i=0; i<10; i++){ map.put(key[i], value[i]); } cout<<"当前map长度:"<<map.size()<<endl; map.print(); cout<<endl; bool b = map.containsKey(5); if(b) cout<<"包含键5:"<<map.get(5)<<endl; else cout<<"不包含键5\n"; b = map.containsKey(12); if(b) cout<<"包含键12:"<<map.get(12)<<endl; else cout<<"不包含键12\n"; b = map.containsValue(111); if(b) cout<<"包含值111:"<<111<<endl; else cout<<"不包含值111\n"; b = map.containsValue(211); if(b) cout<<"包含值211:"<<211<<endl; else cout<<"不包含值211\n"; cout<<"移除6\n"; map.remove(6); cout<<"当前map长度:"<<map.size()<<endl; map.print(); cout<<endl; cout<<"移除90\n"; map.remove(90); map.print(); cout<<endl; return 0; }
发表评论
-
排序方法总结
2012-08-12 11:34 1131这里面包含了所有常见的排序操作 1.性能等比较分析 2 ... -
常见字符串操作大全
2012-08-12 11:34 14161.常见的字符串操作 如计算长度,求子串等都是考验基本功的, ... -
KMP算法解析
2012-08-12 11:35 2773一.理论基础 1.什么 ... -
二叉堆的实现
2012-08-12 11:35 11721.堆的概念 这里只需要注意两点: a.堆的存储方式:就是 ... -
红黑树的插入总结
2012-08-10 11:25 9061.红黑树 这个在july的博客中有详尽的说明,我就不在赘述 ... -
B-树实现
2012-08-10 11:03 15861.什么是B-树? 这个在我的前一篇博客中已经详细的阐释过: ... -
平衡二叉树
2012-08-10 10:39 27931.问题描述 什么是平衡 ... -
二叉排序树
2012-08-10 10:25 14151.基本概念 二叉排 ... -
B-树
2012-07-04 22:48 56091.B-树的概念 是一种多 ... -
构造哈夫曼树
2012-07-04 10:40 11871.算法说明 就是建造哈夫曼树树,从而使得构造出的树带权路径 ... -
线索二叉树
2012-07-04 09:20 12371.算法描述 就是简单的线索二叉树的建立,遍历,查找等基本操 ... -
二叉树基本操作大全
2012-07-03 18:22 25541.二叉树的基本操作 这里我有一个疑问: 在使用构造 ... -
多种队列的实现
2012-06-29 10:09 14921.算法描述 a.数据结构与算法(Mark Allen We ... -
栈的各种实现
2012-06-28 16:34 10731.算法描述 a.实现二个栈,在一个数组里面,除非没有任何空 ... -
中缀表达式转换为后缀
2012-06-28 11:10 17501.算法描述 例如a+b*c这是常见的中缀表达式,但是 ... -
后缀表达式的值
2012-06-27 16:33 12891.算法描述 计算后缀表达式的值 2.事例 如:( ... -
Josephus问题
2012-06-21 15:30 9531.算法描述 简单的游戏:有N个人坐成一圈,编号1-N、从编 ... -
关于最长递增子序列的实际应用--动态规划
2012-06-07 11:35 1788参考链接: a.http://www.programfan. ... -
线性查找二维数组
2012-06-05 17:23 9991.算法描述 有序(行有序,列有序,且每行从左至右递增 ... -
整数的随机置换
2012-06-05 15:10 2230算法描述:生成前N个整 ...
相关推荐
unordered_map和unordered_set的模拟实现 (一)哈希表的特性及概念 定义: 哈希表(Hash table,也叫散列表),是根据关键字值(key,value)直接进行访问的数据结构。也就是说,它通过把关键字映射到表中一个位置来...
学习map和set的友友们如果对红黑树的底层框架很模糊。 可以借鉴一下本文件中的红黑树。 虽然有些地方写的不够全不够好, 但是基本的迭代器功能都已经实现。其实红黑树的学习主要就是学习它的插入, 最重要的就是...
麻雀虽小,五脏俱全 展示了一个JDK的BUG,有兴趣的朋友,可以看下噢 我也不知道算不算BUG,解决起来很简单,但这样似乎违背了JDK的本意
65、Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别 17 66、HashMap和Hashtable的区别 17 67、说出ArrayList,Vector, LinkedList的存储性能和特性 17 68、java中有几...
Hash Map通常在JavaScript中...Hash Map的简单实现: var hashMap = { Set : function(key,value){this[key] = value}, Get : function(key){return this[key]}, Contains : function(key){return this.Get(key
s1在之前介绍集合的时候没有提到,这⾥再提⼀下,这是允许有重复元素的STL集合,学名多级集合 m3就是⼀个多级映射,允许⼀个x对应多个y的情况,这样便于实现字典 我们⼀个⼀个介绍,s1就不介绍了,和set的⽤法完全⼀...
4.8.3 set和map的实现 4.8.4 使用几个map的例子 小结 练习 参考文献 第5章 散列 5.1 基本思想 5.2 散列函数 5.3 分离链接法 5.4 不使用链表的散列表 5.4.1 线性...
gocontainer实现了Java中存在但golang中缺少的一些容器。 这个库是零依赖的,这意味着它不依赖于任何第三方软件包。 当前,容器不是线程安全的。 目录 如何使用这个仓库 这非常简单,只需导入所需的容器,然后直接...
Java实现简单的智力测试系统,让你熟悉掌握和巩固Java Swing组件,Java输入速出相关知识,Java数组,Java Set,LIst,Map等相关操作
在集合框架中主要学习了List集合、Set集合和Map集合,并在项目ReadData类中实现。在MySQL中加强了对数据库的处理能力,学习了使用JDBC操作数据库,并在最后实现了DBUtils工具类。在网页技术学习中学习了HTML5的基本...
Java语言程序设计实验指导书 ...8 泛型与容器 编程实现set、list与map的简单应用。 9 图形用户界面 用图形界面工具,结合事件处理机制,实现一个可视化的计算器。 10 JDBC基础 使用JDBC方式执行数据库基本操作
libmap libmap是一个非常简单的库,用于在c中提供地图实现。 它们的键和值的类型为void*因此我们可以自由地包含任何键和值。 这种实现方式与项目排序无关,其好处是可以使我们更容易地左移而不留下任何漏洞。 之所以...
void set_color (int color); int difc (void); void print_map (void); void print_info (void); void inisnake (void); void inifood (void); void edge (void); int game_over (int way, int score);
4.8.3 set和map的实现 4.8.4 使用几个map的例子 小结 练习 参考文献 第5章 散列 5.1 基本思想 5.2 散列函数 5.3 分离链接法 5.4 不使用链表的散列表 ...
实现一个简单的深拷贝由于深拷贝的边界条件太多了(需要考虑原型、正则、Date、Map、Set、WeakMap、WeakSet等等情况),且没有遇到过必须要深拷贝
辨析List,Set和Map接口。 • 理解List接口,辨别使用List接口的实现类。 • 理解Set接口,辨别使用Set接口的实现类。 • 理解Map接口,辨别使用Map接口的实现类。 培养面向接口编程的思维...
在分发器初始化时通过反射读取控制器和其方法上指定URL添加到Map集合中.这需要一个注解@Mapping来指定URL 依次查看一下Controller -> Map, Controller> mapping -> @Mappting 实现参照 void inti() void ...
应用程序至少应该指明输入/输出的位置(路径),并通过实现合适的接口或抽象类提供map和reduce函数。再加上其他作业的参数,就构成了作业配置(job configuration)。然后,Hadoop的 job client提交作业(jar包/可...
Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边) 一个列表最多可以包含 232 – 1 个元素 (4294967295, 每个列表超过40亿个元素)。 实例 redis ...
configmap secret statefulset k8s特性 daemonset 与 job deployment管理与使用 pod管理与使用 k8s的存储 k8s的网络 labbel与labbel selector service服务发现 melm,rbac权限,k8s日志管理,监控方案1 melm...