二叉树结点的查找跟遍历是很容易实现的,但是要想实现二叉树结点的删除,确实是一项很费事的工作
下面我只介绍二叉树结点的删除。删除二叉树的结点,会遇到三种情况
被删除的结点没有子树。这种情况最容易操作,直接找到该结点,然后让它的父结点指向它的指针为空,然后释放该结点即可
被删除的结点只有一个子树。找到该结点,让其父结点指向它的子树,然后释放该结点
被删除的结点同时拥有左右子树。此处我拿顺序二叉树为例,找到该结点,然后找到该结点右子树的最左的子结点,让该子结点的父结点指向空,再让该结点的父结点指向该子结点,然后释放该结点(此处我提供一个小技巧,我们可以将该子结点复制给该结点,然后让该子结点的父结点指向空,然后释放该子结点)!如果该子结点还有右子树,那么直接将该子结点的父结点的左子树指向该子结点的右子树。
说的有点绕口,慢慢理解吧
#include<stdio.h> #include<stdlib.h> //二叉树结点的结构体定义 typedef struct tree { int num; struct tree *prve;//此处为前驱指针,该指针的目的是为了方便找到父结点 struct tree *left; struct tree *right; }Tree; //初始化二叉树 void Init_Tree(Tree *Root) { Root->prve = NULL; Root->left = NULL; Root->right = NULL; } //插入结点 void Insert_Node(Tree *Root, int key) { if(Root->num >= key){ if(Root->left == NULL){ Tree *node = (Tree *)malloc(sizeof(Tree)); node->prve = node->left = node->right = NULL; node->num = key; Root->left = node; node->prve = Root; } else Insert_Node(Root->left,key); } else{ if(Root->right == NULL){ Tree *node = (Tree *)malloc(sizeof(Tree)); node->prve = node->left = node->right = NULL; node->num = key; Root->right = node; node->prve = Root; } else Insert_Node(Root->right,key); } } //查找结点 Tree *Search_Node(Tree *Root,int key) { if(Root == NULL) return NULL; if(Root->num == key) return Root; else if(Search_Node(Root->left,key) != NULL) return Search_Node(Root->left,key); else if(Search_Node(Root->right,key) != NULL) return Search_Node(Root->right,key); else return NULL; } //查找结点版本2 Tree *Search_Node2(Tree *Root, int key) { if(Root == NULL)return NULL; if(Root->num == key) return Root; if(Root->num > key) return Search_Node2(Root->left,key); else return Search_Node2(Root->right,key); } //删除结点 void Del_Node(Tree *Root) { if(Root->left == NULL && Root->right == NULL) { if(Root->prve->left == Root) Root->prve->left = NULL; else Root->prve->right = NULL; free(Root); } else if(Root->left == NULL) { if(Root->prve->left == Root) Root->prve->left = Root->right; else Root->prve->right = Root->right; free(Root); } else if(Root->right == NULL) { if(Root->prve->left == Root) Root->prve->left = Root->left; else Root->prve->right = Root->left; free(Root); } else{ Tree *temp = Root->right; while(temp->left){ temp = temp->left; } if(temp->right == NULL){ temp->prve->left = NULL; *Root = *temp; free(temp); } else { temp->prve->left = temp->right; *Root = *temp; free(temp); } } } //中序遍历二叉树 void Travel_Tree(Tree *Root) { if(Root == NULL) return ; Travel_Tree(Root->left); printf("point:%d ",Root->num); Travel_Tree(Root->right); } // 广度优先搜索 void Level_Tree(Tree *Root) { Tree *flag[100]; int top = 0, down = 0; flag[top++] = Root; while(top-down) { printf("point: %d ",flag[down++]->num); if(flag[down-1]->left) flag[top++] = flag[down-1]->left; if(flag[down-1]->right) flag[top++] = flag[down-1]->right; } } //非递归先序遍历二叉树 void First_Tree(Tree *Root) { Tree *flag[100], *temp; int top = 0; flag[top++] = Root; while(top) { temp = flag[top-1]; printf("point: %d ",flag[--top]->num); if(temp->right) flag[top++] = temp->right; if(temp->left) flag[top++] = temp->left; } } //非递归中序遍历二叉树 void Mid_Tree(Tree *Root) { Tree *flag[100], *temp; int top = 0; temp = Root; while(top || temp) { if(temp){ flag[top++] = temp; temp = temp->left; }else { temp = flag[--top]; printf("point: %d ",temp->num); temp = temp->right; } } } //非递归后序遍历二叉树 void Last_Tree(Tree *Root) { Tree *flag[100], *p, *q; int top = 0; p = Root->left; q = NULL; flag[top++] = Root; while(top) { if(p){ flag[top++] = p; p = p->left; } else{ p = flag[top-1]; if(p->right == NULL || p->right == q){ printf("point: %d ",p->num); top--; q = p; p = NULL; } else p = p->right; } } } //销毁二叉树 void Destory_Tree(Tree *Root) { if(Root == NULL) return; Destory_Tree(Root->right); Destory_Tree(Root->left); printf("%d over! ", Root->num); free(Root); return ; } //求树的深度 int Deep_Tree(Tree *Root) { if(Root == NULL) return 0; return 1+(Deep_Tree(Root->left) > Deep_Tree(Root->right)?Deep_Tree(Root->left):Deep_Tree(Root->right)); } //统计结点 int Count_Tree(Tree *Root) { if(Root == NULL) return 0; return (1 + Deep_Tree(Root->left) + Deep_Tree(Root->right)); } //删除的结点为根结点 void Del_Root(Tree *Root) { if(Root->left == NULL && Root->right == NULL) Root = NULL; else if(Root->left == NULL) *Root = *(Root->right); else if(Root->right == NULL) *Root = *(Root->left); else{ Tree *p = Root->right; while(p->left) p = p->left; if(p->prve == Root){ Tree *q = Root->left; *Root = *p; free(p); Root->left = q; } else{ Tree *q1, *q2; q1 = Root->left; q2 = Root->right; *Root = *p; if(p->right) p->prve = p->right; else p->prve = NULL; free(p); Root->left = q1; Root->right = q2; } } } int main() { int i, key; Tree *Root, *temp; Root = (Tree *)malloc(sizeof(Tree)); Init_Tree(Root); scanf("%d",&Root->num); for(i = 1;i < 10; i++) { scanf("%d",&key); Insert_Node(Root,key); } Travel_Tree(Root); // printf(" 深度为:%d 总结点数:%d ",Deep_Tree(Root),Count_Tree(Root)); printf("请输入您要删除的结点: "); scanf("%d",&key); temp = Search_Node(Root,key); if(temp != Root) Del_Node(temp); else Del_Root(Root); // Level_Tree(Root); Travel_Tree(Root); printf(" "); /* First_Tree(Root); Mid_Tree(Root); Last_Tree(Root); Destory_Tree(Root); */ return 0; }