数据结构-二叉树(应用篇)-之二叉搜索树 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.二叉搜索树定义 二叉搜索树,是指一棵空树或者具有下列性质的二叉树: 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值: 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根 ...
随机推荐
- python decorator 基础
一般来说,装饰器是一个函数,接受一个函数(或者类)作为参数,返回值也是也是一个函数(或者类).首先来看一个简单的例子: # -*- coding: utf-8 -*- def log_cost_tim ...
- 如何通过Mock API提高APP开发效率?
APP开发过程中,如果可以在客户端的正常项目代码中,自然地(不影响最终apk)添加一种模拟服务器数据返回的功能,这样就可以很方便的在不依赖服务器的情况下展开客户端的开发. Mock API提供了这一问 ...
- 其他函数:值为NULL时的默认值NVL,DECODE
NVL(列,默认数字值),此函数返回值为数值型,非NULL时返回原始值,NULL时返回默认数字值. DECODE:
- 解决vue.js修改数据无法触发视图
data:{checkValue:{}}that.checkValue[key] = [] 赋值无法实时改变变量:(数据其实最终被修改,但是并没有触发检测从而更新视图)原因:Vue 不能检测到对象属性 ...
- APP安全--网络传输安全 AES/RSA/ECC/MD5/SHA
移动端App安全如果按CS结构来划分的话,主要涉及客户端本身数据安全,Client到Server网络传输的安全,客户端本身安全又包括代码安全和数据存储安全.所以当我们谈论App安全问题的时候一般来说在 ...
- C++模板显式实例化,隐式实例化,特化(具体化,偏特化)辨析
最近再次看C++ PRIMER PLUS的时候看到这个部分感觉讲得很烂,前后口径不一致,所以写个辨析让自己明白的同时也希望对此不太清楚的朋友能搞懂. 总结一下,C++只有模板显式实例化(explici ...
- softmax分类算法原理(用python实现)
逻辑回归神经网络实现手写数字识别 如果更习惯看Jupyter的形式,请戳Gitthub_逻辑回归softmax神经网络实现手写数字识别.ipynb 1 - 导入模块 import numpy as n ...
- geoserver安装部署步骤
方式一:直接在geoserver官网下载zip源代码解压包,直接部署在tomcat里面运行geoserver: 方式二:下载安装包方式 以GeoServer2.8.5版本为准,安装之前必须要保证你机子 ...
- Xamarin Android Gestures详解
通过Gesture的监听我们将实现一个,手指的快速滑动显示坐标的变化,我们先来看一看效果图: 1.Android中手势交互的执行顺序 1.手指触碰屏幕时,触发MotionEvent事件! 2.该事件被 ...
- BZOJ 4553 Tjoi2016&Heoi2016 序列
Tjoi2016&Heoi2016序列 Description 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值 可能会变化,但同一个时刻最 ...