C++ 模拟Map
来源:互联网 发布:最优化理论 编辑:程序博客网 时间:2024/06/08 16:35
JDK中的Map类型采用键值对的方式保存数据,且键(key)不能重复。在HashMap的实现中实际采用了Hash分类加数组排序的方式。在C++中我没有采用这样的算法。而是通过首先对Key值进行二叉树排序,再查找对应的Value。而对整个树型结构排序则使用最基本的中序遍历。这些都是数据结构的知识,不太了解的可以查看我之前的博客(查找树ADT)。下面言归正传。
假设场景是我需要输入一系列的人名+年龄,然后按照人名字典排序显示所有数据。以下是测试方法:
1 int main() { 2 using namespace std; 3 Item<string, int>* it1 = new Item<string, int>("Done", 18); 4 it1->put("Tom", 17); 5 it1->put("Kate", 15); 6 it1->put("Lory", 22); 7 it1->put("Xiaom", 14); 8 it1->put("Kate", 23); // 重复记录 9 10 cout << it1->size() << endl; // 結果:511 12 Item<string, int>* it2 = it1; // 调用拷贝构造13 Item<string, int>::Entry* ep = it2->sort(); // 获取数组指针14 15 for (int i = 0; i < it2->size(); i++) { // 遍历指针16 cout << ep[i].str_k << "=" << ep[i].str_v << endl;17 }18 return 0;19 }
(1)第8行添加了一条重复数据,应该覆盖第5行的数据。
(2)第12行调用拷贝函数,测试指针赋值是否正确。
(3)第15行遍历数组,查询数据。
下面是模板类的设计:
#ifndef ITEM_H_#define ITEM_H_#include <iostream>template<typename K, typename V>class Item {public: struct Entry { // 构造一个内部结构用来保存排序对象 K str_k; V str_v; };private: static int len; // 每次新增一个元素+1,作为size()的返回值 static int index; //返回数组的下标 K _key; // 键 V _value; // 值 Item* _left; // 左子树 Item* _right; // 右子树 void _sort(Item& item, Entry entry[]); // 内部排序方法public: Item(const K& key, const V& value) : _key(key), _value(value), _left(0), _right(0) { len++; } virtual ~Item() { // 析构左子树指针和右子树指针 if (_left != 0) delete _left; if (_right != 0) delete _right; } Item(const Item& o) : // 拷贝构造 _key(o._key), _value(o._value), _left(o._left), _right(o._right) { } Item& operator=(const Item& it) { // 默认赋值函数 _key = it._key; _value = it._value; if (_left != 0) delete _left; if (_right != 0) delete _right; _left = it._left; _right = it._right; return *this; } void put(const K& key, const V& value); V get(const K& key) const; int size() const; Entry* sort() { // 采用中序遍历方法排序 Entry* entry = new Entry[len]; _sort(*this, entry); return entry; }};template<typename K, typename V>int Item<K, V>::len = 0;template<typename K, typename V>int Item<K, V>::index = 0;template<typename K, typename V>void Item<K, V>::put(const K& key, const V& value) { if (key == _key) { _key = key; _value = value; } else if (key > _key) { if (_right == 0) { Item* r = new Item(key, value); _right = r; } else { _right->put(key, value); } } else if (key < _key) { if (_left == 0) { Item* l = new Item(key, value); _left = l; } else { _left->put(key, value); } }}template<typename K, typename V>V Item<K, V>::get(const K& key) const { if (key == _key) { return _value; } else if (key < _key) { if (_left == 0) { return 0; } else { _left->get(key); } } else if (key > _key) { if (_right == 0) { return 0; } else { _right->get(key); } }}template<typename K, typename V>int Item<K, V>::size() const { return len;}template<typename K, typename V>void Item<K, V>::_sort(Item& item, Entry entry[]) { if (item._left == 0) { entry[index].str_k = item._key; entry[index].str_v = item._value; index++; } else { _sort(*item._left, entry); entry[index].str_k = item._key; entry[index].str_v = item._value; index++; } if (item._right == 0) { return; } else { _sort(*item._right, entry); }}#endif /* ITEM_H_ */
部分注释我已经下载的代码中,这里做几点说明:
(1)二叉树排序的原则是先形成树根,然后新进入的数据与树根比较。如果小于树根则形成新的二叉树结构并放在左侧形成左子树。反之形成右子树。如果左子树(右子树)已经存在则采取递归的方式插入。
(2)二叉树遍历的原则是先处理左子树,再处理树根,最后处理右子树。同样也需要采用递归查询。
(3)C++不同于Java,最好是自己实现拷贝构造和重载赋值函数。通常情况下,拷贝构造和重载赋值函数效果相同,但在本例中大家可以看到。重载赋值函数需要首先对自己的左右子树的指针析构再赋值。
(4)由于C++编译方式的不同,类中的静态常量是不可以直接赋值的。需要在声明之后再定义数据,并且定义的顺序也很重要。
0 0
- Codeforces 583C GCD Table 模拟 map
- Gym 100625C 密文匹配-模拟题-(map)
- CodeForces - 659C Tanya and Toys (map&模拟)
- CodeForces - 670C Cinema (map&模拟)水
- Google Map模拟
- hdu - 4329 - MAP - 模拟
- 用 js模拟 Map
- js 模拟Map类
- js模拟Map
- HDU 5186 || 模拟map
- javascript模拟map
- js模拟Map
- javascript模拟实现Map
- JS模拟Map(2)
- zjnu1707 TOPOVI (map+模拟)
- 【NOIP模拟】Map
- C++ 模拟Map
- disney (map模拟)
- 第十五周—C语言 项目2(学生成绩管理)
- MySQL主从复制(Master-Slave)【详讲】
- sublime应用
- linux环境下,solr6.30整合tomcat8完整过程
- css超过一定宽度显示点点
- C++ 模拟Map
- 常见OJ评判结果对照表,作为ACMer你懂得!
- Git之忽略文件篇
- Android服务Binder实现小记
- Node.js入门到精通(6)异步IO
- 141. Linked List Cycle#2(Done)
- Ubuntu(Linux系统)虚拟机工具vmtools详细说明
- PHP实现Excel导入
- final关键字详解