普通二叉树二叉查找树平衡二叉树常见操作汇总
Posted CSU迦叶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了普通二叉树二叉查找树平衡二叉树常见操作汇总相关的知识,希望对你有一定的参考价值。
目录
总览表
普通二叉树
struct Node{
int data;
Node* lchild,rchild;
};
Node* newNode(int v){
Node* node = new Node;//申请变量的地址空间
node->lchild = node->rchild = NULL;//新建的结点没有左右孩子
node->data = v;//数据域为传进的参数值
return node;
}
void searchAndModifyCM(Node* root,int value,int nv){//找到所有value,替换为new value
if(root==NULL)return;//递归边界
if(root->data==value)root->data = nv;
searchAndModifyCM(root->lchild,value,nv);//往左子树查找
searchAndModifyCM(root->rchild,value,nv);//往右子数查找
}
void insertCM(Node* &root,int v){//由于要对二叉树的结构进行修改,所以传入根节点的引用
if(root==NULL){//查找失败的位置,就是要插入的位置
root = newNode(v);
return;
}
if(由具体二叉树的性质,x应插在左子树){
insertCM(root->lchild,v);
}else{
insertCM(root->rchild,v);
}
}
Node* createCM(int data[],int n){//data是待插入值域的数组,n是数组长度
Node* root = NULL;
for(int i=0;i<n;i++){
insertCM(root,data[i]);
}
return root;
}
二叉查找树BST
void searchAndModifyBST(Node* root,int value,int nv){//找到所有value,替换为new value
if(root==NULL)return;//递归边界
if(root->data==value)root->data = nv;
else if(value<root->data){//根据二叉树的属性,此时应往左子树查找
searchAndModifyBST(root->lchild,value,nv);
}else{
searchAndModifyBST(root->rchild,value,nv);
}
}
void insretBST(Node* &root,int v){//由于要对二叉树的结构进行修改,所以传入根节点的引用
if(root==NULL){//查找失败的位置,就是要插入的位置
root = newNode(v);
return;
}
if(x==root->data)return;//说明当前值的结点已经在BST上,直接返回
else if(x<root->date)insertBST(root->lchild,v);//根据BST的性质,此时往左子树搜索
else insertBST(root->rchild,v);
}
Node* createBST(int data[],int n){//data是待插入值域的数组,n是数组长度
Node* root = NULL;
for(int i=0;i<n;i++){
insertBST(root,data[i]);
}
return root;
}
//以下2个函数用于辅助找到BST的前驱或后继结点
Node* findMax(Node* root){//找最右的孩子
while(root->rchild!=NULL)root=root->rchild;
return root;
}
Node* findMin(Node* root){//最左的孩子就是前驱
while(root->lchild!=NULL)root=root->lchild;
return root;
}
void deleteBSTnode(Node* &root,int v){
if(root==NULL)return;//当前结点不存在,返回
if(root->data == v){//找到了太子,现在找狸猫
if(root->lchild==NULL&&root->rchild==NULL){
//这是个叶子结点,不用找替身了直接删除
root == NULL;//父节点将引用不到他
}else if(root->lchild){//优先用前驱来替代
Node* pre = findMax(root->lchild);//找到前驱结点
root->data = pre->data;//用前驱替代当前结点
deleteBSTnode(root->lchild,pre->data);//记得把前驱也删除
}else{
Node* post = findMin(root->rchild);
root->data = post->data;
deleteBSTnode(root->rchild,post->data);
}
}else if(v<root->data)deleteBSTnode(root->lchild,v);//向左子树检索
else deleteBSTnode(root->rchild,v);
}
平衡二叉树AVL
struct Node{
int data,height;
Node *lchild,*rchild;
};
Node* newAVLNode(int v){
Node* root = new Node;
root->height = 1;
root->data = v;
root->lchild=root->rchild=NULL;
return Node;
};
int getHei(Node* root){
if(root == NULL)return 0;//结点不存在
else return root->height;
}
int getBF(Node* root){
return getHei(root->lchild)-getHei(root->rchild);
}
int updateHei(Node* root){
return max(getHei(root->lchild),getHei(root->rchild))+1;
}
void L(Node* &root){//A是根节点
Node* temp = root->rchild;//B是A的右孩子
root->rchild = temp->lchild;//让B的左子树成为A的右子树
temp->lchild = root;//让A成为B的左子树
updateHei(root);
updateHei(temp);
root = temp;//将根节点设定为B
}
void R(Node* &root){//B是根节点
Node* temp = root->lchild;//A是B的左孩子
root->lchild = temp->rchild;//让A的右子树成为B的右子树
temp->rchild = root;//让B成为A的右子树
updateHei(root);
updateHei(temp);
root = temp;//将A设定为根节点
}
void insertAVL(Node* &root,int v){
if(root==NULL){
root = newAVLNode(int v);
return;
}
if(v<root->data){//插入左子树
insertAVL(root->lchild,v);
updateHei(root);
if(getBF(root)==2){//可能导致平衡因子正向越界
if(getBF(root->lchild)==1){//LL
R(root);
}else{//LR
L(root->lchild);//转化成LL
R(root);
}
}
}else{//插入右子树
insertAVL(root->rchild,v);
updateHei(root);
if(getBF(root)==-1){//可能导致平衡因子反向越界
if(getBF(root->rchild)==-1){//RR
L(root);
}else{//RL
R(root->rchild);//转化成RR
L(root);
}
}
}
}
Node* createAVL(int data[],int n){
Node* root = NULL;
for(int i=0;i<n;i++){
insertAVL(root,data[i]);
}
return root;//返回根节点
}
以上是关于普通二叉树二叉查找树平衡二叉树常见操作汇总的主要内容,如果未能解决你的问题,请参考以下文章