学习《算法导论》,学着写了二叉查找树。收获不少。
很多东西需要系统的学习呀。
- /********************************************************************
- created: 2008/12/09
- created: 9:12:2008 20:57
- file base: Main
- file ext: cpp
- author: Ai
- purpose: 练习二叉查找树
- *********************************************************************/
- #include <iostream>
- #include <algorithm>
- using namespace std;
- template<class T>
- class BSTree
- {
- struct Node
- {
- Node* left;
- Node* right;
- Node* parent;
- T key;
- Node(T k,Node* l,Node* r,Node* p):
- key(k),left(l),right(r),parent(p){}
- };
- Node* root;
- public:
- //构造函数
- BSTree(T date,Node* l = NULL,Node* r = NULL,Node* p = NULL):
- root(new Node(date,l,r,p)){}
- //析构函数
- ~BSTree()
- {
- DeleteTree(root);
- }
- Node* Insert(T date)
- {
- Node* Target = new Node(date,NULL,NULL,NULL);//需要插入的结点
- Node* NowParent = NULL;//存储父结点
- Node* NowNode = root;//用于遍历的结点
- while(NowNode != NULL)//查找可插入的位置
- {
- NowParent = NowNode;
- if(Target->key > NowNode->key)
- NowNode = NowNode->right;
- else
- NowNode = NowNode->left;
- }
- if(NowParent == NULL)//如果NowParent值为NULL,说明该树为空
- {
- root = Target;
- return root;
- }
- else//将目标结点插入到指定位置
- {
- Target->parent = NowParent;
- if(Target->key > NowParent->key)
- NowParent->right = Target;
- else
- NowParent->left = Target;
- return Target;
- }
- }
- Node* SearchNode(Node* NowNode,const T date)
- {
- if(NowNode == NULL || NowNode->key == date)//未找到返回NULL,找到返回该结点位置
- return NowNode;
- if(date > NowNode->key)
- SearchNode(NowNode->right,date);
- else
- SearchNode(NowNode->left,date);
- }
- Node* Max(Node* Target)
- {
- while(Target->right != NULL)
- Target = Target->right;
- return Target;
- }
- Node* Min(Node* Target)
- {
- while(Target->left != NULL)
- Target = Target->left;
- return Target;
- }
- void Print(const Node* TRoot) const//中序遍历输出
- {
- if(TRoot)
- {
- Print(TRoot->left);
- //copy(&TRoot->key,&TRoot->key+1,ostream_iterator<T>(cout));
- cout<<TRoot->key<<endl;
- Print(TRoot->right);
- }
- }
- const Node* GetRoot() const
- {
- return root;
- }
- void DeleteTree(Node* TRoot)
- {
- if(TRoot)
- {
- DeleteTree(TRoot->left);
- DeleteTree(TRoot->right);
- delete TRoot;
- TRoot = NULL;
- }
- }
- Node* Successor(Node* x)
- {
- if(x->right != NULL)//如果x结点存在有子女结点。那么返回其右子树最小结点
- return Min(x->right);
- Node* y = x->parent;
- while(y != NULL && x == y->right)//x没有右子女结点,那么向上查找直到找到某一结点是其父结点的左结点
- {
- x = y;
- y = y->parent;
- }
- return y;
- }
- void DeleteNode(T date)
- {
- Node* x = NULL;
- Node* y = NULL;
- Node* z = SearchNode(root,date);
- if(z->left == NULL || z->right == NULL)//确定要删除的结点y,该结点y或者是输入结点z,或者是z的后继
- y = z;
- else
- y = Successor(z);
- if(y->left != NULL)
- x = y->left;
- else
- x = y->right;
- if(x != NULL)//修改y->parenet和x中的指针将y删除
- x->parent = y->parent;
- if(y->parent == NULL)
- root = x;
- else if(y == y->parent->left)
- y->parent->left = x;
- else
- y->parent->right = x;
- if(y != z)//如果z的后继就是要被删除的结点,则将y中的内容复制到z中。
- z->key = y->key;
- delete y;
- }
- };
- int main()
- {
- BSTree<int> bst(15);
- bst.Insert(3);
- bst.Insert(5);
- bst.Insert(12);
- bst.Insert(10);
- bst.Insert(13);
- bst.Insert(6);
- bst.Insert(7);
- bst.Insert(16);
- bst.Insert(20);
- bst.Insert(18);
- bst.Insert(23);
- bst.Print(bst.GetRoot());
- cout<<"==============================="<<endl;
- bst.DeleteNode(15);
- bst.Print(bst.GetRoot());
- return 0;
- }