二叉树节点删除操作可以分为三种情况:
思路:
只为叶子节点,可直接删掉,使用delete()函数(C语言中是free)释放节点;有单个孩子节点,则让孩子节点接替要删除的节点;同时有左右孩子节点,则查找右子树中最小值,将其值付给要删除的节点,然后删除右子树中最小节点(其实就是将要删的节点换了个值,整体结构都不变,删掉的是最小节点)
#include <iostream> using namespace std; typedef struct node{ int data; node* lchild; node* rchild; }*bitTree; //这里单独在下面的函数中提到bitTree则等于node* void insert(bitTree &T,int x) { if(T == NULL) { T = new node; T->data = x; T->lchild = NULL; T->rchild = NULL; } if(x==T->data) return; else if(x>T->data) insert(T->rchild,x); else if(x<T->data) insert(T->lchild,x); } int display(bitTree T) {//先序遍历 if(T!=NULL) { display(T->lchild); cout<<T->data<<" "; display(T->rchild); } } bitTree seekmin(bitTree T) { if(T==NULL) return NULL;//null if(T->lchild==NULL) return T; return seekmin(T->lchild); } bool search(bitTree T,int x) { if(T==NULL) return false;//若没有找到,则按照递归的思路会到一个null的节点,所以应该提前判断该值 if(x==T->data) return true; else if(x>T->data) search(T->rchild,x); else if(x<T->data) search(T->lchild,x); } bitTree deletenode(bitTree T,int x)//删除 {//这里需要返回的是bitree也就是node*指针类型,因为查找到要删除的值后,需要对当前的节点进行操作 if(T==NULL) { cout<<"find false"; return T; } else if(x>T->data) T->rchild = deletenode(T->rchild,x); else if(x<T->data) T->lchild = deletenode(T->lchild,x); else if(x==T->data){ if(T->lchild&&T->rchild)//有2个孩子节点 {//两个孩子节点的,从右子树中找最小的元素填充删除节点 bitTree temp = seekmin(T->rchild); T->data = temp->data; T->rchild = deletenode(T->rchild,T->data); //直接将最小值删掉即可,右子树最小值已经赋给了两孩子节点的节点 } else if(!T->lchild)//无孩子或只有右节点 { bitTree temp = T; T = T->rchild; delete(temp);//删除节点 } else{//只有左孩子节点 bitTree temp = T; T = T->lchild; delete(temp); } } return T; } void newnode(bitTree &T,int x)//插入一个新的节点 { if(T==NULL) { T = new node; T->data = x; T->lchild = NULL; T->rchild = NULL; } if(x>T->data) newnode(T->rchild,x); else if(x<T->data) newnode(T->lchild,x); else if(x==T->data) return; } int main() { /* 示例所用二叉树: 18 / \ 10 20 / \ / \ 9 11 19 22 */ int a[7] = {18,10,20,9,11,19,22}; bitTree T = NULL; for(int i = 0;i<7;i++) { insert(T,a[i]); } cout<<"先序遍历:"; display(T); cout<<endl; cout<<"min:"<<seekmin(T)->data<<endl; cout<<"查找值:"<<search(T,18);//找到返回false,没有返回true cout<<endl; newnode(T,4); cout<<"插入新值后:" ; //插入 display(T); cout<<endl; cout<<"删除后:"; deletenode(T,18); display(T); cout<<endl; }
遇到的问题:
需要注意删除节点的函数需要node*的返回,这是由于在递归查找到要删除数值外,还需要对该节点位置做出改变。