一、本博客主要內容
1、三相單詞樹的概念
2、三相單詞樹結構圖
3、三相單詞樹實現
(1)、三相單詞樹節點結構
(2)、三相單詞樹的插入
(3)、三相單詞樹的查找
(4)、三相單詞樹的刪除
4、三相單詞樹代碼鏈接
二、單詞樹的概念
1、三相單詞查找樹是單詞查找樹的該進,當R(字符表)很大時三相單詞樹可節省空間
2、三相單詞查找樹結構:
3、由鍵值key(字符),value(註釋),三個指針域構成(left,mid,right)
4、left的key–比key值小,mid的key–等於key值,right的key–大於key值
5、時間複雜度:O(1.39logN)
6、空間複雜度:64N-64NW
7、應用:適用於非隨機的鍵值
三、三相單詞樹的結構圖
四、單詞樹實現
1、單詞樹節點結構
struct TSTNode {
char _key;
string _value;
TSTNode* _left;
TSTNode* _mid;
TSTNode* _right;
TSTNode(char key = '0',string value = "")
:_key(key)
,_value(value)
,_left(NULL)
,_mid(NULL)
,_right(NULL)
{}
};
2、單詞樹的插入操作
1、三相進行逐位遞歸查找插入位置,
2、節點爲空則創建節點,並將該位字符插入其中
3、到達最後一個字符時,將註釋插入在該節點中
4、如果字符小於節點字符,則節點左 = 左遞歸
5、如果字符大於節點字符,則節點右 = 右遞歸
6、如果當前位不爲最後位(小於當前字符串長),節點mid = 遞歸中間分支同時位+1(查找下一個字符)
void put(string str, string value) {
_root = _put(_root, str, value,0);
}
Node* _put(Node* root, string str, string value, int bit) {
if (root == NULL) {
root = new Node(str[bit]);
}
if (root->_key > str[bit]) root->_left = _put(root->_left, str, value, bit);
else if (root->_key < str[bit]) root->_right = _put(root->_right, str, value, bit);
else if (bit < str.size()-1) //注-1是由於樹不含頭節點,bit從0算起
root->_mid = _put(root->_mid, str, value, bit + 1);
else root->_value = value; //表示已插入最後一個字符,則將註釋插入在最後一個字符處
return root;
}
3、三相單詞樹的查找操作
1、逐個字符查找,並每找個一個字符將字符拼接在一起,找到最後一個字符則返回該節點
2、節點爲空,則未找到
3、長度達到末尾時,如果節點的value值爲空,則返NULL。
4、小於節點字符,則左遞歸
5、大於節點字符,則右遞歸
6、等於節點字符,則遞歸中間分支,同時字符位置+1(查找下個字符)
注:每個位置遞歸都加return
string get(string str) {
Node* cur = _get(_root, str, 0);
if (cur) {
return cur->_value;
}
return "";
}
Node* _get(Node* root, string str, int bit) {
if (root == NULL) return NULL;
if (str[bit] < root->_key)
return _get(root->_left, str, bit);
else if (str[bit] > root->_key)
return _get(root->_right, str, bit);
else if (bit < str.size() - 1)
return _get(root->_mid, str, bit + 1);
else return root; //長度相同,返回該節點
}
4、三相單詞樹的刪除操作
1、遞歸查找,並且接收返回值(更新指針域)
2、先找到刪除節點,即到達最後一個字符位置,將該節點的value置爲“”
3、如果刪除節點的左右中指針域爲空,則刪除該節點,並返回NULL否則返回該節點
void deleteKye(string str) {
_deleteKey(_root, str,0);
}
Node* _deleteKey(Node* root, string str,int bit) {
if (root == NULL) return NULL;
if (root->_key > str[bit]) {
root->_left = _deleteKey(root->_left, str, bit);
}
else if (root->_key < str[bit]) {
root->_right = _deleteKey(root->_right, str, bit);
}
else if (bit < str.size()-1) {
root->_mid = _deleteKey(root->_mid, str, bit+1);
}
else {
root->_value = "";
}
if (root->_value.size() > 0) return root;
if (root->_left == NULL &&
root->_mid == NULL &&
root->_right == NULL) {
delete root;
return NULL;
}
return root;
}
5、三相單詞樹的其它操作與普通單詞樹操作類似,可參考單詞樹的實現(https://mp.csdn.net/mdeditor/85235977#)。
五、三向單詞樹完整代碼鏈接:https://github.com/weienjun/-algorithm/tree/master/TST