int deleteNode(PNode *root,KeyType key){ //because you will delete the node , so you must free/release the memory PNode p = search((*root),key); PNode temp; int tempkey; if(p==NULL) return 0; if(p->left==NULL&&p->right==NULL){ if(p->parent==NULL) { free(p); (*root)=NULL; } p->parent->left==p?p->parent->left==NULL:p->parent->right==NULL; free(p); } else if(p->left && !(p->right)) { p->left->parent = p->parent; if(p->parent==NULL){ (*root)=p->left; }else if(p->parent->left==p) { p->parent->left=p->left; }else{ p->parent->right=p->left; } free(p); }else if(p->right && !(p->left)) { p->right->parent=p->parent; if(p->parent==NULL){ (*root)=p->right; }else if(p->parent->left==p) { p->parent->left=p->right; }else{ p->parent->right=p->right; } free(p); }else{ /*temp = searchSuccessor(p); tempkey = temp->key; temp->parent=p->parent; if(p->parent==NULL){ (*root)=temp; }else if(p->parent->left=p){ p->parent->left=temp; }else{ p->parent->right=temp; } deleteNode(root,tempkey); free(p);*/ //you don't have to delete the node actually,instead you can replace the value of the node which will simplify the process temp = searchSuccessor(p); tempkey = temp->key; deleteNode(root,tempkey); p->key=tempkey; } return 1; }
int main(void) { int i; PNode root=NULL; KeyType nodeArray[11]= {15,6,18,3,7,17,20,2,4,13,9}; create(&root,nodeArray,11); for(i=0; i<2; i++) deleteNode(&root,nodeArray[i]); printf("%d\n",searchPredecessor(root)->key); printf("%d\n",searchSuccessor(root)->key); printf("%d\n",searchMin(root)->key); printf("%d\n",searchMax(root)->key); printf("%d\n",search(root,13)->key); return 0; }
//根据关键字删除某个结点,删除成功返回1,否则返回0 //如果把根结点删掉,那么要改变根结点的地址,所以传二级指针 int deleteNode(PNode* root,KeyType key) { PNode q; //查找到要删除的结点 PNode p=search(*root,key); KeyType temp; //暂存后继结点的值 //没查到此关键字 if(!p) return 0; //1.被删结点是叶子结点,直接删除 if(p->left == NULL && p->right == NULL) { //只有一个元素,删完之后变成一颗空树 if(p->parent == NULL) { free(p); (*root)=NULL; } else { //删除的结点是父节点的左孩子 if(p->parent->left == p) p->parent->left=NULL; else //删除的结点是父节点的右孩子 p->parent->right=NULL; free(p); } } //2.被删结点只有左子树 else if(p->left && !(p->right)) { p->left->parent=p->parent; //如果删除是父结点,要改变父节点指针 if(p->parent == NULL) *root=p->left; //删除的结点是父节点的左孩子 else if(p->parent->left == p) p->parent->left=p->left; else //删除的结点是父节点的右孩子 p->parent->right=p->left; free(p); } //3.被删结点只有右孩子 else if(p->right && !(p->left)) { p->right->parent=p->parent; //如果删除是父结点,要改变父节点指针 if(p->parent == NULL) *root=p->right; //删除的结点是父节点的左孩子 else if(p->parent->left == p) p->parent->left=p->right; else //删除的结点是父节点的右孩子 p->parent->right=p->right; free(p); } //4.被删除的结点既有左孩子,又有右孩子 //该结点的后继结点肯定无左子树(参考上面查找后继结点函数) //删掉后继结点,后继结点的值代替该结点 else { //找到要删除结点的后继 q=searchSuccessor(p); temp=q->key; //删除后继结点 deleteNode(root,q->key); p->key=temp; } return 1; }