資料結構:二叉搜尋樹
阿新 • • 發佈:2019-02-19
實現的操作
1.0 插入:找待插入的節點的位置(data<_root->_data左子樹,data>_root->_data 右子樹)data為待插入節點的值。
2.0 尋找:找節點的位置(data<_root->_data左子樹,data>_root->_data 右子樹)data為待插入節點的值。
注意:尋找的時候先考慮等於的情況,插入則最後考慮,以上返回值都為bool型別
3.0 刪除:先找到待刪除節點的位置-->分情況刪除(如圖)
具體的二叉樹:
遞迴程式碼如下:
bstree.h
#pragma once #include<iostream> using namespace std; template<class T> class bstreeNode { public: bstreeNode(const T& data) : _data(data) , _left(NULL) , _right(NULL) {} bstreeNode(bstreeNode<T>& node) : _root->_data(node->data) , _root->_left(node->_left) , _root->_right(node->_right) {} bstreeNode<T>* _left; bstreeNode<T>* _right; T _data; }; template<class T> class bstree { typedef bstreeNode<T> Node; typedef Node* PNode; public: bstree() :_root(NULL) {} //中序遍歷 void InOrderTraverse() { _InOrderTraverse(_root); } bool Insert(const T& data) { return _Insert(_root, data); } //查詢 bool Find(const T& data) { return _Find(_root,data); } //刪除 bool Delete(const T& data) { return _Delete(_root, data); } ~bstree() { _clear(_root); } protected: ////插入(遞迴實現) //bool _Insert(PNode& _root, const T& data) //傳引用,修改了_root的值 //{ // if (NULL == _root)//樹為空 // { // _root = new Node(data); // if (NULL == _root) //new失敗 // return false; // return true; // } // else //非空 // { // if (data < _root->_data) // _Insert(_root->_left, data); // else if (_root->_data) // _Insert(_root->_right, data); // else //相等的情況 // return false; // } //} //插入(迴圈實現) bool _Insert(PNode& _root, const T& data) //傳引用,修改了_root的值 { if (NULL == _root)//樹為空 { _root = new Node(data); if (NULL == _root) //new失敗 return false; return true; } else //非空 { PNode PCur = _root; PNode parent = NULL; while (PCur) { if (data < _root->_data) { parent = PCur; PCur = PCur->_left; } else if (data> _root->_data) { parent = PCur; PCur = PCur->_right; } else //相等的情況 return false; } PCur = new Node(data); if (data > parent->_data) parent->_right = PCur; else parent->_left = PCur; } } //尋找(遞迴實現) /*bool _Find(PNode _root, const T& data) { if (NULL == _root) return false; if (_root->_data == data) return true; else if (data< _root->_data) _Find(_root->_left, data); else _Find(_root->_right, data); }*/ //尋找(迴圈實現) bool _Find(PNode _root, const T& data) { if (NULL == _root) return false; PNode PCur = _root; while (PCur) { if (PCur->_data == data) return true; else if (data < PCur->_data) PCur = PCur->_left; else PCur = PCur->_right; } if (NULL == PCur) return false; else return true; } //刪除(遞迴實現) //bool _Delete(PNode& _root,const T& data) //{ // if (NULL == _root) // return false; // if (data< _root->_data) // return _Delete(_root->_left, data); // else if (data> _root->_data) // return _Delete(_root->_right, data); // else //找到了待刪除的節點 // { // PNode PCur = _root; // if (PCur->_right ==NULL) // { // _root = PCur->_left; // delete PCur; // PCur = NULL; // } // else if (PCur->_left == NULL) // { // _root = PCur->_right; // delete PCur; // PCur = NULL; // } // else // { // PCur = PCur->_right; // while (PCur->_left) //確定待刪除節點的右子樹的最左側節點 // { // PCur = PCur->_left; // } // _root->_data = PCur->_data; // _Delete(_root->_right, PCur->_data); // } // return true; // } //} //刪除(迴圈實現) bool _Delete(PNode& _root, const T& data) { PNode PCur = _root; PNode parent = NULL; if (NULL == _root) return false; while (PCur) { if (PCur->_data == data) break; else if (data < PCur->_data) { parent = PCur; PCur = PCur->_left; } else { parent = PCur; PCur = PCur->_right; } } if (NULL == PCur) return false; else //找到了待刪除的節點 { if (PCur->_right == NULL) //該節點沒有左孩子,或者該節點為葉子結點 { if (PCur == _root) //待刪除節點為根節點 _root = PCur->_left; else //非根 { if (parent->_left == PCur) //待刪除節點為雙親節點的左孩子 parent->_left = PCur->_left; else //待刪除節點為雙親節點的右孩子 parent->_right = PCur->_left; } } else if (PCur->_left == NULL) { if (PCur == _root) //待刪除節點為根節點 _root = PCur->_right; else //非根 { if (parent->_left == PCur) //待刪除節點為雙親節點的左孩子 parent->_left = PCur->_right; else //待刪除節點為雙親節點的右孩子 parent->_right = PCur->_right; } } else { parent = NULL; PNode PDel = PCur->_right; while (PDel->_left) //確定待刪除節點的右子樹的最左側節點 { parent = PDel; PDel = PDel->_left; } PCur->_data = PDel->_data; if (parent->_left == PDel) //待刪除d的替代節點為雙親節點的左孩子 parent->_left = PDel->_right; if (parent->_right == PDel) //待刪除d的替代節點為雙親節點的右孩子 parent->_right = PDel->_right; PCur = PDel; } delete PCur; PCur = NULL; return true; } } void _clear(PNode& _Proot) { if (NULL == _Proot) return; _clear(_Proot->_left); _clear(_Proot->_right); delete _Proot; _Proot = NULL; } void _InOrderTraverse(PNode root) { if (NULL==root) return; _InOrderTraverse(root->_left); cout << root->_data << " "; _InOrderTraverse(root->_right); } private: PNode _root; }; void bstree_test() { bstree<int> bst; int arr[] = { 3, 2, 0, 5, 8, 7 }; int size = sizeof(arr) / sizeof(arr[0]); for (int i = 0; i < size; ++i) { bst.Insert(arr[i]); } bst.InOrderTraverse(); cout << endl; cout<<bst.Find(6)<<endl; cout<<bst.Find(2)<<endl; cout << bst.Delete(5)<< endl; bst.InOrderTraverse(); cout << endl; cout << bst.Delete(7) << endl; bst.InOrderTraverse(); cout << endl; cout << bst.Delete(8) << endl; bst.InOrderTraverse(); cout << endl; cout << bst.Delete(0) << endl; bst.InOrderTraverse(); cout << endl; cout << bst.Delete(3) << endl; bst.InOrderTraverse(); cout << endl; cout << bst.Delete(2) << endl; bst.InOrderTraverse(); }
main.cpp
#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include"bstree.h"
#include<iostream>
using namespace std;
int main()
{
bstree_test();
system("pause");
return 0;
}
結果: