数据结构-二叉树(应用篇)-之二叉搜索树 C和C++的实现
一、概念

二叉搜索树(Binary Sort Tree/Binary Search Tree...),是二叉树的一种特殊扩展。也是一种动态查找表。
在二叉搜索树中,左子树上所有节点的均小于根节点,右子树上所有节点的均值大于根节点。
所以,如果使用中序遍历的方法,树数据刚好以从小到大的形式排好序并打印出来。
前驱:在二叉树(前序/中序/后序)搜索中的上一个元素。
后继:在二叉树(前序/中序/后序)搜索中的下一个元素。
关于二叉树的其它性质,可以看上一篇:http://www.cnblogs.com/HongYi-Liang/p/7231440.html
二、程序
C++:
在上一篇中,我们已经实现了二叉树,本篇的二叉搜索树将在上一遍的二叉树类模板中继承。

BinarySearchTree.h
#ifndef _BINARYSEARCHTREE_H
#define _BINARYSEARCHTREE_H #include <iostream>
#include <queue>
#include <vector>
#include "BinaryTree.h"
#include "BiTreeNode.h" template <typename T>
class BinarySearchTree:public BinaryTree<T>
{
public:
BinarySearchTree(int size,int rootIndex,T data);
BinarySearchTree(vector<T> vect);
virtual ~BinarySearchTree(); //get
vector<T> getResult(); //add/delete
bool addNode(int index,T data);
bool insert(int index,T data, BiTreeNode<T> *pNode);
bool deleteMinNode();
bool deleteMaxNode(); virtual bool deleteNodeByIndex(int index); //删除节点(使用索引)
virtual bool deleteNodeByNode(BiTreeNode<T> *pNode); //删除节点(使用地址)
virtual bool deleteNodeByData(T data); //删除节点(使用数据) //search
bool searchNode(T data,BiTreeNode<T>** node); //sort
bool sortToVec();
bool sort(BiTreeNode<T> *pNode); //pinrtf
void BSTreePreorderTraversal(); //先序遍历
void BSTreeInorderTraversal(); //中序遍历
void BSTreeSubsequentTraversal(); //后序遍历 private:
vector<T> m_tVec;
}; template <typename T>
BinarySearchTree<T>::BinarySearchTree(int size,int rootIndex,T data):BinaryTree(size,int rootIndex,T data)
{ } template <typename T>
BinarySearchTree<T>::BinarySearchTree(vector<T> vect):BinaryTree((int)vect.size(),,vect[])
{
unsigned int size = vect.size();
for(unsigned int i=;i<size;i++)
{
this->addNode(i,vect[i]);
}
} template <typename T>
BinarySearchTree<T>::~BinarySearchTree()
{ } template <typename T>
vector<T> BinarySearchTree<T>::getResult()
{
sortToVec();
return m_tVec;
} template <typename T>
bool BinarySearchTree<T>::addNode(int index,T data)
{
if(IsTreeFull())
{
return false;
}
insert(index,data,m_pRoot);
return true;
} template <typename T>
bool BinarySearchTree<T>::insert(int index,T data, BiTreeNode<T> *pNode)
{
if(data < pNode->getData())
{
if(pNode ->getLChild() != NULL)
{
if(insert(index,data,pNode->getLChild()))
return true;
}
else
{
if(addLeftNodeByNode(index,data,pNode))
return true;
}
}
else
{
if(pNode ->getRChild() != NULL)
{
if(insert(index,data,pNode->getRChild()))
return true;
}
else
{
if(addRightNodeByNode(index,data,pNode))
return true;
}
}
return false;
} template <typename T>
bool BinarySearchTree<T>::deleteMinNode()
{
if(IsTreeEmpty())
return false; BiTreeNode<T> *pNode = m_pRoot;
while(pNode->getLChild() != NULL)
{
pNode = pNode->getLChild();
}
if(pNode==m_pRoot)
{
pNode = m_pRoot->getRChild();
while(pNode->getLChild()!=NULL)
{
pNode = pNode->getLChild();
}
} deleteNodeByNode(pNode);
return true ;
} template <typename T>
bool BinarySearchTree<T>::deleteMaxNode()
{
if(IsTreeEmpty())
return false; BiTreeNode<T> *pNode = m_pRoot;
while(pNode->getRChild() != NULL)
{
pNode = pNode->getRChild();
}
if(pNode==m_pRoot)
{
pNode = m_pRoot->getLChild();
while(pNode->getRChild()!=NULL)
{
pNode = pNode->getRChild();
}
} deleteNodeByNode(pNode);
return true;
} template <typename T>
bool BinarySearchTree<T>::deleteNodeByIndex(int index)
{
BiTreeNode<T> *pNode = getNodeByIndex(index);
if(NULL != pNode)
{
/*there are 3 condition in the following:
1、The node has no child.
2、The node only has left child or right child.
3、The node both has left and right child,so make the target node replaced by precursor,and then delete precursor by useing condition 2 function.
*/
/*condition 1:no child*/
if(NULL == pNode->getRChild() && NULL == pNode->getLChild())
{
if(pNode!=m_pRoot)
{
BiTreeNode<T> *pfatherNode= pNode->getParent();
if(pfatherNode->getLChild() == pNode)
{
pfatherNode->setLChild(NULL);
}
else
{
pfatherNode->setRChild(NULL);
}
this->m_iSize--;
delete pNode;
}
else
return false;//only root left
}
/*condition 3:The node both has left and right child*/
else if(NULL != pNode->getRChild() && NULL != pNode->getLChild())
{
BiTreeNode<T> *preNode = pNode->getInorderPrecursor();
pNode->setIndex(preNode->getIndex());
pNode->setData(preNode->getData());
pNode = preNode;
}
/*condition 2: The node only has left child or right child.*/
if(NULL == pNode->getRChild())
{
BiTreeNode<T> *pfatherNode= pNode->getParent();
if(pfatherNode->getLChild() == pNode )//Target node is father left son.
{
pfatherNode->setLChild(pNode->getLChild());//Target node left son link to it fater.
}
else//Target node is father right son.
{
pfatherNode->setRChild( pNode->getLChild());//Target node left son link to it father.
}
pNode->setLChild(NULL);
this->m_iSize--;
delete pNode;
}
else if(NULL == pNode->getLChild())
{
BiTreeNode<T> *pfatherNode=pNode->getParent();
if(pfatherNode->getLChild() == pNode )//Target node is father left son.
{
pfatherNode->setLChild(pNode->getRChild());//Target node left son link to it fater.
}
else//Target node is father right son.
{
pfatherNode->setRChild( pNode->getRChild());//Target node left son link to it father.
}
pNode->setRChild(NULL);
this->m_iSize--;
delete pNode;
}
return true;
}
else
return false;//if(NULL != pNode); there are no such node!
}
template <typename T>
bool BinarySearchTree<T>::deleteNodeByNode(BiTreeNode<T> *pNode)
{
return false;
} template <typename T>
bool BinarySearchTree<T>::deleteNodeByData(T data)
{
BiTreeNode<T> *pNode = m_pRoot;
if(searchNode(data,&pNode))
{
/*there are 3 condition in the following:
1、The node has no child.
2、The node only has left child or right child.
3、The node both has left and right child,so make the target node replaced by precursor,and then delete precursor by useing condition 2 function.
*/
/*condition 1:no child*/
if(NULL == pNode->getRChild() && NULL == pNode->getLChild())
{
if(pNode!=m_pRoot)
{
BiTreeNode<T> *pfatherNode= pNode->getParent();
if(pfatherNode->getLChild() == pNode)
{
pfatherNode->setLChild(NULL);
}
else
{
pfatherNode->setRChild(NULL);
}
this->m_iSize--;
delete pNode;
}
else
return false;//only root left
}
/*condition 3:The node both has left and right child*/
else if(NULL != pNode->getRChild() && NULL != pNode->getLChild())
{
BiTreeNode<T> *preNode = pNode->getInorderPrecursor();
pNode->setIndex(preNode->getIndex());
pNode->setData(preNode->getData());
pNode = preNode;
}
/*condition 2: The node only has left child or right child.*/
if(NULL == pNode->getRChild())
{
BiTreeNode<T> *pfatherNode= pNode->getParent();
if(pfatherNode->getLChild() == pNode )//Target node is father left son.
{
pfatherNode->setLChild(pNode->getLChild());//Target node left son link to it fater.
}
else//Target node is father right son.
{
pfatherNode->setRChild( pNode->getLChild());//Target node left son link to it father.
}
pNode->setLChild(NULL);
this->m_iSize--;
delete pNode;
}
else if(NULL == pNode->getLChild())
{
BiTreeNode<T> *pfatherNode=pNode->getParent();
if(pfatherNode->getLChild() == pNode )//Target node is father left son.
{
pfatherNode->setLChild(pNode->getRChild());//Target node left son link to it fater.
}
else//Target node is father right son.
{
pfatherNode->setRChild( pNode->getRChild());//Target node left son link to it father.
}
pNode->setRChild(NULL);
this->m_iSize--;
delete pNode;
}
return true;
}
else
return false;//if(searchNode(data,&pNode)); there are no such node!
} template <typename T>
bool BinarySearchTree<T>::searchNode(T data,BiTreeNode<T>** node)
{
BiTreeNode<T> *pNode = m_pRoot; if(data>m_pRoot->getData())
{
while(data>pNode->getData())
{
if(pNode->getRChild() != NULL)
{
pNode = pNode->getRChild();
}
else
{
return false;
}
}
while(data<pNode->getData())
{
if(pNode->getLChild() != NULL)
{
pNode = pNode->getLChild();
}
else
{
return false;
}
}
*node = pNode;
return true;
}
else
{
while(data<pNode->getData())
{
if(pNode->getLChild() != NULL)
{
pNode = pNode->getLChild();
}
else
{
return false;
}
}
while(data>pNode->getData())
{
if(pNode->getRChild() != NULL)
{
pNode = pNode->getRChild();
}
else
{
return false;
}
}
*node = pNode;
return true;
}
} template <typename T>
bool BinarySearchTree<T>::sortToVec()
{
m_tVec.clear();
sort(m_pRoot);
return true;
} template <typename T>
bool BinarySearchTree<T>::sort( BiTreeNode<T> *pNode)
{
if(pNode->getLChild() != NULL)
{
sort(pNode->getLChild());
} m_tVec.push_back(pNode->getData()); if(pNode->getRChild() != NULL)
{
sort(pNode->getRChild());
} return true;
} template <typename T>
void BinarySearchTree<T>::BSTreePreorderTraversal()
{
PreorderTraversal();
} template <typename T>
void BinarySearchTree<T>::BSTreeInorderTraversal()
{
InorderTraversal();
} template <typename T>
void BinarySearchTree<T>::BSTreeSubsequentTraversal()
{
SubsequentTraversal();
} #endif
BinaryTree.h
#ifndef _BINARYTREE_H
#define _BINARYTREE_H #include <iostream>
#include <queue>
#include "BiTreeNode.h"
using namespace std; template <typename T>
class BinaryTree
{
public:
BinaryTree(int size,int index,T data);
BinaryTree(int size);
virtual ~BinaryTree();
bool IsTreeEmpty(); //树是否为空
bool IsTreeFull(); //树的容量是否已满
//search
BiTreeNode<T> *getNodeByIndex(int index); //通过索引搜索节点
int getLeaves(); //获取树的叶子数
int getHeight(); //获取树的高度(包含根节点)
int getWidth(); //获取树的宽度(包含根节点)
int getNowSize(); //获取树现在的节点数(包含根节点)
int getMaxSize(); //获取树的最大节点数
//add/delete
bool addLeftNodeByIndex(int newIndex,T data,int searchIndex); //添加左子树(使用索引)
bool addRightNodeByIndex(int newIndex,T data,int searchIndex); //添加右子树(使用索引)
bool addLeftNodeByNode(int index,T data,BiTreeNode<T> *pNode); //添加左子树(使用节点地址)
bool addRightNodeByNode(int index,T data,BiTreeNode<T> *pNode); //添加右子树(使用节点地址) virtual bool deleteNodeByIndex(int index); //删除节点(使用索引)
virtual bool deleteNodeByNode(BiTreeNode<T> *pNode); //删除节点(使用地址) //traversal
void PreorderTraversal(); //先序遍历
void InorderTraversal(); //中序遍历
void SubsequentTraversal(); //后序遍历 protected:
BiTreeNode<T> *m_pRoot; //tree root
int m_iSize; //Tree now nodes size (without root)
int m_iMaxSize; //Tree max nodes size (without root)
}; template <typename T>
BinaryTree<T>::BinaryTree(int size,int index,T data)
{
m_pRoot = new BiTreeNode<T>(index,data);
m_pRoot->setLChild(NULL);
m_pRoot->setRChild(NULL);
m_pRoot->setParenet(NULL);
m_iSize = ;
m_iMaxSize = size;
} template <typename T>
BinaryTree<T>::BinaryTree(int size)
{
m_pRoot = new BiTreeNode<T>(,);
m_pRoot->setLChild(NULL);
m_pRoot->setRChild(NULL);
m_pRoot->setParenet(NULL);
m_iSize = ;
m_iMaxSize = size;
} template <typename T>
BinaryTree<T>::~BinaryTree()
{
if(NULL != m_pRoot)
delete m_pRoot;
m_pRoot=NULL;
} template <typename T>
bool BinaryTree<T>::IsTreeEmpty()
{
if(m_iSize == )
return true;
return false;
} template <typename T>
bool BinaryTree<T>::IsTreeFull()
{
if(m_iSize >= m_iMaxSize)
return true;
return false;
} //search
template <typename T>
BiTreeNode<T> *BinaryTree<T>::getNodeByIndex(int index)
{
if(NULL == m_pRoot)
{
return NULL;
}
return m_pRoot->NodeSearch(index);
} template <typename T>
int BinaryTree<T>::getLeaves()
{
if(NULL == m_pRoot)
{
return ;
}
return m_pRoot->NodeLeavesStatistics();
} template <typename T>
int BinaryTree<T>::getWidth()
{
if(NULL == m_pRoot)
{
return ;
}
int maxWidth=; //save max width
int parentWidth=; //save this width
int childrenWidth=; //save next width
queue<BiTreeNode<T>*> stdQueue;
BiTreeNode<T> *tempNode = m_pRoot;
if(tempNode -> getLChild() != NULL)
{
stdQueue.push(tempNode -> getLChild());
parentWidth ++;
}
if(tempNode -> getRChild() != NULL)
{
stdQueue.push(tempNode ->getRChild());
parentWidth ++;
} while(!stdQueue.empty())
{
while(parentWidth>)
{
tempNode = stdQueue.front();
stdQueue.pop();
if(tempNode -> getLChild() != NULL)
{
stdQueue.push(tempNode -> getLChild());
childrenWidth ++;
}
if(tempNode -> getRChild() != NULL)
{
stdQueue.push(tempNode ->getRChild());
childrenWidth ++;
}
parentWidth --;
}
parentWidth = childrenWidth;
if(parentWidth > maxWidth)
{
maxWidth = parentWidth;
}
childrenWidth =;
} // result = m_pRoot->NodeChildrenNodeWidth(&child);
return maxWidth;
} template <typename T>
int BinaryTree<T>::getHeight()
{
if(NULL == m_pRoot)
return ;
return m_pRoot->NodeChildrenNodeHeigh();//including root
} template <typename T>
int BinaryTree<T>::getNowSize()
{
if(NULL == m_pRoot)
{
return ;
}
//return m_iSize;//quickly get Size
return m_pRoot ->NodeChildrenStatistics();//including root
} template <typename T>
int BinaryTree<T>::getMaxSize()
{
return m_iMaxSize ;
} //add/delete
template <typename T>
bool BinaryTree<T>::addLeftNodeByIndex(int newIndex,T data,int searchIndex)
{
if(NULL == m_pRoot)
{
return false;
}
BiTreeNode<T> *tempNode;
tempNode = m_pRoot->NodeSearch(searchIndex);//find the node that index is = searchIndex
if(tempNode!=NULL)
{
return addLeftNodeByNode(newIndex,data,tempNode);
}
return false;
}
template <typename T>
bool BinaryTree<T>::addRightNodeByIndex(int newIndex,T data,int searchIndex)
{
if(NULL == m_pRoot)
{
return false;
}
BiTreeNode<T> *tempNode ;
tempNode = m_pRoot->NodeSearch(searchIndex);
if(tempNode!=NULL)
{
return addRightNodeByNode(newIndex,data,tempNode);
}
return false;
}
template <typename T>
bool BinaryTree<T>::addLeftNodeByNode(int index,T data,BiTreeNode<T> *pNode)
{
BiTreeNode<T> *pNodeCopy = pNode;//make a copy of pNode to protect the pNode being changed by accidentally
if(IsTreeFull())
{
return false ;
}
if(pNodeCopy -> getLChild() == NULL)
{
BiTreeNode<T> *newNode = new BiTreeNode<T>(index,data);
pNodeCopy->setLChild(newNode);
newNode->setParenet(pNodeCopy);
}
else
{
return false ;
} m_iSize++;
return true;
} template <typename T>
bool BinaryTree<T>::addRightNodeByNode(int index,T data,BiTreeNode<T> *pNode)
{
BiTreeNode<T> *pNodeCopy = pNode;//make a copy of pNode to protect the pNode being changed by accidentally
if(IsTreeFull())
{
return false ;
}
if(pNodeCopy -> getRChild() == NULL)
{
BiTreeNode<T> *newNode = new BiTreeNode<T>(index,data);
pNodeCopy->setRChild(newNode);
newNode->setParenet(pNodeCopy);
}
else
{
return false ;
} m_iSize++;
return true;
} template <typename T>
bool BinaryTree<T>::deleteNodeByIndex(int index)
{
if(IsTreeEmpty())
{
return false;
} BiTreeNode<T> *deleteNode = m_pRoot->NodeSearch(index);
if(deleteNode != NULL)
{
if(deleteNode == m_pRoot)
{
cout<<"BinaryTree<T>::deleteNodeByIndex():"<<index<<"是根节点不能删除"<<endl;
return false;
}
return deleteNodeByNode(deleteNode);
}
return false;
}
template <typename T>
bool BinaryTree<T>::deleteNodeByNode(BiTreeNode<T> *pNode)
{
if(IsTreeEmpty())
return false; if(pNode!=NULL)
{
/*clear parent Node L/RChild*/
BiTreeNode<T> *parentNode = pNode->getParent();
if(parentNode != NULL)
{
if(parentNode->getLChild() == pNode)
{
parentNode->setLChild(NULL);
}
else
{
parentNode->setRChild(NULL);
}
}
/*delete node*/
int SizeDec;//use to caculate how much Node was delete
SizeDec = pNode->NodeDelete();
m_iSize-=SizeDec;
return true;
}
return false;
} //traversal
template <typename T>
void BinaryTree<T>::PreorderTraversal()
{
cout<<"PerorderTraversal:"<<endl;
if(NULL == m_pRoot)
{
return ;
}
m_pRoot ->NodePreorderTraversal();
}
template <typename T>
void BinaryTree<T>::InorderTraversal()
{
cout<<"InorderTraversal:"<<endl;
if(NULL == m_pRoot)
{
return ;
}
m_pRoot ->NodeInorderTraversal();
}
template <typename T>
void BinaryTree<T>::SubsequentTraversal()
{
cout<<"SubsequentTraversal:"<<endl;
if(NULL == m_pRoot)
{
return ;
}
m_pRoot ->NodeSubsequentTraversal();
} #endif
BiTreeNode.h
#ifndef _BITREENODE_H
#define _BITREENODE_H
#include<iostream>
using namespace std; template <typename T>
class BiTreeNode
{
public:
BiTreeNode();
BiTreeNode(int index,T data);
virtual ~BiTreeNode();
//get data
int getIndex();
T getData();
BiTreeNode *getParent();
BiTreeNode *getLChild();
BiTreeNode *getRChild();
BiTreeNode *getInorderPrecursor(); //获取中序前驱
BiTreeNode *getInorderSubsequence(); //获取中序后继
//set data
void setIndex(int index);
void setData(T data);
void setParenet(BiTreeNode *Node);
void setLChild(BiTreeNode *Node);
void setRChild(BiTreeNode *Node);
//else
BiTreeNode *NodeSearch(int index); //通过索引搜索节点(以本节点作为根寻找树的某个节点)
int NodeLeavesStatistics(int leaves = ); //统计叶子数
int NodeChildrenNodeHeigh(); //统计子节点的最大高度(包含本节点)/(以本节点作为根求树的高度)
int NodeChildrenStatistics(); //统计子节点数(包含本节点)
int NodeDelete(); //删除节点
//traversal
void NodePreorderTraversal();
void NodeInorderTraversal();
void NodeSubsequentTraversal(); private:
int m_iIndex;
T m_tData;
BiTreeNode *m_pParent;
BiTreeNode *m_pLeftChild;
BiTreeNode *m_pRightChild; //struct NodeWidth<T> stNodeWidth;
}; template <typename T>
BiTreeNode<T>::BiTreeNode()
{
m_iIndex = ;
m_tData = ;
m_pParent = NULL;
m_pLeftChild = NULL;
m_pRightChild = NULL;
} template <typename T>
BiTreeNode<T>::BiTreeNode(int index,T data)
{
m_iIndex = index;
m_tData = data;
m_pParent = NULL;
m_pLeftChild = NULL;
m_pRightChild = NULL;
} template <typename T>
BiTreeNode<T>::~BiTreeNode()
{
if(m_pLeftChild != NULL)
{
m_pLeftChild->NodeDelete();
m_pLeftChild = NULL;
}
if(m_pRightChild != NULL)
{
m_pRightChild->NodeDelete();
m_pRightChild = NULL;
}
m_pParent = NULL;
}
/*-----------------------getdata------------------------*/
template <typename T>
int BiTreeNode<T>::getIndex()
{
return m_iIndex;
} template <typename T>
T BiTreeNode<T>::getData()
{
return m_tData;
} template <typename T>
BiTreeNode<T> *BiTreeNode<T>::getParent()
{
return m_pParent;
} template <typename T>
BiTreeNode<T> *BiTreeNode<T>::getLChild()
{
return m_pLeftChild;
} template <typename T>
BiTreeNode<T> *BiTreeNode<T>::getRChild()
{
return m_pRightChild;
} template <typename T>
BiTreeNode<T> *BiTreeNode<T>::getInorderPrecursor()
{
/*
condition 1: Node has left child.
condition 2: Node hasn't left child,and it is its father right child.
condition 3: Node hasn't left child,and it is its father left child.
*/
/*condition 1:node has left child*/
if(NULL != this->getLChild())
{
BiTreeNode *tempNode=this->getLChild();
while(NULL != tempNode->getRChild() )
{
tempNode=tempNode->getRChild();
}
return tempNode;
}
else
{
BiTreeNode *fatherNode=this->getParent();
if(NULL == fatherNode)
{
return NULL;//it is root.
}
/*condition 2*/
else if(fatherNode->getRChild() == this)
{
return fatherNode;
}
/*condition*/
else
{
while( fatherNode->getParent()->getRChild() != fatherNode)
{
fatherNode =fatherNode ->getParent();
if(NULL == fatherNode )
{
return NULL;//it is root;
}
}
return fatherNode->getParent();
}
}
return NULL;
} template <typename T>
BiTreeNode<T> *BiTreeNode<T>::getInorderSubsequence() //获取中序后继
{
/*
condition 1: Node has right child.
condition 2: Node hasn't right child,and it is its father left child.
condition 3: Node hasn't right child,and it is its father right child.
*/
/*condition 1*/
if(NULL != this->getRChild())
{
BiTreeNode *tempNode = this->getRChild();
while(NULL != tempNode->getLChild() )
{
tempNode=tempNode->getLChild();
}
return tempNode;
}
/*condition 2*/
else
{
BiTreeNode *fatherNode=this->getParent();
if(NULL == fatherNode)//it is root.
{
return NULL;
}
else if(fatherNode->getLChild() == this)
{
return fatherNode;
}
else
{
while(fatherNode->getParent()->getLChild() !=fatherNode)
{
fatherNode=fatherNode->getParent();
if(NULL == fatherNode)
{
return NULL;//it is root;
}
}
return fatherNode->getParent();
}
}
}
/*-----------------------setdata------------------------*/
template <typename T>
void BiTreeNode<T>::setIndex(int index)
{
m_iIndex = index;
}
template <typename T>
void BiTreeNode<T>::setData(T data)
{
m_tData = data;
}
template <typename T>
void BiTreeNode<T>::setParenet(BiTreeNode *Node)
{
m_pParent = Node;
} template <typename T>
void BiTreeNode<T>::setLChild(BiTreeNode *Node)
{
m_pLeftChild = Node;
} template <typename T>
void BiTreeNode<T>::setRChild(BiTreeNode *Node)
{
m_pRightChild = Node;
} /*-----------------------else------------------------*/
template <typename T>
BiTreeNode<T> *BiTreeNode<T>::NodeSearch(int index)
{
BiTreeNode<T> *tempNode = NULL;
if(m_iIndex == index)
{
return this;
}
if(m_pLeftChild != NULL)
{
tempNode = m_pLeftChild->NodeSearch(index);
if(tempNode != NULL)//match
{
return tempNode;
}
} if(m_pRightChild !=NULL)
{
tempNode = m_pRightChild->NodeSearch(index);
if(tempNode != NULL)// match
{
return tempNode;
}
} return NULL;
} /*statistcal children node heigh(includding me)*/
template <typename T>
int BiTreeNode<T>::NodeChildrenNodeHeigh()
{
int heightLeft = ;
int heightRight =;
if(m_pLeftChild != NULL)
{
heightLeft += m_pLeftChild->NodeChildrenNodeHeigh();
}
if(m_pRightChild != NULL)
{
heightRight += m_pRightChild->NodeChildrenNodeHeigh();
}
if(heightRight > heightLeft)
{
return ++heightRight;
}
else
{
return ++heightLeft;
}
} /*statistcal leaves node(includding me)*/
template <typename T>
int BiTreeNode<T>::NodeLeavesStatistics(int leaves)
{
if(this->m_pLeftChild != NULL)
{
leaves = this->m_pLeftChild->NodeLeavesStatistics(leaves);
}
if(this->m_pRightChild != NULL)
{
leaves = this->m_pRightChild->NodeLeavesStatistics(leaves);
}
if(this->getLChild() == NULL && this->getRChild() == NULL)
{
leaves ++;
}
return leaves;
}
/*statistcal children node(includding me)*/
template <typename T>
int BiTreeNode<T>::NodeChildrenStatistics()
{
int iCnt=;
if(this->m_pLeftChild != NULL)
{
iCnt+=this->m_pLeftChild->NodeChildrenStatistics();
}
if(this->m_pRightChild!= NULL)
{
iCnt+=this->m_pRightChild->NodeChildrenStatistics();
}
iCnt++;
return iCnt;
} template <typename T>
int BiTreeNode<T>::NodeDelete()
{
int Times=;
if(this->m_pLeftChild != NULL)
{
//delete this->getLChild();
Times+=this->m_pLeftChild->NodeDelete();
this->m_pLeftChild =NULL;
}
if(this->m_pRightChild!= NULL)
{
//delete this->getRChild();
Times+=this->m_pRightChild->NodeDelete();
this->m_pRightChild =NULL;
}
Times++;
delete this;
return Times;
}
/*-----------------------traversal------------------------*/
template <typename T>
void BiTreeNode<T>::NodePreorderTraversal()
{
cout<<"Index:"<<this->getIndex()<<";Data:"<<this->getData()<<endl; if(this->getLChild() != NULL)
{
this->getLChild()->NodePreorderTraversal();
} if(this->getRChild() != NULL)
{
this->getRChild()->NodePreorderTraversal();
}
} template <typename T>
void BiTreeNode<T>::NodeInorderTraversal()
{
if(this->getLChild() != NULL)
{
this->getLChild()->NodeInorderTraversal();
} cout<<"Index:"<<this->getIndex()<<";Data:"<<this->getData()<<endl; if(this->getRChild() != NULL)
{
this->getRChild()->NodeInorderTraversal();
}
} template <typename T>
void BiTreeNode<T>::NodeSubsequentTraversal()
{
if(this->getLChild() != NULL)
{
this->getLChild()->NodeSubsequentTraversal();
} if(this->getRChild() != NULL)
{
this->getRChild()->NodeSubsequentTraversal();
} cout<<"Index:"<<this->getIndex()<<";Data:"<<this->getData()<<endl;
} #endif
main.c
#include <iostream>
#include <vector>
#include "BinaryTree.h"
#include "BinarySearchTree.h" using namespace std; int main()
{
/*初始化一个vec向量用于建树*/
vector<int> Vec1;
Vec1.push_back();
Vec1.push_back();
Vec1.push_back();
Vec1.push_back();
Vec1.push_back();
Vec1.push_back();
Vec1.push_back();
Vec1.push_back();
Vec1.push_back();
Vec1.push_back();
/*建立一颗搜索二叉树*/
BinarySearchTree<int> BSTree(Vec1);
/*中序遍历*/
BSTree.BSTreeInorderTraversal();
/*排序并按顺序打印*/
vector<int> Vec2 = BSTree.getResult();
for(unsigned int i=;i<Vec2.size();i++)
{
cout<<Vec2[i]<<" ";
}
cout<<endl;
/*获取元素个数*/
cout<<"size:"<<BSTree.getNowSize()<<endl;
cout<<"width:"<<BSTree.getWidth()<<endl;
cout<<"height:"<<BSTree.getHeight()<<endl; /*删除元素*/
// BSTree.deleteMinNode();
// BSTree.deleteMaxNode();
BSTree.deleteNodeByData();
//BSTree.deleteNodeByIndex(50);
Vec2 = BSTree.getResult();
for(unsigned int i=;i<Vec2.size();i++)
{
cout<<Vec2[i]<<" ";
}
cout<<endl;
cout<<"size:"<<BSTree.getNowSize()<<endl; system("pause");
return ;
}
构建二叉树如图所示

运行结果:

在程序中,主要讲述以下两个重点:
- 添加节点
- 删除节点
添加节点:

先看下,对于二叉搜索树,
删除节点:

数据结构-二叉树(应用篇)-之二叉搜索树 C和C++的实现的更多相关文章
- 数据结构学习笔记_树(二叉搜索树,B-树,B+树,B*树)
一.查找二叉树(二叉搜索树BST) 1.查找二叉树的性质 1).所有非叶子结点至多拥有两个儿子(Left和Right): 2).所有结点存储一个关键字: 3).非叶子结点的左指针指向小于其关键字的子树 ...
- 剑指Offer的学习笔记(C#篇)-- 二叉搜索树的后序遍历序列
题目描述 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 一 . 解题思想与二叉搜索树概念 (1). 二叉树 ...
- 【遍历二叉树】07恢复二叉搜索树【Recover Binary Search Tree】
开一个指针数组,中序遍历这个二叉搜索树,将节点的指针依次保存在数组里, 然后寻找两处逆序的位置, 中序便利里BST得到的是升序序列 ++++++++++++++++++++++++++++++++++ ...
- [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法
二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...
- 【数据结构05】红-黑树基础----二叉搜索树(Binary Search Tree)
目录 1.二分法引言 2.二叉搜索树定义 3.二叉搜索树的CRUD 4.二叉搜索树的两种极端情况 5.二叉搜索树总结 前言 在[算法04]树与二叉树中,已经介绍过了关于树的一些基本概念以及二叉树的前中 ...
- 小白专场-是否同一颗二叉搜索树-python语言实现
目录 一.二叉搜索树的相同判断 二.问题引入 三.举例分析 四.方法探讨 4.1 中序遍历 4.2 层序遍历 4.3 先序遍历 4.4 后序遍历 五.总结 六.代码实现 一.二叉搜索树的相同判断 二叉 ...
- 【算法】【python实现】二叉搜索树插入、删除、查找
二叉搜索树 定义:如果一颗二叉树的每个节点对应一个关键码值,且关键码值的组织是有顺序的,例如左子节点值小于父节点值,父节点值小于右子节点值,则这棵二叉树是一棵二叉搜索树. 类(TreeNode):定义 ...
- LeetCode(108):将有序数组转换为二叉搜索树
Easy! 题目描述: 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1. 示例: 给定有序数组 ...
- 二叉搜索树详解(Java实现)
1.二叉搜索树定义 二叉搜索树,是指一棵空树或者具有下列性质的二叉树: 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值: 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根 ...
随机推荐
- Windows环境下部署Tomcat服务器图文教程
Tomcat是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP程序的首选. 本文将详细介绍在Windows环境下 ...
- webpack入门(2)
webpack入门(2) ps:每个案例都是基于前一个案例改造的 webpack入门(1) 戳这里 案例源码戳这里 十二.ProvidePlugin 自动加载模块 new webpack.Provid ...
- (转)解决jdk1.8中发送邮件失败(handshake_failure)问题
解决jdk1.8中发送邮件失败(handshake_failure)问题 作者 zhisheng_tian 2016.08.12 22:44* 字数 1573 阅读 2818评论 6喜欢 9 暑假在家 ...
- 「mysql优化专题」主从复制面试宝典!面试官都没你懂得多!(11)
内容较多,可先收藏,目录如下: 一.什么是主从复制 二.主从复制的作用(重点) 三.主从复制的原理(重中之重) 四.三步轻松构建主从 五.必问面试题干货分析(最最重要的点) 一.什么是主从复制(技术文 ...
- Angular 非父子组件间的service数据通信
完成思路:以service.ts(主题subject---订阅sbuscribe模式)为数据中转中间件,通过sku.ts的数据更改监测机制,同步更改service.ts中的数据,同时buy.ts组件实 ...
- 一些常用的vim编辑器快捷键:
一些常用的vim编辑器快捷键: h」.「j」.「k」.「l」,分别控制光标左.下.上.右移一格. 按「ctrl」+「b」:屏幕往“后”移动一页. 按「ctrl」+「f」:屏幕往“前”移动一页. 按「c ...
- Java I/O---概述
对于程序设计者来说,创建一个好的输入/输出系统(I/O)系统是一项艰难的任务. 现在大量不同方案已经说明了这一点.挑战似乎来自于要涵盖所有的可能性.不仅存在各种I/O源端和想要与之通信的接收端(文件. ...
- [置顶]
android ListView包含Checkbox滑动时状态改变
题外话: 在xamarin android的开发中基本上所有人都会遇到这个小小的坎,的确有点麻烦,当时我也折腾了好一半天,如果你能看到这篇博客,说明你和我当初也是一样的焦灼,如果你想解决掉这个小小的坎 ...
- java中可变长参数
** * Created by Lenovo on 2017/12/10. * java中可变长参数 */ public class reflect04 { //m1有一个int类型的可比变长参数 / ...
- 某次送温暖考试的 c题
题目大意: 给定n个点的无根树,树上每个点都有一个非负的点权. 树上的路径的价值定义为树上路径的点权和-树上路径的点权最大值; 现在给定一个参数P询问有多少条路径的价值是P的倍数(注意单点也算路径,路 ...