二叉排序树C++实现

来源:互联网 发布:淘宝找不到已买的宝贝 编辑:程序博客网 时间:2024/04/29 17:28

简介

学习了算法导论12章关于二叉排序树的内容,自己利用C++实现了二叉排序树的封装。由此对二叉树这种数据结构理解更加深刻了,对于递归在树中的应用之广更是有深切体会,例如递归创建,递归前,中,后序遍历,返回树高(个人最喜欢这个树高递归函数,一句话返回树高确实酷),递归删除等……因为很多树本身就是递归定义的。(删除某节点比较难,有3,4种情况要分别考虑,暂时没有实现,后续再补吧)
有什么不足之处希望不吝赐教!

具体实现

头文件二叉排序树类的定义

注释比较清楚,就不再赘述了:

#pragma once#include<iostream>using namespace std;//树节点定义,包含父节点指针(便于回溯前驱与后继)typedef struct Node {    int data;    struct Node *leftchild;    struct Node *rightchild;    struct Node *parent;}Node_t;/*二叉排序树类定义*/class BSearchTree{ public:    BSearchTree(void);      ~BSearchTree(void);    inline Node_t* getRoot() const { return this->root;}     void createBSTree(int *dataset, int size); //建立二叉排序树    bool insertNode(Node_t **root, int value); //插入新节点,需要传入二级指针(改变根指针的值)    void inorderTraverse(Node_t *root) const;  //中序遍历    void visitMiddleOrder() const;  //对上一函数继续封装    Node_t* searchNode(Node_t *root,int value) const; //按值查找    void searchByValue(int value) const; //对上一函数继续封装    //最大与最小代码对称    void getMax(Node_t *root) const; //获取最大值    void getMin(Node_t *root) const; //获取最小值    //前驱与后继代码对称    void getPredecessor(Node_t *node); //获取节点前驱     void getSuccessor(Node_t *node); //获取节点后继    int getHeight(Node_t *root) const; //返回树高 private:     Node_t *root; //根节点};

成员函数的实现:

#include "BSearchTree.h"BSearchTree::BSearchTree(void){    root = NULL;}BSearchTree::~BSearchTree(void){    //to do sth}//建立二叉排序树(导入数组内元素,逐一插入)void BSearchTree:: createBSTree(int *dataset, int size) {    for ( int i=0; i<size; i++ ) {        insertNode(&root,dataset[i]);    }}//插入新节点//注意因为要修改root根指针的值,所以需要传入二级指针bool BSearchTree:: insertNode(Node_t **root, int value) {    //初始化将插入的新节点    Node_t *new_node = new Node_t;    if ( new_node == NULL ) {        return false;       }    new_node->data = value;    new_node->leftchild = new_node->rightchild = new_node->parent = NULL;     //空树时,直接让根指针指向新节点    if( (*root) == NULL ) {        *root = new_node;        return true;    }     //插入到当前结点(*root)的左孩子      if ((*root)->leftchild == NULL && (*root)->data > value ) {        new_node->parent = (*root);        (*root)->leftchild = new_node;        return true;    }     //插入到当前结点(*root)的右孩子      if((*root)->rightchild == NULL && (*root)->data < value){          new_node->parent = (*root);          (*root)->rightchild = new_node;          return true;      }      //递归法插入新节点    if ( (*root)->data > value ) {  //新节点的值小于根节点,递归寻找左边空位        insertNode( &(*root)->leftchild,value);  //关键点    }    else if ( (*root)->data < value ) {  //新节点的值大于根节点,递归寻找右边空位        insertNode( &(*root)->rightchild,value);     } else {        return true;    }}//中序遍历void BSearchTree:: inorderTraverse(Node_t *root) const {    //递归出口    if ( root == NULL ) {        return;    }    inorderTraverse( root->leftchild );    cout<< root->data <<" ";    inorderTraverse( root->rightchild );}void BSearchTree::visitMiddleOrder() const {    inorderTraverse(this->root);}//按值查找,返回节点的地址Node_t* BSearchTree:: searchNode(Node_t *root,int value) const {    if ( root == NULL ) {        return NULL;    }    if ( root->data > value ) {        searchNode( root->leftchild,value);    }    else if ( root->data < value ) {        searchNode( root->rightchild,value);    } else {        return root;    }}void BSearchTree:: searchByValue(int value) const{    Node_t *p_findnode = this->searchNode(root,value);    if ( p_findnode == NULL ) {        cout<<"没有找到该节点"<<endl;    } else {        cout<< "该节点存在" <<endl;    }}//获取最大值void BSearchTree:: getMax(Node_t *root) const {    while( root->rightchild ) {        root = root->rightchild;    }    cout<<root->data<<endl;}//获取最小值void BSearchTree:: getMin(Node_t *root) const {    while( root->leftchild ) {        root = root->leftchild;    }    cout<<root->data<<endl;}//获取节点前驱void BSearchTree:: getPredecessor(Node_t *node) {    //节点如果有左子树,则其前驱节点是左子树的最大值    if ( node->leftchild != NULL ) {        return getMax( node->leftchild );    } else {        cout<<"(该点无左子树,开始回溯祖先...)"<<endl;    }    //如果没有右子树,则向上回溯,最顶层的祖先节点则是后继    Node_t *y = node->parent; //y首先指向该节点的父节点    while( y != NULL && node == y->leftchild ) {        node = y;        y = y->parent;    }    cout<<y->data;}//获取节点后继void BSearchTree:: getSuccessor(Node_t *node) {    //节点如果有右子树,则其后继节点是右子树的最小值    if ( node->rightchild != NULL ) {        return getMin( node->rightchild );    } else {        cout<<"(该点无右子树,开始回溯祖先...)"<<endl;    }    //如果没有右子树,则向上回溯,最顶层的祖先节点则是后继    Node_t *y = node->parent;    while( y != NULL && node == y->rightchild ) { //遇到第一个“拐角”回溯结束        node = y;  //节点向上爬一层        y = y->parent; //y也向上逐层回溯祖先    }    cout<<y->data;}//返回树高,树通用写法//ps:算法导论认为只有一个根节点时树高为0,我们常认为1int BSearchTree::getHeight(Node_t *root) const {    return root ?  max(getHeight(root->leftchild),getHeight(root->rightchild))+1 : -1;}

测试代码:

#include"BSearchTree.h"void main(void) {     int arrs[] = { 14,2,4,10,3,5,8,23,18,35 };    //int arrs[] = { 23, 65, 12, 3, 8, 76,  90, 21, 75, 34,345, 61 };    int len = sizeof(arrs) / sizeof(arrs[0]);    BSearchTree bsearch_tree;    bsearch_tree.createBSTree(arrs,len);    cout<<"中序遍历结果: ";    bsearch_tree.visitMiddleOrder();    cout<<endl;    cout<<"寻找节点3..."<<endl;    bsearch_tree.searchByValue(3);    cout<<endl;    cout<<"寻找节点100..."<<endl;    bsearch_tree.searchByValue(100);    cout<<endl;    cout<<"max :";    bsearch_tree.getMax(bsearch_tree.getRoot());    cout<<"min :";    bsearch_tree.getMin(bsearch_tree.getRoot());    cout<<endl;    cout<<"树高:"<< bsearch_tree.getHeight(bsearch_tree.getRoot())<<endl<<endl;    Node_t *pnext = bsearch_tree.searchNode(bsearch_tree.getRoot(),4);    cout<<"节点"<<pnext->data<<"的后继为:";    bsearch_tree.getSuccessor(bsearch_tree.searchNode(bsearch_tree.getRoot(),4));    pnext = bsearch_tree.searchNode(bsearch_tree.getRoot(),8);    cout<<"节点"<<pnext->data<<"的后继为:";    bsearch_tree.getSuccessor(bsearch_tree.searchNode(bsearch_tree.getRoot(),8));    cout<<endl;    cout<<endl;    Node_t *pbefore = bsearch_tree.searchNode(bsearch_tree.getRoot(),14);    cout<<"节点"<<pbefore->data<<"的前驱为:";    bsearch_tree.getPredecessor(bsearch_tree.searchNode(bsearch_tree.getRoot(),14));    pbefore = bsearch_tree.searchNode(bsearch_tree.getRoot(),18);    cout<<"节点"<<pbefore->data<<"的前驱为:";    bsearch_tree.getPredecessor(bsearch_tree.searchNode(bsearch_tree.getRoot(),18));    cout<<endl;    system("pause");}

运行结果:

这里写图片描述

0 0