【二叉搜索树】

随机生成时平均深度为logN,平均插入、删除和搜索时间都是O(logN)。

可能存在的问题是数据不均衡,使树单边生长,极端情况下变成类似链表,最坏插入、删除、搜索时间O(N)

写这个例程也花了些时间,例程主要包括查找、插入、删除、遍历、清空几个内容。

同时避免之前写链表到了半途再修改,拷贝构造、拷贝赋值、析构也写成了深拷贝的模式。

光这两份代码在一起还无法运行,因为层序遍历那一块用了之前写的队列例程。

测试代码:

 #include <iostream>
#include "bstree.h"
using bstree::BSTree;
int main(void)
{
//测试插入
BSTree<int> number;
cout << "additem" << endl;
number.additem();number.additem();number.additem();number.additem();
number.additem();number.additem();number.additem();number.additem();
number.additem();number.additem();number.additem();number.additem();
number.additem();number.additem();number.additem();number.additem();
number.additem(); number.additem(); number.additem(); number.additem();
//打印
number.printpre();
cout << "--preorder"<<endl;
number.printin();
cout << "--inorder" << endl;
number.printpost();
cout << "--postorder" << endl;
number.printseq();
cout << "--seqorder" << endl; //测试拷贝构造函数
cout << "\ncopy constructor" << endl;
BSTree<int> number2(number);
number2.printpre();
cout << "--preorder" << endl;
number2.printin();
cout << "--inorder" << endl; //测试插入重复元素
cout << "\ncollision" << endl;
number.additem(); //删除测试
//删除节点没有右子树
cout << "\nremove number 3: iter->right = nullptr" << endl;
number.remove();
number.printpre();
cout << "--preorder" << endl;
number.printin();
cout << "--inorder" << endl; //删除测试
//删除节点的右子树没有左子树
cout << "\nremove number 15: iter->right->left = nullptr" << endl;
number.remove();
number.printpre();
cout << "--preorder" << endl;
number.printin();
cout << "--inorder" << endl; //删除测试
//删除节点的右子树有左子树
cout << "\nremove number 10: iter->right->left != nullptr" << endl;
number.remove();
number.printpre();
cout << "--preorder" << endl;
number.printin();
cout << "--inorder" << endl; //删除测试
//删除根
cout << "\nremove number 8: iter == root" << endl;
number.remove();
number.printpre();
cout << "--preorder" << endl;
number.printin();
cout << "--inorder" << endl; //删除测试
//删除不存在的元素
cout << "\nremove number not existed" << endl;
number.remove(); //查找最值
cout << "\nmax = " << number.findmax()->data << endl;
cout << "min = " << number.findmin()->data << endl; //清空树,并测试在空树下删除
cout << "\nclear" << endl;
number.clear();
number.remove(); system("pause");
}

实现代码:

 #ifndef BINARYSEARCHTREE
#define BINARYSEARCHTREE
#include <iostream>
#include "queue.h"
using queue::Queue;
using std::cout;
using std::cin;
using std::endl;
using std::string;
using std::flush;
namespace bstree
{
template <typename T> struct Node
{
Node<T>() : left(nullptr), right(nullptr){}
Node<T>(const T &item) : data(item), left(nullptr), right(nullptr){}
T data;
Node<T>* left;
Node<T>* right;
};
template <typename T> class BSTree
{
//构造函数
public:
BSTree() :nodes(), root(nullptr){}
BSTree(const BSTree& another)
{
root = nullptr;
nodes = ;
void(BSTree::*pf)(const Node<T>*);
pf = &BSTree::additem_from_another;
traverse_seq(another.root, pf);
}
~BSTree(){ clear(); }
BSTree& operator=(const BSTree& another)
{
if (&another != this)
{
clear();
void(BSTree::*pf)(const Node<T>*);
pf = &BSTree::additem_from_another;
traverse_seq(another.root, pf);
}
}
//接口
public:
//元素个数
unsigned int size()const{ return nodes; }
//是否空
bool empty()const{ return noodes == ; }
//获得根指针
Node<T>* getroot()const{ return root; }
//各种遍历
//前中后序使用辅助函数递归完成,层序遍历需使用队列结构
void printpre()const{ traverse(root, printnode, ); }
void printin()const{ traverse(root, printnode, ); }
void printpost()const{ traverse(root, printnode, ); }
void printseq()const{ traverse_seq(root, printnode); }
//#查找元素
Node<T>* find(const T &item)const;
//#查找最值
Node<T>* findmax()const;
Node<T>* findmin()const;
//#增加元素
bool additem(const T &item);
//#删除元素
bool remove(const T &item);
//清空树并将数据初始化
void clear(){ release(root); root = nullptr; nodes = ; } //辅助函数
private:
void release(Node<T>* iter);
Node<T>* find_prev(const T &item)const;
Node<T>* remove_node(Node<T>* iter);
void traverse(const Node<T>* iter, void(*fp)(const Node<T>*), int mode)const;
void traverse_seq(const Node<T>* iter, void(BSTree::*pf)(const Node<T>*));
void traverse_seq(const Node<T>* iter, void(*pf)(const Node<T>*))const;
void additem_from_another(const Node<T>* iter){ additem(iter->data); }
//数据
private:
Node<T>* root;
unsigned int nodes;
}; //辅助函数,打印节点元素
template <typename T> static void printnode(const Node<T>* iter){ cout << iter->data << " " << flush; }
//辅助函数
//查找元素的父树。如果树为空或元素为根,返回空指针;如果元素不存在,返回插入该元素时的父树
template <typename T> Node<T>* BSTree<T>::find_prev(const T &item)const
{
Node<T>* prev = nullptr;
Node<T>* curr = root;
while (curr != nullptr)
{
if (item < curr->data)
{
prev = curr;
curr = curr->left;
}
else if (item > curr->data)
{
prev = curr;
curr = curr->right;
}
else
break;
}
return prev;
}
//查找元素,如果元素不存在则返回空指针
template <typename T> Node<T>* BSTree<T>::find(const T &item)const
{
Node<T>* iter = find_prev(item);
if (iter == nullptr)
return root;
if (item < iter->data)
return iter->left;
else
return iter->right;
}
//查找最值
template <typename T> Node<T>* BSTree<T>::findmax()const
{
if (nodes == )
return nullptr;
Node<T>* iter = root;
while (iter->right != nullptr)
iter = iter->right;
return iter;
}
template <typename T> Node<T>* BSTree<T>::findmin()const
{
if (nodes == )
return nullptr;
Node<T>* iter = root;
while (iter->left != nullptr)
iter = iter->left;
return iter;
}
//插入元素,元素重复则报错
template <typename T> bool BSTree<T>::additem(const T &item)
{
Node<T>* prev = nullptr;
Node<T>* curr = root;
//找到待插入元素应该插入的位置
while (curr != nullptr)
{
if (item < curr->data)
{
prev = curr;
curr = curr->left;
}
else if (item > curr->data)
{
prev = curr;
curr = curr->right;
}
//元素相等导致冲突则报错
else
{
cout << "Elements collision!" << endl;
return false;
}
}
Node<T>* pnew = new Node<T>(item);
if (prev == nullptr)
root = pnew;
else if (item < prev->data)
prev->left = pnew;
else
prev->right = pnew;
++nodes;
return true; }
//删除元素
template <typename T> bool BSTree<T>::remove(const T &item)
{
if (nodes == )
{
cout << "Tree is empty!" << endl;
return false;
}
//函数主体执行查找操作
//查找到相应删除点后,交给remove_node()处理
Node<T>* iter = find_prev(item);
if (iter == nullptr)
{
if (root->data != item)
{
cout << "Not Found!" << endl;
return false;
}
root = remove_node(root);
}
else if (item < iter->data)
{
if (iter->left == nullptr)
{
cout << " Not Found!" << endl;
return false;
}
iter->left = remove_node(iter->left);
}
else
{
if (iter->right == nullptr)
{
cout << "Not Found!" << endl;
return false;
}
iter->right = remove_node(iter->right);
}
--nodes;
return true;
}
//辅助函数,删除具体节点
template <typename T> Node<T>* BSTree<T>::remove_node(Node<T>* iter)
{
//用即将被删除节点的右子树的最左边的子节点替代即将被删除的位置
//情况一,删除节点无右子树
if (iter->right == nullptr)
{
Node<T>* save = iter->left;
delete iter;
return save;
}
//情况二,删除节点的右子书无左子树
else if (iter->right->left == nullptr)
{
Node<T>* save = iter->right;
save->left = iter->left;
delete iter;
return save;
}
//情况三,删除节点的右子树有左子树
else
{
Node<T>* prev = iter->right;
Node<T>* curr = iter->right->left;
while (curr->left != nullptr)
{
prev = curr;
curr = curr->left;
}
prev->left = curr->right;
curr->left = iter->left;
curr->right = iter->right;
delete iter;
return curr;
}
}
//辅助函数,前中后遍历执行模式
template <typename T> void BSTree<T>::traverse(const Node<T>* iter, void(*fp)(const Node<T>*), int mode)const
{
if (iter == nullptr)
return;
if (mode == )
{
(*fp)(iter);
traverse(iter->left, fp, );
traverse(iter->right, fp, );
}
else if (mode == )
{
traverse(iter->left, fp, );
(*fp)(iter);
traverse(iter->right, fp, );
}
else if (mode == )
{
traverse(iter->left, fp, );
traverse(iter->right, fp, );
(*fp)(iter);
}
return;
}
//辅助函数,层序遍历,需队列辅助
//重载两个版本,一个用于遍历树不需改变树元素,调用非成员函数printnode。则标记const,函数参数为(*pf)
//另一个用于拷贝构造与拷贝赋值需改变树元素,调用成员函数。则不标记const,显示声明调用成员函数(BSTree::*pf)
template <typename T> void BSTree<T>::traverse_seq(const Node<T>* iter, void(BSTree::*pf)(const Node<T>*))
{
if (iter != nullptr)
{
Queue<const decltype(iter)> node_address;
node_address.enqueue(iter);
while (!node_address.empty())
{
const Node<T>* temp = node_address.getfirst();
node_address.dequeue();
if (temp->left != nullptr)
node_address.enqueue(temp->left);
if (temp->right != nullptr)
node_address.enqueue(temp->right);
(this->*pf)(temp);
}
}
}
template <typename T> void BSTree<T>::traverse_seq(const Node<T>* iter, void(*pf)(const Node<T>*))const
{
if (iter != nullptr)
{
Queue<const decltype(iter)> node_address;
node_address.enqueue(iter);
while (!node_address.empty())
{
const Node<T>* temp = node_address.getfirst();
node_address.dequeue();
if (temp->left != nullptr)
node_address.enqueue(temp->left);
if (temp->right != nullptr)
node_address.enqueue(temp->right);
(*pf)(temp);
}
}
}
//辅助函数,释放所有节点清空内存
template <typename T> void BSTree<T>::release(Node<T>* iter)
{
if (iter == nullptr)
return;
release(iter->left);
release(iter->right);
delete(iter);
}
}
#endif
05-26 23:23