關於刪除二叉樹子樹的兩種操作
阿新 • • 發佈:2019-02-13
/*一、
名稱:刪除二叉樹中以x為根的子樹
說明:此程式的大部分內容,註釋都解釋的較為詳細了。在這裡需要提及一點的是此處遞迴函式flag傳遞的不是上篇中講的引用,而是普通的變數,因為在向下傳遞引數(當前結點是否是x的資訊)的過程中只要傳遞給對應的子樹,並不需要傳遞給整個樹的結點。在下一篇會做個關於遞迴傳遞引數的總結。*/
/* 二、同時傳遞父節點與子節點,因為是中序線索二叉樹,因此要判斷一下ltag和rtag的值,若是普通二叉樹,刪掉即可。
名稱:刪除二叉樹中以x為根的子樹
說明:此程式的大部分內容,註釋都解釋的較為詳細了。在這裡需要提及一點的是此處遞迴函式flag傳遞的不是上篇中講的引用,而是普通的變數,因為在向下傳遞引數(當前結點是否是x的資訊)的過程中只要傳遞給對應的子樹,並不需要傳遞給整個樹的結點。在下一篇會做個關於遞迴傳遞引數的總結。*/
//遞迴刪除二叉樹中以x為根的子樹,(flag為標誌) int DelRoot_x(BiTree &T, int x,int flag) { if(T == NULL) return 0; else { if(T->data == x) //如果當前節點的值為x,則更改標誌位,在下面將向遞迴子函式中傳遞flag值 { flag = 1; } int lef_ret = DelRoot_x(T->lchild,x,flag); //遞迴左子樹,lef_ret為從左子樹中返回的資訊 int rig_ret = DelRoot_x(T->rchild,x,flag); //遞迴右子樹,rig_ret為從右子樹中返回的資訊 if(1 == flag) //如果標誌為1,說明其祖父結點中有x,也就是說當前結點需要刪除 { if(T->data == x) //如果是x結點,則需要向上層結點傳遞資訊,以便其父節點將對應的指標域賦空 return 1; delete T; } else { if(1 == lef_ret) //從子結點接受收的資訊,即如果其子結點為x,需要將其指標域賦空 T->lchild = NULL; if(1 == rig_ret ) //從子結點接受收的資訊,即如果其子結點為x,需要將其指標域賦空 T->rchild = NULL; } } return 0; }
/* 二、同時傳遞父節點與子節點,因為是中序線索二叉樹,因此要判斷一下ltag和rtag的值,若是普通二叉樹,刪掉即可。
void Tree::deleteNodeTree(char data,struct node* node,struct node* pre) { if (node != NULL) { if (node->data == data && node != getRoot())//如果刪除的不是根節點 { if (pre->leftChild == node) //防止刪除節點的父節點的指標懸空 pre->leftChild = NULL; else if (pre->rightChild == node) pre->rightChild = NULL; destroyTree(node); return; } else if (node->data == data) { destroyTree(node); return; } if(node->ltag == 0) deleteNodeTree(data,node->leftChild,node); if(node->rtag == 0) deleteNodeTree(data,node->rightChild,node); } }
void Tree::destroyTree(struct node* node) { if (node == NULL) { return; } if (node->leftChild != NULL&&node->ltag == 0) { destroyTree(node->leftChild); } if (node->rightChild != NULL&&node->rtag == 0) { destroyTree(node->rightChild); } delete node; node = NULL; return; }