首先因為關聯式容器中儲存的是鍵值對,我們需要對之前實現的紅黑樹進行改造。
修改模板引數:template
1. k代表key的型別
2. valuetype如果是map則表示鍵值對pair;如果是set則表示k。
3. keyofvalue:是通過valuetype獲取key值的乙個仿函式類,因為我們在進行插入操作需要比較大小時,操作的是鍵值對無法直接比較大小,需要通過仿函式來獲取要比較大小的值(key)來比較大小,仿函式就是在類中過載operator()函式,這樣我們可以通過:類名+(),即建立乙個該類的臨時物件,通過該臨時物件去訪問operator(),從而可以將類當做函式一樣來使用。
改造後的紅黑樹**:myrbtree.h
#pragma once
#include#includeusing namespace std;
enum color
;templatestruct rbnode
};templateclass iterator
iterator(const iterator& it)
:pnode(it.pnode)
{} t& operator*()
t* operator->()
iterator& operator++()
iterator& operator++(int)
iterator& operator--()
iterator& operator--(int)
bool operator!=(const iterator& it)
bool operator==(const iterator& it)
private:
void increasement()
}else
if (pnode->right != pparent)
}} void decreasement()
else if (pnode->right)
}else
pnode = pparent;
} }node* pnode;
};templateclass rbtree
_iterator end()
rbtree()
pair<_iterator, bool> insert(const t& value)
keyofvlaue keyofvalue;
node* parent = nullptr;
node* root = header->parent;
node* cur = root;
while (cur)
else if (keyofvalue(cur->val) < keyofvalue(value))
else
}cur = new node(value, red);
node* newnode = cur;
if (keyofvalue(parent->val) > keyofvalue(cur->val))
else
while (cur != root&&cur->parent->color == red)
else
rotater(grandpa);
parent->color = black;
grandpa->color = red;
break;}}
else
else
rotatel(grandpa);
parent->color = black;
grandpa->color = red;
break;}}
} header->parent->color = black;
header->left = leftmost();
header->right = rightmost();
return make_pair(_iterator(newnode), true);
} void rotater(node* parent)
subl->right = parent;
node* grandpa = parent->parent;
parent->parent = subl;
if (header->parent == parent)
else
else
subl->parent = grandpa;
} }void rotatel(node* parent)
subr->left = parent;
node* grandpa = parent->parent;
parent->parent = subr;
if (header->parent == parent)
else
else
subr->parent = grandpa;
} }node* leftmost()
while (cur->left)
return cur;
} node* rightmost()
while (cur->right)
return cur;
} void inorder()
bool empty()
bool isvalidrbtree()
if (black != root->color)
size_t blackcount = 0;
node* cur = root;
while (cur)
cur = cur->left;
} size_t k = 0;
_isvalidrbtree(root, k, blackcount);
}private:
node* header;
void _inorder(node* root)
_inorder(root->left);
cout << root->val << " ";
_inorder(root->right);
} bool _isvalidrbtree(node* root, size_t k, size_t blackcount)
if (black == root->color)
node* pparent = root->parent;
if (pparent&&pparent->color == red&&root->color == red)
if (nullptr == root->left&&nullptr == root->right)
}return _isvalidrbtree(root->left, k, blackcount) && _isvalidrbtree(root->right, k, blackcount);
}};
map模擬實現:mymap.h
#include"myrbtree.h"
templateclass map
};public:
typedef typename rbtree, keyofvalue>::_iterator iterator;
iterator begin()
iterator end()
bool empty() const
v& operator(const k& key)
pairinsert(const pair& kv)
private:
rbtree, keyofvalue> tree;
}; void testmap()
m[6];
m[7] = "seven";
it = m.begin();
while (it != m.end())
cout << m[4] << endl;
}
map的乙個特點就是過載了 operator 函式,而該函式的原理是,先插入,然後返回 value 值。
1. 我們先利用底層紅黑樹的插入,將鍵值對插入進去:tree.insert(make_pair(key,v()))
2. 紅黑樹的插入函式insert()返回的是pair鍵值對,該鍵值對的first值是乙個迭代器,也就是鍵值對pair的位置: (tree.insert(make_pair(key,v()))).first
3. 我們只要取出該鍵值對的second值,就是我們想要的value值: (*(tree.insert(make_pair(key,v()))).first).second
set的模擬實現:myset.h
set的模擬實現與map類似,只是沒有過載 operator 函式,而且插入的只是乙個key值
#include"myrbtree.h"
templateclass set
};public:
typedef typename rbtree::_iterator iterator;
iterator begin()
iterator end()
bool empty() const
pairinsert(const k& key)
private:
rbtreetree;
};void testset()
cout << endl;
}
模擬實現memcpy和memove
首先我們應該知道memcpy有什麼作用,他是乙個記憶體拷貝函式,函式原型如下 void memcpy void destination,const void source,size t num 它的作用就是將源拷貝到目標,拷貝num個位元組。下面看具體 實現。void mymemcopy void ...
模擬實現memcpy和memove
首先我們應該知道memcpy有什麼作用,他是乙個記憶體拷貝函式,函式原型如下 void memcpy void destination,const void source,size t num 它的作用就是將源拷貝到目標,拷貝num個位元組。下面看具體 實現。void mymemcopy void ...
模擬實現Spring IOC
通過在類上標註 registration 註冊進容器,injection從容器注入物件 容器類 public class springcontainer else bean.setbeanclass c mappropsmap new hashmap 處理注入屬性 field props c.get...