数据结构-二叉树(应用篇)-之二叉搜索树 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.二叉搜索树定义 二叉搜索树,是指一棵空树或者具有下列性质的二叉树: 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值: 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根 ...
随机推荐
- 移植 MQTT broker mosquitto 到 omapl138
概述 本次移植使用创龙的 TL138-EVM 开发板,基于 TI 的 MCSDK 开发环境.具体上位机系统为 Ubuntu 12.04-32bit,软件环境基于创龙的用户手册搭建. 为了移植后在 13 ...
- BeautifulSoup 抓取网站url
1 # -*- coding:utf-8 -*- 2 import urlparse 3 import urllib2 4 from bs4 import BeautifulSoup 5 6 url ...
- C#:StreamReader读取.CSV文件(转换成DataTable)
using System.Data; using System.IO; /// <summary> /// Stream读取.csv文件 /// </summary> /// ...
- 谈谈CommonsChunkPlugin抽取公共模块
引言 webpack插件CommonsChunkPlugin的主要作用是抽取webpack项目入口chunk的公共部分,具体的用法就不做过多介绍,不太了解可以参考webpack官网介绍: 该插件是we ...
- JavaWeb之数据源连接池(4)---自定义数据源连接池
[续上文<JavaWeb之数据源连接池(3)---Tomcat>] 我们已经 了解了DBCP,C3P0,以及Tomcat内置的数据源连接池,那么,这些数据源连接池是如何实现的呢?为了究其原 ...
- CDH的安装
环境5台装有centos 6.9系统的服务器 1.网络配置 sudo vi /etc/sysconfig/network修改hostname: NETWORKING=yes HOSTNAME=ZXXS ...
- kendo ui grid选中行事件,获取combobox选择的值
背景: 以前用 telerik ui做的grid现在又要换成kendo ui,不过说句实话kendo ui真的比telerik好多,可以说超级升级改头换面.当然用的mvc的辅助方法,以前的teleri ...
- redis中使用 check-and-set 操作实现乐观锁
WATCH 命令可以为 Redis 事务提供 check-and-set (CAS)行为. 被 WATCH 的键会被监视,并会发觉这些键是否被改动过了. 如果有至少一个被监视的键在 EXEC 执行之前 ...
- c# 了解c# 面向对象
C#是微软公司发布的一种面向对象的.运行于.NET Framework之上的高级程序设计语言.并定于在微软职业开发者论坛(PDC)上登台亮相.C#是微软公司研究员Anders Hejlsberg的最新 ...
- 基于POI和DOM4将Excel(2007)文档写进Xml文件
刚进公司的training, 下面是要求: Requirements Write a java program to read system.xlsx Use POI API to parse all ...