3C科技 娛樂遊戲 美食旅遊 時尚美妝 親子育兒 生活休閒 金融理財 健康運動 寰宇綜合

Zi 字媒體

2017-07-25T20:27:27+00:00
加入好友
C++ Binary Search Tree(二元搜尋樹): Search(搜尋資料)、Insert(新增資料)、Sort(排序)、Delete(刪除資料) 資料來源:http://alrightchiu.github.io/SecondRound/binary-search-tree-searchsou-xun-zi-liao-insertxin-zeng-zi-liao.html https://github.com/alrightchiu/SecondRound/blob/master/content/Algorithms and Data Structures/Tree series/ExampleCode/BST_Search_Insert.cpp http://alrightchiu.github.io/SecondRound/binary-search-tree-sortpai-xu-deleteshan-chu-zi-liao.html GITHUB: https://github.com/jash-git/Cpp_Binary_Search_Tree main.cpp #include #include #include #include #include "BST.h" using namespace std; void Pause() {     printf("Press Enter key to continue…");     fgetc(stdin); } int main() {     BST T;     T.InsertBST(8,"龜仙人");     T.InsertBST(1000,"悟空");     T.InsertBST(2,"克林");     T.InsertBST(513,"比克");     cout << "Inorder Traversal:\n";     T.InorderPrint();     cout << endl << endl;     cout << "Level-order Traversal:\n";     T.Levelorder();     cout << endl << endl;     T.DeleteBST(8);         // 刪除龜仙人(8), 確認比克(513)會成為新的root     cout << "Level-order Traversal:\n";     T.Levelorder();     cout << endl << endl;     TreeNode *node = T.Search(1000);     if(node != NULL)     {         cout << "There is " << node->GetElement() << "(" << node->GetKey() << ")" << endl;     }     else     {         cout << "no element with Key(1000)" << endl;     }     node = T.Search(8);     if(node != NULL)     {         cout << "There is " << node->GetElement() << "(" << node->GetKey() << ")" << endl;     }     else     {         cout << "no element with Key(8)" << endl;     }     Pause();     return 0; } TreeNode.h #ifndef TREENODE_H #define TREENODE_H #include #include #include using std::string; using std::endl; class TreeNode{ private: TreeNode *leftchild; TreeNode *rightchild; TreeNode *parent; int key; string element; public: TreeNode(); TreeNode(int a, string b); int GetKey();// 為了在main()要能夠檢視node是否正確 string GetElement();// 才需要這兩個member function讀取private data // 其餘情況, 因為class BST是class TreeNode的friend class // 在class BST的member function中, 可以直接存取class TreeNode的private data friend class BST; // 放在 private 或 public 都可以 }; #endif // TREENODE_H TreeNode.cpp #include "TreeNode.h" TreeNode::TreeNode():leftchild(0),rightchild(0),parent(0),key(0),element("") { } TreeNode::TreeNode(int a, string b):leftchild(0),rightchild(0),parent(0),key(a),element(b) { } int TreeNode::GetKey() { return key; } string TreeNode::GetElement() { return element; } BST.h #ifndef BST_H #define BST_H #include "TreeNode.h" class BST {     private:         TreeNode *root;         TreeNode* Leftmost(TreeNode *current);         TreeNode* Successor(TreeNode *current);     public:         BST():root(0){};         TreeNode* Search(int key);         void InsertBST(int key, string element);         void InorderPrint();         void Levelorder();         void DeleteBST(int key); }; #endif // BST_H BST.cpp #include "BST.h" #include #include #include using std::string; using std::cout; using std::endl; TreeNode* BST::Search(int KEY) {     TreeNode *current = root;               // 將curent指向root作為traversal起點     while (current != NULL && KEY != current->key) {  // 兩種情況跳出迴圈:                                                   // 1.沒找到 2.有找到         if (KEY < current->key){             current = current->leftchild;   // 向左走         }         else {             current = current->rightchild;  // 向右走         }     }     return current; } void BST::InsertBST(int key, string element) {     TreeNode *y = 0;        // 準新手爸媽     TreeNode *x = 0;        // 哨兵     TreeNode *insert_node = new TreeNode(key, element);     x = root;     while (x != NULL) {                // 在while中, 以如同Search()的方式尋找適當的位置         y = x;         if (insert_node->key < x->key){             x = x->leftchild;         }         else{             x = x->rightchild;         }     }                                  // 跳出迴圈後, x即為NULL                                        // y即為insert_node的parent     insert_node->parent = y;           // 將insert_node的parent pointer指向y     if (y == NULL){                    // 下面一組if-else, 把insert_node接上BST         this->root = insert_node;     }     else if (insert_node->key < y->key){         y->leftchild = insert_node;     }     else{         y->rightchild = insert_node;     } } TreeNode* BST::Leftmost(TreeNode *current) {     while (current->leftchild != NULL){         current = current->leftchild;     }     return current; } TreeNode* BST::Successor(TreeNode *current){     if (current->rightchild != NULL){         return Leftmost(current->rightchild);     }     TreeNode *new_node = current->parent;     while (new_node != NULL && current == new_node->rightchild) {         current = new_node;         new_node = new_node->parent;     }     return new_node; } void BST::InorderPrint(){     TreeNode *current = new TreeNode;     current = Leftmost(root);     while(current){         cout << current->element << "(" << current->key << ")" << " ";         current = Successor(current);     } } void BST::Levelorder() {     std::queue q;     q.push(this->root);     // 把root作為level-order traversal之起點             // 推進queue中     while (!q.empty()){                     // 若queue不是空的, 表示還有node沒有visiting     TreeNode *current = q.front();      // 取出先進入queue的node     q.pop();     cout << current->element << "(" << current->key << ")" << " ";     if (current->leftchild != NULL){    // 若leftchild有資料, 將其推進queue             q.push(current->leftchild);         }         if (current->rightchild != NULL){   // 若rightchild有資料, 將其推進queue             q.push(current->rightchild);         }     } } void BST::DeleteBST(int KEY){               // 要刪除具有KEY的node     TreeNode *delete_node = Search(KEY);    // 先確認BST中是否有具有KEY的node     if (delete_node == NULL) {         std::cout << "data not found.\n";         return;     }     TreeNode *y = 0;      // 真正要被刪除並釋放記憶體的node     TreeNode *x = 0;      // 要被刪除的node的"child"     if (delete_node->leftchild == NULL || delete_node->rightchild == NULL){         y = delete_node;     }     else{         y = Successor(delete_node);        // 將y設成delete_node的Successor     }                                      // 經過這組if-else, y調整成至多只有一個child                                            // 全部調整成case1或case2來處理     if (y->leftchild != NULL){         x = y->leftchild;                  // 將x設成y的child, 可能是有效記憶體,     }                                      // 也有可能是NULL     else{         x = y->rightchild;     }     if (x != NULL){                        // 在y被刪除之前, 這個步驟把x接回BST         x->parent = y->parent;             // 此即為圖二(c)中, 把基紐接回龜仙人的步驟     }                                            // 接著再把要被釋放記憶體的node之"parent"指向新的child     if (y->parent == NULL){                // 若刪除的是原先的root, 就把x當成新的root         this->root = x;     }     else if (y == y->parent->leftchild){    // 若y原本是其parent之left child         y->parent->leftchild = x;           // 便把x皆在y的parent的left child, 取代y     }     else{                                   // 若y原本是其parent之right child         y->parent->rightchild = x;          // 便把x皆在y的parent的right child, 取代y     }                                             // 針對case3     if (y != delete_node) {                 // 若y是delete_node的替身, 最後要再將y的資料         delete_node->key = y->key;          // 放回delete_node的記憶體位置, 並將y的記憶體位置釋放         delete_node->element = y->element;  // 圖二(d), y即是達爾, delete_node即是西魯     }     delete y;                               // 將y的記憶體位置釋放     y = 0; } 心得: 沒有辦法用SQL時的備案方法

本文由jashliaoeuwordpress提供 原文連結

寫了 5860316篇文章,獲得 23313次喜歡
精彩推薦