您好,登錄后才能下訂單哦!
本篇內容介紹了“c++二叉查找樹怎么使用”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
在數據順序存儲時 如果無序我們用順序查找, 有序時我們用折半查找法,插值查找法,斐波那契查找法。 但是當需要插入跟刪除
時就需要用到鏈式
存儲了 這時我們引入二叉排序樹(二叉搜索樹)。
線索二叉樹node->left .data < node.data < node->right.data;
中序遍歷時為遞增數列 InOrderTraverse;
刪除節點時 重點注意下;有4種
1.從node->left 找最大值替換node;
2.從node->right找最小值替換node;
3.將node->right整體移動到node->left最大值的右邊;
4.將node->left整體移動到node->right最小值的左邊;
不過考慮到樹的深度最好采用前兩種 這就設計到樹的左右節點平衡的問題了AVL樹
#include <iostream> #include <vector> using namespace std; typedef struct treenode { int data; struct treenode *left; struct treenode *right; }TREE_NODE;//節點 typedef struct Bstree { TREE_NODE* root; int size; }BSTREE;//二叉樹 BSTREE* create_tree() //創建 { BSTREE* tree = new(BSTREE); tree->root = NULL; tree->size = 0; return tree; } TREE_NODE* create_node(int data) //創建節點 { TREE_NODE* node =new(TREE_NODE); node->data = data; node->left = NULL; node->right = NULL; } void insert(TREE_NODE* node, TREE_NODE** root) //插入一個節點到那個位置 { if(NULL == *root) { *root = node; } else { if(node->data > (*root)->data) { insert(node, & (*root)->right); } else { insert(node, &(*root)->left); } } } void PreOrderTraverse(TREE_NODE* root) //先序遍歷 { if(root) { cout << root->data <<endl; PreOrderTraverse(root->left); PreOrderTraverse(root->right); } } void InOrderTraverse(TREE_NODE* root) //中序遍歷 { if(root) { InOrderTraverse(root->left); cout << root->data <<endl; InOrderTraverse(root->right); } } void PostOrderTraverse(TREE_NODE * root) //后序遍歷 { if(root) { PostOrderTraverse(root->left); PostOrderTraverse(root->right); cout << root->data <<endl; } } void bstree_insert(int data, BSTREE* tree) //插入一個節點 { insert(create_node(data), &tree->root); (tree->size)++; } TREE_NODE** bstree_find(int data, TREE_NODE** root) //查找DATA 對應的位置 { if(NULL==*root) { return root; } if(data >(*root)->data) { return bstree_find(data,& (*root)->right); } else if(data < (*root)->data) { return bstree_find(data, & (*root)->left); } else { return root; } //下面是非遞歸查找*root if(NULL==*root) { return root; } TREE_NODE* temp = *root; while(temp && ( temp->data !=data )) { if(data > temp->data) { temp = temp->right; } else if(data < temp->data) { temp = temp->left; } if(temp) { return &temp; } else { return &temp; } } } void del_node(TREE_NODE* node) //刪除 該節點 { delete(node); } bool bstree_erase(int data, BSTREE* tree) //樹中 插入 傳入的是地址 如果想修改 這一地址變量就要 根據地址的地址 修改 { TREE_NODE** node = bstree_find(data, & tree->root); if(*node) { TREE_NODE* temp = *node; if( ((*node)->right==NULL) &&((*node)->left==NULL))//如果為葉子節點 { *node = NULL; del_node(temp); --tree->size; } if(((*node)->right==NULL) &&((*node)->left!=NULL))//node的right為空 { *node = (*node)->left; del_node(temp); --tree->size; } else if(((*node)->right!=NULL) &&((*node)->left==NULL))//node的left為空 { *node = (*node)->right; del_node(temp); --tree->size; } //下面是左右子樹都不為空 刪除時任一種情況 最好用1 2 種 //node的左右都不為空將left中最大的數頂替已經刪除的node if(((*node)->left != NULL) && ((*node)->right != NULL)) { TREE_NODE* s = (*node)->left; while(s->right) { temp=s; s=s->right; } (*node)->data = s->data; if(temp != *node) { temp->righ = s->left; } else { temp->left =s->left;//類似左子樹 } del_node(s); --tree->size; } //node的左右都不為空將right中最小的數頂替已經刪除的node if(((*node)->left != NULL) && ((*node)->right != NULL)) { TREE_NODE* s = (*node)->right; while(s->left) { temp=s; s=s->left; } (*node)->data = s->data; if(temp != *node) { temp->left = s->right; } else { temp->right =s->right;//類似右子樹 } del_node(s); --tree->size; } //node的左右都不為空,直接將右邊整體移動到左邊最大值下面 if(((*node)->left != NULL) && ((*node)->right != NULL)) { TREE_NODE* s = (*node)->left; while(s->right) { s=s->right; } s->right = (*node)->right; *node = (*node)->left; del_node(s); --tree->size; } //node的左右都不為空,直接將左邊邊整體移動到右邊最小值下面 if(((*node)->left != NULL) && ((*node)->right != NULL)) { TREE_NODE* s = (*node)->right; while(s->left) { s=s->left; } s->left = (*node)->left; *node = (*node)->right; del_node(s); --tree->size; } return true; } return false; } void bstree_updata(BSTREE* tree,int old,int now) //新舊替換更新 { while(bstree_erase(old,tree)) { bstree_insert(now,tree); } } void clear_node(TREE_NODE** root) //清楚節點 { if(*root) { clear_node(&(*root)->left); clear_node(&(*root)->right); del_node(*root); *root = NULL; } } void clear_tree(BSTREE* tree) //clear_tree { clear_node(&tree->root); tree->size = 0; } void bstree_destroy(BSTREE* tree) //bstree_destroy { clear_tree(tree); delete(tree); } int bstree_size(BSTREE* tree) //大小 { return tree->size; } int bstree_deep(TREE_NODE* root) //深度DEPTH { if(root) { int Hleft = bstree_deep(root->left); int Hright = bstree_deep(root->right); return Hleft>Hright ? Hleft+1 : Hright+1; } return 0; } void printNodeByLevel(TREE_NODE* root) //層序遍歷 { if(root ==NULL) { return; } vector<TREE_NODE*>vec; vec.push_back(root); int cur=0; int last =1; while(cur<vec.size() ) { last = vec.size(); while(cur<last) { cout<<vec[cur]->data<<" "; if(vec[cur]->left != NULL) { vec.push_back(vec[cur]->left); } if(vec[cur]->right != NULL) { vec.push_back(vec[cur]->right); } ++cur; } cout<<endl; } } void print(TREE_NODE* root) { if(root==NULL) { return; } vector<TREE_NODE*>vec; vec.push_back(root); int cur=0; while(cur<vec.size()) { cout<<vec[cur]->data<<" "; if(vec[cur]->left != NULL) { vec.push_back(vec[cur]->left); } if(vec[cur]->right != NULL) { vec.push_back(vec[cur]->right); } ++cur; } cout<<endl; } int main() { BSTREE* tree = create_tree(); bstree_insert(5, tree); bstree_insert(6, tree); bstree_insert(2, tree); bstree_insert(1, tree); bstree_insert(4, tree); bstree_insert(3, tree); cout << "the level print:\n"; printNodeByLevel(tree->root); cout << "the first print:\n"; PreOrderTraverse(tree->root); cout << "the middle print:\n"; InOrderTraverse(tree->root); cout << "the endl print:\n"; PostOrderTraverse(tree->root); cout<<"the tree deep:\n"; cout<<bstree_deep(tree->root)<<endl; bstree_erase(2,tree); cout << "delete num of 2:\n"; cout << "after delete 2 print:\n"; PreOrderTraverse(tree->root); cout << "destroy the tree:\n"; bstree_destroy(tree); return 0; }
“c++二叉查找樹怎么使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。