用c++实现一个二叉排序树

来源:互联网 发布:nginx centos yum 编辑:程序博客网 时间:2024/06/02 02:46

二叉排序树又称二叉查找树(Binary Search Tree)。其定义为:二叉排序树或者收空树,或者是满足如下性质的二叉树。
(1)若它的左子树非空,则左子树上所有节点的值均小于根节点的值。
(2)若它的右子树非空,则右子树上所有节点的值均大于根节点的值。
(3)左右子树本身又各是一颗二叉排序树。
二叉排序树
二叉排序树数据结构如下:

//节点类定义class Node{    int data;    Node *parent;   //父节点    Node *left;        //左节点    Node *right;     //右节点    public:        Node():data(-1),parent(NULL),left(NULL),right(NULL){};        Node(int num):data(num),parent(NULL),left(NULL),right(NULL){};}

二叉排序树类的定义:

class Tree{    public:        Tree(int num[],int len);  //插入num数组的前len个数据        void insertNode1(int data);  //插入数据,用递归的方式        void insertNode(int data);   //插入数据,用非递归的方式        Node *searchNode(int data); //查找节点        void deleteNode(int data);    //删除节点以及子树     private:         void insertNode(Node* current,int data); //递归插入方法         Node* searchNode(Node* current,int data); //递归查找方法         void deleteNode(Node* current);   //递归删除方法    private:        Node *root; //根节点}

在private中的三个方法主要是为了封装性的考虑,指针root是私有成员变量,于是在public中使用递归方法的三个函数都只能有一个参数data,然而,这里只含有一个参数是无法进行递归计算的。因此他们内部调用了这三个private中的方法。
接下来说明各个方法的实现。
1,创建二叉排序树的方法(在构造函数中)

Tree::Tree(int num[],int len){    root=new Node(num[0]);//建立root节点    for(int i=1;i<len;i++)    {        insertNode1(num[i]);        /*insertNode(num[i]);*/    }};

2,插入节点操作

//以非递归的方式void Tree::insertNode1(int data){    Node *p,*par;    Node *newNode=new Node(data);    p=par=root;    while(p!=NULL)    {        par=p;        if(data>p->data)            p=p->right;            else if(data<p->data)                p=p->left;        else if(data==p->data)            {                delete newNode;  //不能插入重复数据                return;            }    }    newNode->parent=par;    if(par->data > newNode->data)        par->left=newNode;    else        par->right=newNode;}

它分为以下步骤:
(1)创建节点
(2)查找新建节点的插入位置
(3)把新建点插入目标节点的正确位置。

insertNode()内部调用private函数insertNode(),使用递归方式插入。

//插入数据为参数data的节点,调用递归插入的方法void Tree::insertNode(int data){    if(root!=NULL)    {        insertNode(root,data);    }}//递归插入方法void Tree::insertNode(Node* current,int data){    //如果data小于当前节点数据,则在当前节点的左子树插入    if(data<current->data)    {        if(current->left==NULL)//若不存在,则插入到左节点        {            current->left=new Node(data);            current->left->parent=current;        }        else            insert(current->left,data);    }    //如果data大于当前节点,则在右子树中插入    else if(data>current->data)    {        if(current->right==NULL)        {            current->right=new Node(data);            current->right->parent=current;        }        else            insertNode(current->right,data);    }    return;   //data等于当前节点数据时,不插入}

3,查找节点

Node* Tree::searchNode(Node* current,int data){    //如果data小于当前节点,则搜索左子树    if(data<current->data)    {        if(current->left==NULL)//如果不存在左子树            return NULL;        return searchNode(current->left,data);    }    /*如果data大于当前节点,则递归搜索其右子树*/    else if(data>current->data)    {        if(current->right==NULL)            return NULL;        return searchNode(current->right,data);    }    //如果相等,则返回current    return current;}

4,删除节点

void Tree::deleteNode(int data){    Node *current=NULL;    current=searchNode(data);   //查找节点    if(current!=NULL)    {        deleteNode(current);    }}void Tree::deleteNode(Node *current){    if(current->left!=NULL)         deleteNode(current->left);    if(current->right!=NULL)        deleteNode(current->right);    if(current->parent==NULL)    {             /*如果current是根节点,把root置空*/        delete current;        root=NULL;        return;    }    //将current父亲节点的相应指针置空    if(current->parent->data>current->data)        current->parent->left=NULL;    else        current->parent->right=NULL;    //最后删除此节点    delete current;}