第12章:二叉搜索树代码:

这章主要讲了二叉查找树及其相关性质。二叉搜索树的结点结构插入搜索删除结点后继结点前驱遍历代码如下。

结点结构:

struct node{
                Type element;//存储的关键字
                node* parent;//母结点
                node* left;//左孩子结点
                node* right;//右孩子结点
                node(const Type& e=Type(),node* p=0,node* l=0,node* r=0):element(e),parent(p),left(l),right(r){}
        };

插入:

  • 非递归插入:
template<class Type>
bool binarySearchTree<Type>::noRecursiveInsertion(const Type& val,node*& rootNode)//根节点引用是必须的,因为可能对根节点直接赋值
{
        node* preNode=0;
        node* currNode=rootNode;

        while(currNode!=0){
                preNode=currNode;

                if(val<currNode->element)
                        currNode=currNode->left;
                else if(currNode->element<val)
                        currNode=currNode->right;
                else
                        return false;//假设树中只能插入不同的元素
        }

        actualSize++;//树中存储的元素实际个数

        if(preNode==0)//插入前根结点为0
                rootNode=new node(val);
        else if (val<preNode->element)
                preNode->left=new node(val,preNode);
        else
                preNode->right=new node(val,preNode);

        return true;
}
  • 递归插入:
template<class Type>
bool binarySearchTree<Type>::recursiveInsertion(const Type& val,node*& rootNode)
{
        if(rootNode!=0){
                if(val<rootNode->element){
                        if(rootNode->left==0){
                                rootNode->left=new node(val,rootNode);
                                return true;
                        }
                        else
                                return recursiveInsertion(val,rootNode->left);
                }
                else if(rootNode->element<val){
                        if(rootNode->right==0){
                                rootNode->right=new node(val,rootNode);
                                return true;
                        }
                        else
                                return recursiveInsertion(val,rootNode->right);
                }
                else
                        return false;
        }
        else{
                rootNode=new node(val);
                return true;
        }
}

搜索:

template<class Type>
typename binarySearchTree<Type>::node* binarySearchTree<Type>::search(const Type& val,node* rootNode) const
{
        while(rootNode!=0&&rootNode->element!=val)
                if(val<rootNode->element)
                        rootNode=rootNode->left;
                else
                        rootNode=rootNode->right;

        return rootNode;
}

删除:

删除操作有点麻烦,详细可见算法导论第三版中文版P166。现给出代码:

// node v is used to replace node u;
template<class Type>
void binarySearchTree<Type>::transplant(node* u,node* v)
{
        if(u->parent==0)
                root=v;
        else if(u==u->parent->right)
                u->parent->right=v;
        else
                u->parent->left=v;

        if(v!=0)
                v->parent=u->parent;
}

template<class Type>
bool binarySearchTree<Type>::remove(const Type& val)
{
        node* objectNode=search(val,root);

        if(objectNode==0)
                return false;
        else{
                if(objectNode->left==0)
                        transplant(objectNode,objectNode->right);
                else if(objectNode->right==0)
                        transplant(objectNode,objectNode->left);
                else{
                        node* minNode=minimum(objectNode->right);

                        if(minNode->parent!=objectNode){
                                transplant(minNode,minNode->right);
                                minNode->right=objectNode->right;
                                minNode->right->parent=minNode;
                        }
                        transplant(objectNode,minNode);
                        minNode->left=objectNode->left;
                        minNode->left->parent=minNode;
                }
        }

        actualSize--;
        delete objectNode;
        return true;
}

结点后继:

一个结点x的后继结点被定义为大于x.key的最小关键字的结点。

template<class Type>
typename binarySearchTree<Type>::node* binarySearchTree<Type>::successor(node* currNode) const
{
        //右子树不为空,找到右子树的最小节点
        if(currNode->right!=0)
                return minimum(currNode->right);

       //右子树为空的情况:     
        node* parentNode=currNode->parent;
        while(parentNode!=0&&currNode==parentNode->right){
                currNode=parentNode;
                parentNode=parentNode->parent;
        }

        return parentNode;
}

结点前驱:

结点前驱与结点后继是对称的。

template<class Type>
typename binarySearchTree<Type>::node* binarySearchTree<Type>::predecessor(node* currNode) const
{
        if(currNode->left!=0)
                return maximum(currNode->left);
        else{
                node* parentNode=currNode->parent;

                while(parentNode!=0&&currNode==parentNode->left){
                        currNode=parentNode;
                        parentNode=parentNode->parent;
                }
                return parentNode;
        }
}

遍历:

  • 递归的前序,中序,后续遍历:
template<class Type>
void binarySearchTree<Type>::preorderTreeWalk(node* rootNode) const
{
        if(rootNode!=0){
                cout<<rootNode->element<<" ";
                preorderTreeWalk(rootNode->left);
                preorderTreeWalk(rootNode->right);
        }
}

template<class Type>
void binarySearchTree<Type>::inorderTreeWalk(node* rootNode) const
{
        if(rootNode!=0){
                inorderTreeWalk(rootNode->left);
                cout<<rootNode->element<<" ";
                inorderTreeWalk(rootNode->right);
        }
}

template<class Type>
void binarySearchTree<Type>::postorderTreeWalk(node* rootNode) const
{
        if(rootNode!=0){
                postorderTreeWalk(rootNode->left);
                postorderTreeWalk(rootNode->right);
                cout<<rootNode->element<<" ";
        }
}
  • 用栈实现的非递归遍历。可参考该博客教科书上的非递归遍历那一段落。
template<class Type>
void binarySearchTree<Type>::preorderTreeWalkWithStack(node* rootNode) const
{
        stack<node*> s;
        node* currentNode=rootNode;

        while(currentNode!=0||!s.empty()){
                while(currentNode!=0){
                        cout<<currentNode->element<<" ";
                        s.push(currentNode);
                        currentNode=currentNode->left;
                }

                if(!s.empty()){
                        currentNode=s.top();
                        s.pop();
                        currentNode=currentNode->right;
                }
        }
}

template<class Type>
void binarySearchTree<Type>::inorderTreeWalkWithStack(node* rootNode) const
{
        stack<node*> s;
        node* currentNode=rootNode;

        while(currentNode!=0||!s.empty()){
                while(currentNode!=0){
                        s.push(currentNode);
                        currentNode=currentNode->left;
                }

                if(!s.empty()){
                        currentNode=s.top();
                        s.pop();
                        cout<<currentNode->element<<" ";
                        currentNode=currentNode->right;
                }
        }
}

template<class Type>
void binarySearchTree<Type>::postorderTreeWalkWithStack(node* rootNode) const
{
        struct postNode{
                node* treeNode;
                bool isFirst;
                postNode(node* n=0,bool isF=true):treeNode(n),isFirst(isF){}
        };

        stack<postNode*> s;
        node* currentNode=rootNode;
        postNode* tmp;

        while(currentNode!=0||!s.empty()){
                while(currentNode!=0){
                        tmp=new postNode(currentNode);
                        s.push(tmp);
                        currentNode=currentNode->left;
                }

                if(!s.empty()){
                        tmp=s.top();
                        s.pop();
                        if(tmp->isFirst==true){
                                tmp->isFirst=false;
                                s.push(tmp);
                                currentNode=tmp->treeNode->rightNode;
                        }
                        else{
                                cout<<tmp->treeNode->element<<" ";
                                delete tmp;
                                currentNode=0;
                        }
                }
        }
}
template<class Type>
void binarySearchTree<Type>::preorderTreeWalkWithMorris(node* rootNode)
{
        node* currentNode=rootNode;
        node* tmp;

        while(currentNode!=0){
                if(currentNode->left==0){
                        cout<<currentNode->element<<" ";
                        currentNode=currentNode->right;
                }
                else{
                        tmp=currentNode->left;
                        while(tmp->right!=0&&tmp->right!=currentNode)
                                tmp=tmp->right;

                        if(tmp->right==0){
                                cout<<currentNode->element<<" ";
                                tmp->right=currentNode;
                                currentNode=currentNode->left;
                        }
                        else{
                                tmp->right=0;
                                currentNode=currentNode->right;
                        }
                }
        }
}

template<class Type>
void binarySearchTree<Type>::inorderTreeWalkWithMorris(node* rootNode)
{
        node* currentNode=rootNode;
        node* tmp;

        while(currentNode!=0){
                if(currentNode->left==0){
                        cout<<currentNode->element<<" ";
                        currentNode=currentNode->right;
                }
                else{
                        tmp=currentNode->left;
                        while(tmp->right!=0&&tmp->right!=currentNode)
                                tmp=tmp->right;

                        if(tmp->right==0){
                                tmp->right=currentNode;
                                currentNode=currentNode->left;
                        }
                        else{
                                cout<<currentNode->element<<" ";
                                tmp->right=0;
                                currentNode=currentNode->right;
                        }
                }
        }
}

template<class Type>
void binarySearchTree<Type>::postorderTreeWalkWithMorris(node* rootNode)
{
        node* dump=new node();
        dump->left=rootNode;

        node* currentNode=dump;
        node* tmp;

        while(currentNode!=0){
                if(currentNode->left==0)
                        currentNode=currentNode->right;
                else{
                        tmp=currentNode->left;
                        while(tmp->right!=0&&tmp->right!=currentNode)
                                tmp=tmp->right;

                        if(tmp->right==0){
                                tmp->right=currentNode;
                                currentNode=currentNode->left;
                        }
                        else{
                                printReverse(currentNode->left,tmp);
                                tmp->right=0;
                                currentNode=currentNode->right;
                        }
                }
        }

    delete dump;
}

template<class Type>
void binarySearchTree<Type>::reverse(node* startNode,node* finalNode)
{
        if(startNode==finalNode)
                return;

        node* x=startNode;
        node* y=startNode->right;
        node* z=0;
        while(x!=finalNode){
                z=y->right;
                y->right=x;
                x=y;
                y=z;
        }
}

template<class Type>
void binarySearchTree<Type>::printReverse(node* startNode,node* finalNode)
{
        reverse(startNode,finalNode);

        node* currentNode=finalNode;
        while(true){
                cout<<currentNode->element<<" ";
                if(currentNode==startNode)
                        break;

                currentNode=currentNode->right;
        }

        reverse(finalNode,startNode);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值