对于二叉查找树的最大难处,我觉得是在于删除,当删除一个元素时,简单地说有两种情况,一种是节点,一种是叶子。假设被删除值为D
1.叶子,很简单,找到叶子的父节点,然后将这个父节点指向该叶子的树枝赋为0;有一种特殊情况是就一个根,那么释放根,然后返回0。
2.节点,需要做两步,找到该节点的左子树的最大值或者右子树的最小值,假设为F,用F替代被删除节点的值D,然后再删除F,而F肯定是叶子,采用1中的方法。
这种算法删除时最坏的情况就是删除点是一个节点,首先遍历一遍找到该节点D,然后再遍历该节点的某个子树找到F,再遍历一遍找到F的父节点,logn1+2logn2,小于3logn,可以再提高的是叶子节点和它的父亲可以一次性完成,而不需要两次,那么算法复杂度是2logn。当然写的复杂一些的话,可以一遍遍历就将所有要改变的节点保留下来,此时算法复杂度是logn
以下是实现代码:
typedef struct _node { int element; struct _node *lefttree; struct _node *righttree; }node; node * insert(node * root,int element) { if(root == 0) { root = (node *)malloc(sizeof(node)); if(root == 0) return 0; root->element = element; root->lefttree = root->righttree = 0; } else if(root->element > element) { root->lefttree = insert(root->lefttree,element); } else if(root->element < element) { root->righttree = insert(root->righttree,element); } return root; } node * find(node * root,int element) { if(root == 0) return 0; if(root->element > element) return find(root->lefttree,element); else if(root->element < element) return find(root->righttree,element); return root; } void printtree(node * root) { if(root == 0) return 0; printtree(root->lefttree); printf("%d\t",root->element); printtree(root->righttree); } node* destroytree(node *root) { if(root == 0) return 0; root->lefttree = destroytree(root->lefttree); root->righttree = destroytree(root->righttree); free(root); return 0; } node *findmax(node *root) { if(root == 0) return 0; if(root->righttree == 0) return root; return findmax(root->righttree); } node *findmin(node *root) { if(root == 0) return 0; if(root->lefttree == 0) return root; return findmin(root->lefttree); } node *findparent(node *root,int element) { if(root == 0) return 0; else if(root->lefttree && root->lefttree->element == element) return root; else if(root->righttree && root->righttree->element == element) return root; else if(root->element > element) return findparent(root->lefttree,element); else if(root->element < element) return findparent(root->righttree,element); else return 0xffffffff; } node* deleteelement(node *root,int element) { node *parent; node *self; if(root == 0) return -1; self = find(root,element); if(self == 0) return 0; if(self->lefttree) { node *tmp = findmax(self->lefttree); self->element = tmp->element; parent = findparent(self->lefttree,tmp->element); if(parent == 0xffffffff) { self->lefttree = 0; } else { parent->righttree = 0; } free(tmp); } else if(self->righttree) { node *tmp = findmin(self->righttree); self->element = tmp->element; parent = findparent(self->righttree,tmp->element); if(parent == 0xffffffff) { self->righttree = 0; } else { parent->lefttree = 0; } free(tmp); } else { parent = findparent(root,self->element); if(parent == 0xffffffff) { free(root); } else { if(parent->lefttree&&parent->lefttree->element == element) parent->lefttree = 0; else parent->righttree = 0; free(self); } } return root; } int main() { int a[10] = {5,6,8,1,2,9,3,7,4,0}; int i = 0; node *root = 0; node *parent = 0; root = insert(root,a[0]); for(i = 1;i<10;i++) insert(root,a[i]); root = deleteelement(root,0); /*for(i = 0;i<11;i++) { parent = findparent(root,i); if(parent == 0xffffffff) printf("root = %d\n",i); else if(parent == 0) printf("not exist = %d\n",i); else printf("%d‘s parent = %d\n",i,parent->element); }*/ printtree(root); destroytree(root); return 1; }
时间: 2024-11-10 07:28:47