数据结构与算法——搜索二叉树

原创
2016/11/05 21:00
阅读数 122

        基础的数据结构一般都会包含插入、删除、查找和修改等几个基本的操作。对于搜索二叉树而言,数据的插入和删除操作都是在叶子结点进行。搜索二叉树主要方便于数据的查找,其查找算法复杂度为O(h),h表示其树高,而二叉树的高度h在lgN和N之间,因此,查找算法强烈依赖于树形的好坏,而树形的好坏与数据的增长有关。对于好的数据输入,二叉树可以是平衡的高度为lgN,然而很难保证都是这种情况。对于坏的数据输入二叉树甚至可能退化成链表,其查找的复杂度为N,这是我们最不希望看到的。

        本文以C++作为算法语言编写二叉树的一个模版BinarySearchTree<T>,T可以是任何基础数据类型,在linux环境下g++编译通过。

#ifndef _BINARYSEARCHTREE_
#define _BINARYSEARCHTREE_
#include<iostream>
#include<cstdio>
template<typename T>
struct Node
{
  T data;
  Node* left;
  Node* right;
  Node<T>(T node=0):data(node){}
};

template<typename T>
class BinarySearchTree
{
private:
  Node<T> * root;
  unsigned int size;
  int num;
public:
  BinarySearchTree();//:root(NULL){}
  ~BinarySearchTree();
private:
  void destroyTree(Node<T>*);
public:
  Node<T>* getRootNode();
  unsigned int getSize();
  bool createTree(T d);
  bool addNode(T d);
  const Node<T> * findNode(T d,Node<T>* &) const; 
  void preorderdisplayNode(Node<T>*);
  void inorderdisplayNode(Node<T>*);
  void postorderdisplayNode(Node<T>*);
};

template<typename T>
BinarySearchTree<T>::BinarySearchTree():root(NULL),size(0),num(0)
{

}
 
template<typename T>
BinarySearchTree<T>::~BinarySearchTree()
{
   destroyTree(getRootNode());
}
 
template<typename T>
Node<T>* BinarySearchTree<T>::getRootNode()
{
   Node<T>* rootNode=this->root;
   return rootNode;
}
template<typename T>
unsigned int BinarySearchTree<T>::getSize()
{
  return this->size;
}

template<typename T>
void BinarySearchTree<T>::destroyTree(Node<T>* node)
{
  if(!node){
  delete node;
  destroyTree(node->left);
  destroyTree(node->right);
  }
}

template<typename T>
bool BinarySearchTree<T>::createTree(T d)
{
  if(!this->root){
     this->root=new Node<T>(d);
     size++;
     this->root->left=NULL;
     this->root->right=NULL;
     return true;
  }
  else{
    return true;
  }
  
}

template<typename T>
bool BinarySearchTree<T>::addNode(T d)
{
 Node<T>* parent= this->getRootNode();
    if(!parent){
      printf("error,the tree is  empty!\n");
      return false;
    }
    Node<T>* iPtr=parent;
    Node<T>* tmp=NULL;
    while(iPtr){
      if(d<=iPtr->data){
         tmp=iPtr;
         iPtr=iPtr->left;
      }
      else if(d>iPtr->data){
         tmp=iPtr;
         iPtr=iPtr->right;
      }
      else{
         throw "something error!";
      }
    }
    if(d>tmp->data){
      tmp->right=new Node<T>(d);
      size++;
    }
    else{
      tmp->left= new Node<T>(d);
      size++;
    }
 return true; 
}

template<typename T>
const Node<T> * BinarySearchTree<T>::findNode(T d,Node<T>* &node) const
{
   Node<T> * tmpNode=node;
   if(!tmpNode) return tmpNode;
   if(d>tmpNode->data){
     tmpNode=tmpNode->right;
     findNode(d,tmpNode);
     return tmpNode;
   }
   else if(d<tmpNode->data){
     tmpNode=tmpNode->left;
     findNode(d,tmpNode);
     return tmpNode;
   }
   else if(d==tmpNode->data){
     return tmpNode;
   }
   else {
     return NULL;
   }
}

template<typename T>
void BinarySearchTree<T>::inorderdisplayNode(Node<T>* node)
{
  Node<T>* tmpPtr=node;
  if(tmpPtr){
    inorderdisplayNode(tmpPtr->left);
    printf("%d ",tmpPtr->data);
    inorderdisplayNode(tmpPtr->right);
  }
  num=0;
}
template<typename T>
void BinarySearchTree<T>::preorderdisplayNode(Node<T>* node)
{
  Node<T>* tmpPtr=node;
  if(tmpPtr){
    printf("%d ",tmpPtr->data);
    preorderdisplayNode(tmpPtr->left);
    preorderdisplayNode(tmpPtr->right);
  }
  num=0;
}
template<typename T>
void BinarySearchTree<T>::postorderdisplayNode(Node<T>* node)
{
  Node<T>* tmpPtr=node;
  if(tmpPtr){
    postorderdisplayNode(tmpPtr->left);
    postorderdisplayNode(tmpPtr->right);
    printf("%d ",tmpPtr->data);
  }
  num=0;
}
#endif //binarysearchtree.h
#include<iostream>
#include"searchbinarytree.h"
using namespace std;

int main()
{
  BinarySearchTree<int> Tree1;
  Tree1.createTree(5); 
  Tree1.addNode(4);
  Tree1.addNode(7);
  Tree1.addNode(1);
  Tree1.addNode(2);
  Tree1.addNode(0);
  Tree1.addNode(3);
  Tree1.addNode(6);
  Tree1.addNode(8);
  Tree1.addNode(9);
  cout<<"inorder display node:"<<endl;
  Tree1.inorderdisplayNode(Tree1.getRootNode()); 
  endl(cout);
  cout<<"preorder display node:"<<endl;
  Tree1.preorderdisplayNode(Tree1.getRootNode()); 
  endl(cout);
  cout<<"postorder display node:"<<endl;
  Tree1.postorderdisplayNode(Tree1.getRootNode()); 
  endl(cout);
return 0;
}

对于一组数据,这里以0~9为例,不同的输入将造成树形的不同,从而影响查找数据的效率。

 

 

 

 

 

 

 

 

 

 

 

高度为4

 

 

 

 

 

 

 

 

 

 

 

 

高度为10,此时二叉树退化成链表,其查找算法复杂度和链表一样。

展开阅读全文
打赏
0
1 收藏
分享
加载中
更多评论
打赏
0 评论
1 收藏
0
分享
返回顶部
顶部