二叉查找树
二叉树是节点最多只有两个子树的树状结构,这两个子树可以称为左子树和右子树。可是对于普通的二叉树,并没有足够的信息来提示我们左子树和右子树存储的是什么,我们没有办法进行高效的信息查找。为了提高查找效率,我们会把二叉树升级为二叉查找树(Binary Search Tree)。
二叉查找树是符合以下定义的二叉树:
1.节点左子树中全部的节点键值都比该节点要小。
2.节点右子树中全部的节点键值都比该节点要大。
3.没有重复键值
这样,我们在根据键值寻找一个节点的时候,是不是就可以有方向的进行寻找了?从根节点开始找,如果键值不等于目标键值,目标键值比当前节点的小,我们就跑去左子树继续寻找,反之去右子树。这样每次都能确定前进一层。这样查询效率将得到极大的提升。
节点结构定义
class BSTNode{
public:
BSTNode(int d=0,BSTNode* l=0,BSTNode* r=0):data(d),left(l),right(r){};
int data;
BSTNode* left;
BSTNode* right;
};
本文中的代码实现只为说明相关算法,并不能直接应用于工业设计,所以这里我就不用模板啦。节点数据皆为一个整数data。
需要一个数据节点,左子树指针left和右子树指针right。
二叉查找树结构定义
class BST{
public:
BST(BSTNode* r=0):root(r){
size = 0;
}
~BST();
enum dfstype{PRE=0,IN=1,POST=2};
enum deletetype{MERGE=0,COPY=1};
//插入
void insert(int data);
//查找
bool find(int data) const;
//层次遍历
void bfs() const;
//深搜遍历
void dfs(BST::dfstype) const;
//递归写法
void predfs(BSTNode*) const;
void indfs(BSTNode*) const;
void postdfs(BSTNode*) const;
//回溯写法
void predfsNormal() const;
void indfsNormal() const;
void postdfsNormal() const;
//计数写法
void predfsCount() const;
void indfsCount() const;
void postdfsCount() const;
void clearTime();
//删除相关
void deleteELement(int data,enum deletetype type);
void mergeDelete(BSTNode*&);
void copyDelete(BSTNode*&);
//平衡树
/*
*中序遍历得到有序数组,然后根据数组重新构建树,效率较低
*/
void balance();
void balance(int data[],int first,int last);
//DSW旋转算法
void rightRotate(BSTNode* z,BSTNode* f,BSTNode* n);
void leftRotate(BSTNode* z,BSTNode* f,BSTNode* n);
void createList();
void createPerfectTree();
//AVL树
//其它
int getSize() const;
void clear();//清空节点
private:
BSTNode* root;
int size;
};
插入算法
void BST::insert(int data){
BSTNode* newnode = new BSTNode(data);
BSTNode* temp = root;
BSTNode* pre = 0;
while(temp!=0){
pre = temp;
if(temp->data>data){
temp = temp->left;
}else if(temp->data<data){
temp = temp->right;
}else{
return;
}
}
if(pre==0)
root = newnode;
else{
if(pre->data>data){
pre->left = newnode;
}else{
pre->right = newnode;
}
}
size++;
}
查找元素算法
bool BST::find(int data) const{
BSTNode* temp = root;
while(temp!=0)
{
if(temp->data==data)
return true;
else if(temp->data>data)
temp = temp->left;
else
temp = temp->right;
}
return false;
}
树的遍历
树的遍历
方法有两种:深度优先遍历(Depth First Search,DFS),广度优先遍历(Breadth First Search,BFS)
广度优先遍历利用队列一层一层访问即可。
深度优先遍历分未3种:先序、中序、后序遍历。
值得一提的是,对于符合定义的二叉查找树来说,中序遍历的结果恰好是有序的(有趣不有趣?),所以中序遍历应用最为广泛的。