/*二叉查找树,查找算法里面的一种,折半查找的时间复杂度是O(nlgn)
二叉查找树:可以进行的操作是:插入,删除,查找,最大值,最小值。
对于有n个节点的二叉查找树来说的话,树的高度是O(lgn),那么进行一次的查找的时间复杂度也就是O(lgn)
*/
#include <iostream>
using namespace std;
struct node
{
int key;//其他卫星数据亦可包含;
node* left;
node* right;
node* p;
node()
{
key=0;
left=NULL;
right=NULL;
p=NULL;
}
node(int k):key(k){
left=NULL;
right=NULL;
p=NULL;
}
node& operator=(const node n)
{
if (this!=&n)
{
this->p=n.p;
this->left=n.left;
this->right=n.right;
this->key=n.key;
}
return *this;
}
};
struct bintree
{
node* root;
bintree()
{
root=NULL;
}
};
void mid_tree_walk(node* ptr)//中序遍历
{
if (ptr!=NULL)
{
mid_tree_walk(ptr->left);
cout<<ptr->key<<" ";
mid_tree_walk(ptr->right);
}
cout<<"finished !"<<endl;//遍历二叉树的时间复杂度是O(n);
}
//二叉树的查找:支持最大,最小,前驱和后继的操作,树高度为h,那么操作就是O(h)
node* tree_search(node* ptr,int k)
{
if(ptr==NULL||k==ptr->key)
{
cout<<"search finished !"<<endl;
return ptr;
}
else if(ptr->key<k)
return tree_search(ptr->right,k);
else
return tree_search(ptr->left,k);
}
//或者替换
node* tree_search1(node* ptr,int k)
{
while (ptr!=NULL||k!=ptr->key)
{
if(ptr->key<k)
ptr=ptr->right;
else
ptr=ptr->left;
}
return ptr;
}
node* tree_min(node* ptr)//根据二叉树的性质可以获取
{
while (ptr->left!=NULL)
{
ptr=ptr->left;
}
return ptr;
}
node* tree_max(node* ptr)
{
while (ptr->right!=NULL)
{
ptr=ptr->right;
}
return ptr;
}
/*求前驱和后继:分情况讨论:当是使用中序遍历的情况的话,求后继的时候一般的是某一个键的后继是比该键值大的最小的一个数字,
那么会出现的情况讨论为:当一个键,有右子树,当一个键没有右子树,但是要求该键的时候,前一种情况求后继很简单,中序的情况
下,后继就是遍历完该根,之后右子树的最左的值;后一种情况,当没有右子树的时候,我们需要向上回溯,回溯到没有遍历的那个父或者祖父节点
通过分析二叉搜索树的结构可以分析得到的是:当该节点的父,祖父等节点不是其对应父节点的右子树的时候就是了。
*/
node* successor(node* ptr)//中序遍历后继
{
node* pptr=ptr->p;
if(ptr->right!=NULL)
return tree_min(ptr->right);
while (pptr!=NULL&&ptr==pptr->right)
{
ptr=pptr;
pptr=pptr->p;
}
return pptr;
}
node* presuccessor(node* ptr)//前驱
{
node* pptr=ptr->p;
if (ptr->left!=NULL)
{
tree_max(ptr->left);
}
while (pptr!=NULL&&ptr==pptr->left)
{
ptr=pptr;
pptr=pptr->p;
}
return pptr;
}
/***********tree_min and tree_max 递归版本***********/
node *tree_max_plus(node* pptr)
{
if (pptr->right!=NULL)
return tree_max_plus(pptr->left);
else
return pptr;
}
node *tree_min_plus(node* pptr)
{
if(pptr->left!=NULL)
return tree_min_plus(pptr->left);
else
return pptr->left;
}
/*****************插入和删除******************************/
void tree_insert(bintree* btr,node* ptr)//插入,从根节点进行插入对应的node,同样插入的时间复杂度是树的高度的那样
{
node *py=NULL;
node *px=NULL;
px=btr->root;
while (px!=NULL)
{
py=px;
if(ptr->key<px->key)
{
px=px->left;
}else
{
px=px->right;
}
}
ptr->p=py;
if (py==NULL)
btr->root=ptr;
else
if (ptr->key<py->key)
py->left=ptr;
else
py->right=ptr;
cout<<ptr->key<<" finishted insert !"<<endl;
}
node* tree_delete(bintree* btr,node* ptr)//删除,同样的时间复杂度上是和高度有关系的。
{
node *py=NULL;
node *px=NULL;
if(ptr->left==NULL||ptr->right==NULL)
py=ptr;
else
py=successor(ptr);
if (py->left!=NULL)
px=py->left;
else
px=py->right;
if (px!=NULL)
px->p=py->p;
if (py->p==NULL)
btr->root=px;
else
{
if (py==(py->p->left))
py->p->left=px;
else
py->p->right=px;
}
if (py!=ptr)
ptr->key=py->key;
return py;//删除的这个点是什么?
//首先是判断该ptr的左右的点是不是有,少于2个的情况就直接点删,对于多余1个的就找后继,对于后继进行点删,并把ptr的值用py的代替。时间复杂度还是那样的。
}
node* tree_delete(bintree btr,node* ptr)//删除,同样的时间复杂度上是和高度有关系的。
{
node *py=NULL;
node *px=NULL;
if(ptr->left==NULL||ptr->right==NULL)
py=ptr;
else
py=successor(ptr);
if (py->left!=NULL)
px=py->left;
else
px=py->right;
if (px!=NULL)
px->p=py->p;
if (py->p==NULL)
btr.root=px;
else
{
if (py==(py->p->left))
py->p->left=px;
else
py->p->right=px;
}
if (py!=ptr)
ptr->key=py->key;
return py;//删除的这个点是什么?
//首先是判断该ptr的左右的点是不是有,少于2个的情况就直接点删,对于多余1个的就找后继,对于后继进行点删,并把ptr的值用py的代替。时间复杂度还是那样的。
}
int main()
{
bintree *btr=new bintree();
node* ptr1=new node(1);
node* ptr2=new node(2);
node* ptr3=new node(4);
node* ptr4=new node(6);
node* ptr5=new node(9);
tree_insert(btr,ptr1);
tree_insert(btr,ptr2);
tree_insert(btr,ptr3);
tree_insert(btr,ptr4);
tree_insert(btr,ptr5);
cout<<"---------------"<<endl;
mid_tree_walk(btr->root);
node *ptr=tree_max(btr->root);
cout<<"max : "<<ptr->key<<endl;
ptr=tree_min(btr->root);
cout<<"min : "<<ptr->key<<endl;
tree_delete(btr,ptr2);
cout<<"---------------"<<endl;
mid_tree_walk(btr->root);
return 0;
}
算法导论十二章复习
最新推荐文章于 2023-02-08 11:01:23 发布