二叉排序数的总结

来源:互联网 发布:刘义军 知乎 编辑:程序博客网 时间:2024/05/01 15:35

做 九度笔记之 1467:二叉排序树时又重新翻阅了算法导论里相关的知识,之前都是看看也没有动手实践,这次就顺便把二叉排序数的其它函数都实现了下,还真发现了不少问题。

以下前提条件是所有的数都互不相同。

1查找

通过比较查找数值qvalue和 当前节点值node.value,如果相同就找到了,如果qvalue<node.value 就跑到左子树查找,否者到右子树查找。
biNode* search(biNode *root,int value){biNode*x =root;while(x!=NULL && x->value!=value){if(x->value > value){x = x->Left;}elsex = x->Right;}return x;}
如果找不到就返回NULL
注意这里循环的判断条件为 
while(x!=NULL && x->value!=value)

2.最大最小值

biNode* treeMax(biNode *root){biNode* x = root;while(x->Right!=NULL){x = x->Right;}return x;}biNode* treeMin(biNode *root){biNode* x = root;while(x->Left!=NULL){x = x->Left;}return x;}

循环条件为
while(x->Right!=NULL)
while(x->Left!=NULL)

3.插入

类似查找,不过需要一个额外的变量y,表示当前节点的父亲节点。

void insert(biNode *&root,int value){biNode *temNode = new biNode(value);if(root==NULL){root  = temNode;return;}biNode *y = NULL;biNode *x = root;while(x!=NULL){if(value > x->value){y = x;x = x->Right;}else{y = x;x = x->Left;}}if(value < y->value){y->Left = temNode;}elsey->Right = temNode;temNode->Parent = y;}
这里需要注意的是参数 root 应为

biNode *&root
因为root初始为NULL, 出入后root的值就改变了,但是要想更改root的值就要用引用或者指针,也就是指针的指针,我们在这里用指针的引用。

然后需要注意的就是 要先判断root是否为NULL

这里的循环判断条件

while(x!=NULL)

4.求后继或前任

注意的是要分两种情况考虑。
后继就是求大于x.value的 最小数,如果存在右子树,右子树上的值都大于x.value,所以只要求treeMin(x->Right)就行
如果不存在右子树的话,就要向上寻找一个点y,x  满足x是y的左孩子, 则y的值大于以x为根的子树上所有节点的值。
在寻找过程中,x是y的右孩子,则y的值小于x的值。直到满足上面的条件,

求前继是相反的过程。
biNode* treeSuccessor(biNode *x){if(x->Right!=NULL){return treeMin(x->Right);}biNode *y = x->Parent;while(y!=NULL && x==y->Right){x = y;y = y->Parent;}return y;}biNode* treePredecessor(biNode *x){if(x->Left!=NULL){return treeMax(x->Left);}biNode *y = x->Parent;while(y!=NULL && x==y->Left){x = y;y = y->Parent;}return y;}


5.删除

删除节点z


删除节点分为上面4中情况,(d)情况通过转换转为(c)情况。
void transplant(biNode *&root,biNode *u,biNode *v){// MUST *& ROOTif(u->Parent==NULL)root = v;//ATTENTIONelse if(u == u->Parent->Left)u->Parent->Left = v;//elseu->Parent->Right = v;//if(v!=NULL)v->Parent = u->Parent;}void deleteNode(biNode *&root, biNode *z){// MUST *& ROOTif(z->Left==NULL){transplant(root,z,z->Right);}else if(z->Right == NULL)transplant(root,z,z->Left);else{//biNode *y = treeSuccessor(z);//ATTENIONbiNode *y = treeMin(z->Right);//ATTENIONif(y->Parent!=z){transplant(root,y,y->Right);y->Right = z->Right;z->Right->Parent = y;}transplant(root,z,y);y->Left = z->Left;//ATTENTIONz->Left->Parent = y;//}}

transplant函数的作用是把
TRANSPLANT, which replaces one subtree as a child of its parent with
another subtree. When TRANSPLANT replaces the subtree rooted at node u with
the subtree rooted at node , node u’s parent becomes node ’s parent, and u’s
parent ends up having  as its appropriate child.

transplant 和deleteNode函数都有可能改变root的值,所以root的参数为 指针引用
void transplant(biNode *&root,biNode *u,biNode *v)
void deleteNode(biNode *&root, biNode *z)

总结 

首先要谨记root为指针,指针保存的是地址,一定要注意函数是否有可能需要修改root的值,是的话就要把root的参数 为指针的引用, 因为只有这样才能真正的修改root的值。


//============================================================================// Name        : BiTree.cpp// Author      : wdy// Version     :// Copyright   : Your copyright notice// Description : Hello World in C++, Ansi-style//============================================================================#include <iostream>using namespace std;struct biNode{int value;biNode* Parent;biNode* Left;biNode* Right;public:biNode(int value_):value(value_),Parent(NULL),Left(NULL),Right(NULL){};};//biNode *root=NULL;void preWalkPrintTree(biNode *root){if(root==NULL){return;}std::cout<< root->value <<" ";preWalkPrintTree(root->Left);preWalkPrintTree(root->Right);}biNode* search(biNode *root,int value){biNode*x =root;while(x!=NULL && x->value!=value){if(x->value > value){x = x->Left;}elsex = x->Right;}return x;}biNode* treeMax(biNode *root){biNode* x = root;while(x->Right!=NULL){x = x->Right;}return x;}biNode* treeMin(biNode *root){biNode* x = root;while(x->Left!=NULL){x = x->Left;}return x;}void insert(biNode *&root,int value){biNode *temNode = new biNode(value);if(root==NULL){root  = temNode;return;}biNode *y = NULL;biNode *x = root;while(x!=NULL){if(value > x->value){y = x;x = x->Right;}else{y = x;x = x->Left;}}if(value < y->value){y->Left = temNode;}elsey->Right = temNode;temNode->Parent = y;}biNode* treeSuccessor(biNode *x){if(x->Right!=NULL){return treeMin(x->Right);}biNode *y = x->Parent;while(y!=NULL && x==y->Right){x = y;y = y->Parent;}return y;}biNode* treePredecessor(biNode *x){if(x->Left!=NULL){return treeMax(x->Left);}biNode *y = x->Parent;while(y!=NULL && x==y->Left){x = y;y = y->Parent;}return y;}void transplant(biNode *&root,biNode *u,biNode *v){// MUST *& ROOTif(u->Parent==NULL)root = v;//ATTENTIONelse if(u == u->Parent->Left)u->Parent->Left = v;//elseu->Parent->Right = v;//if(v!=NULL)v->Parent = u->Parent;}void deleteNode(biNode *&root, biNode *z){// MUST *& ROOTif(z->Left==NULL){transplant(root,z,z->Right);}else if(z->Right == NULL)transplant(root,z,z->Left);else{//biNode *y = treeSuccessor(z);//ATTENIONbiNode *y = treeMin(z->Right);//ATTENIONif(y->Parent!=z){transplant(root,y,y->Right);y->Right = z->Right;z->Right->Parent = y;}transplant(root,z,y);y->Left = z->Left;//ATTENTIONz->Left->Parent = y;//}}void test(){int num[11] = {15,6,18,3,7,17,20,2,4,13,9};biNode *root=NULL;//ATTENTIONstd::cout<<"insert"<<std::endl;for(int i = 0;i<11;i++){insert(root,num[i]);/*preWalkPrintTree(root);std::cout<<std::endl;std::cout<<"tree max"<< treeMax(root)->value <<std::endl;std::cout<<"tree min"<< treeMin(root)->value <<std::endl;*/}//std::cout<<"2 succe"<<treeSuccessor(search(root,2))->value<<std::endl;;//std::cout<<"4 succe"<<treeSuccessor(search(root,4))->value<<std::endl;;//std::cout<<"9 succe"<<treeSuccessor(search(root,9))->value<<std::endl;;//std::cout<<"20 succe"<<treeSuccessor(search(root,20))->value<<std::endl;;//std::cout<<"15 succe"<<treeSuccessor(search(root,15))->value<<std::endl;;//std::cout<<"13 succe"<<treeSuccessor(search(root,13))->value<<std::endl;;//std::cout<<"****"<<std::endl;//std::cout<<"2 succe"<<treePredecessor(search(root,2))->value<<std::endl;;//std::cout<<"4 succe"<<treePredecessor(search(root,4))->value<<std::endl;;//std::cout<<"9 succe"<<treePredecessor(search(root,9))->value<<std::endl;;//std::cout<<"20 succe"<<treePredecessor(search(root,20))->value<<std::endl;;//std::cout<<"15 succe"<<treePredecessor(search(root,15))->value<<std::endl;;//std::cout<<"7 succe"<<treePredecessor(search(root,7))->value<<std::endl;;preWalkPrintTree(root);std::cout<<"****"<<std::endl;deleteNode(root,search(root,15));//Attention//biNode =preWalkPrintTree(root);}int main() {//cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!test();return 0;}



原创粉丝点击