数据结构基础 之 二叉搜索树的思想与实现

原创 2015年07月06日 16:22:17

【摘要】

首先,本文阐述二叉搜索树的基本概念,然后,对二叉搜索树的数据结构进行性能分析并给出优化数据结构。最后,贴上了二叉搜索树的创建与遍历的源码。

【正文】

二叉排序树(BinarySortTree)

二叉排序树(BinarySortTree)又称二叉查找树、二叉搜索树。

它或者是一棵空树;或者是具有下列性质的二叉树:

若左子树不空,则左子树上所有结点的值均小于它的根结点的值;若右子树不空,则右子树上所有结点的值均大于它的根结点的值;左、右子树也分别为二叉排序树。

若子树为空,查找不成功。

二叉排序树性能分析
每个结点的C(i)为该结点的层次数。最坏情况下,当先后插入的关键字有序时,构成的二叉排序树蜕变为单支树,树的深度为,其平均查找长度为(n+1)/2(和顺序查找相同),最好的情况是二叉排序树的形态和折半查找的判定树相同,其平均查找长度和log 2 (n)成正比。
二叉排序树优化

AVL树、红黑树、Size Balanced Tree(SBT)、Treap(Tree+Heap)这些均可以使查找树的高度为O(log(n))。

【二叉搜索树的创建与遍历源码】

#include <iostream>
using namespace std;
//树结点类的实现
template<class Elem>
class TreeNode
{
public:
<span style="white-space:pre">	</span>TreeNode(Elem dataVal,TreeNode* leftVal     = NULL,TreeNode* rightVal     = NULL)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>data     = dataVal;
<span style="white-space:pre">		</span>left     = leftVal;
<span style="white-space:pre">		</span>right     = rightVal;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>TreeNode(TreeNode* leftVal     = NULL,TreeNode* rightVal     = NULL)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>left     = leftVal;
<span style="white-space:pre">		</span>right     = rightVal;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>TreeNode* GetLeft()
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>return left;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>TreeNode* GetRight()
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>return right;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>Elem GetVal()
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>return data;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>void SetVal(Elem it)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>data     = it;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>void SetLeft(TreeNode<Elem>* l)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>left     = l;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>void SetRight(TreeNode<Elem>* r)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>right     = r;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>TreeNode* left;
<span style="white-space:pre">	</span>TreeNode* right;
<span style="white-space:pre">	</span>Elem data;
};
//树的类型实现。
template<class Elem>
class SearchTree
{
public:
<span style="white-space:pre">	</span>SearchTree(Elem it)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>init(it);
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>~SearchTree()
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>DeleteTree(root);
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>void init(Elem);
<span style="white-space:pre">	</span>void DeleteTree(TreeNode<Elem>*);
<span style="white-space:pre">	</span>void InsertNode(TreeNode<Elem>*,Elem item);
<span style="white-space:pre">	</span>void PreOrder(TreeNode<Elem>*);
<span style="white-space:pre">	</span>bool Find(TreeNode<Elem>*,Elem);
<span style="white-space:pre">	</span>TreeNode<Elem>* GetRoot()
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>return root;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>void InOrder(TreeNode<Elem>* T);
<span style="white-space:pre">	</span>void PostOrder(TreeNode<Elem>* T);
private:
<span style="white-space:pre">	</span>TreeNode<Elem>* root;
};
template<class Elem>
void SearchTree<Elem>::init(Elem item)
{
<span style="white-space:pre">	</span>root     = new TreeNode<Elem>(item,NULL,NULL);
}
template<class Elem>
void SearchTree<Elem>::DeleteTree(TreeNode<Elem>* T)
{
<span style="white-space:pre">	</span>if(T!     = NULL)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>DeleteTree(T->GetLeft());
<span style="white-space:pre">		</span>DeleteTree(T->GetRight());
<span style="white-space:pre">		</span>delete T;
<span style="white-space:pre">	</span>}
}
//插入结点。
template<class Elem>
void SearchTree<Elem>::InsertNode(TreeNode<Elem>* T,Elem item)
{
<span style="white-space:pre">	</span>TreeNode<Elem>* pointer     = NULL;
<span style="white-space:pre">	</span>if(T     =     = NULL)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>init(item);
<span style="white-space:pre">		</span>return;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>else pointer     = T;
<span style="white-space:pre">	</span>while(1)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>if(pointer->GetVal()     =     = item) 
<span style="white-space:pre">			</span>return;
<span style="white-space:pre">		</span>else 
<span style="white-space:pre">			</span>if(pointer->GetVal()>item)
<span style="white-space:pre">			</span>{ 
<span style="white-space:pre">				</span>if(pointer->GetLeft()     =     = NULL)
<span style="white-space:pre">				</span>{
<span style="white-space:pre">					</span>pointer->left     = new TreeNode<Elem>(item,NULL,NULL);
<span style="white-space:pre">					</span>return;
<span style="white-space:pre">				</span>}
<span style="white-space:pre">				</span>else
<span style="white-space:pre">					</span>pointer     = pointer->left;
<span style="white-space:pre">			</span>}
<span style="white-space:pre">			</span>else
<span style="white-space:pre">			</span>{
<span style="white-space:pre">				</span>if(pointer->GetRight()     =     = NULL)
<span style="white-space:pre">				</span>{
<span style="white-space:pre">					</span>pointer->right     = new TreeNode<Elem>(item,NULL,NULL);
<span style="white-space:pre">					</span>return;
<span style="white-space:pre">				</span>}
<span style="white-space:pre">				</span>else
<span style="white-space:pre">					</span>pointer     = pointer->right;
<span style="white-space:pre">			</span>}
<span style="white-space:pre">	</span>}
}
//前序递归遍历。
template<class Elem>
void SearchTree<Elem>::PreOrder(TreeNode<Elem>*T)
{
<span style="white-space:pre">	</span>if(T!     = NULL)
<span style="white-space:pre">		</span>{
<span style="white-space:pre">			</span>cout<<T->GetVal()<<" ";
<span style="white-space:pre">			</span>PreOrder(T->GetLeft());
<span style="white-space:pre">			</span>PreOrder(T->GetRight());
<span style="white-space:pre">		</span>}
}
//二叉递归查找
template<class Elem>
bool SearchTree<Elem>::Find(TreeNode<Elem>* T,Elem item)
{
<span style="white-space:pre">	</span>if(T     =     = NULL)
<span style="white-space:pre">		</span>return false;
<span style="white-space:pre">	</span>else if(T->GetVal()>item)
<span style="white-space:pre">		</span>return  Find(T->left,item);
<span style="white-space:pre">	</span>else if(T->GetVal()<item)
<span style="white-space:pre">		</span>return Find(T->right,item);
<span style="white-space:pre">	</span>else
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>item     = T->GetVal();
<span style="white-space:pre">		</span>return true;
<span style="white-space:pre">	</span>} 
}
//中序递归遍历。
template<class Elem>
void SearchTree<Elem>::InOrder(TreeNode<Elem>*T)
{
<span style="white-space:pre">	</span>if(T!     = NULL)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>InOrder(T->left);
<span style="white-space:pre">		</span>cout<<T->data<<" ";
<span style="white-space:pre">		</span>InOrder(T->right);
<span style="white-space:pre">	</span>}
}
//后序递归遍历。
template<class Elem>
void SearchTree<Elem>::PostOrder(TreeNode<Elem>* T)
{
<span style="white-space:pre">	</span>if(T!     = NULL)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>PostOrder(T->left);
<span style="white-space:pre">		</span>PostOrder(T->right);
<span style="white-space:pre">		</span>cout<<T->data<<" ";
<span style="white-space:pre">	</span>}
}
int main()
{
<span style="white-space:pre">	</span>SearchTree<char> A('h');//先创建一个根结点。
<span style="white-space:pre">	</span>char it;
<span style="white-space:pre">	</span>char item;
<span style="white-space:pre">	</span>TreeNode<char>* b;
<span style="white-space:pre">	</span>b     = A.GetRoot();
<span style="white-space:pre">	</span>cout<<"insert any number in the tree"<<endl;
<span style="white-space:pre">	</span>cout<<"when you enter '# 'is end!"<<endl;
<span style="white-space:pre">	</span>cin>>item;
<span style="white-space:pre">	</span>while(item!     = '#')
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>A.InsertNode(b,item);    //连续插入结点。
<span style="white-space:pre">		</span>cin>>item;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>cout<<"PreOrder print all the number:";
<span style="white-space:pre">	</span>A.PreOrder(b);
<span style="white-space:pre">	</span>cout<<endl;
<span style="white-space:pre">	</span>cout<<"inorder print:";
<span style="white-space:pre">	</span>A.InOrder(b);
<span style="white-space:pre">	</span>cout<<endl;
<span style="white-space:pre">	</span>cout<<" PostOrder print:";
<span style="white-space:pre">	</span>A.PostOrder(b);
<span style="white-space:pre">	</span>cout<<endl;
<span style="white-space:pre">	</span>cin>>it;
<span style="white-space:pre">	</span>if(A.Find(b,it))
<span style="white-space:pre">		</span>cout<<"there is the same number!";
<span style="white-space:pre">	</span>else
<span style="white-space:pre">		</span>cout<<"there isn't the number!";
<span style="white-space:pre">	</span>return 0;
}


【后序遍历判断是否二叉树】

http://blog.csdn.net/pengyan0812/article/details/46409745

冒泡排序(BubbleSort)思想与实现

冒泡排序也属于简单的排序方法,时间复杂度为:O(n^2)。 (1) 冒泡排序的思想 冒泡排序的思想就是:该排序算法意在从后往前像气泡一样,以此冒出数组中值小的元素。 以升序为例,假设数组的长度为siz...
  • disappear_XueChao
  • disappear_XueChao
  • 2017年08月28日 20:02
  • 238

数据结构基础 之 单链表 各类操作、思想与实现

本文从单链表头结点,头指针展开,讲述单链表的实现,分析并给出单链表创建、插入、删除、测长、输出、逆置、排序的思想与代码实现。...
  • u013630349
  • u013630349
  • 2015年04月06日 20:18
  • 693

数据结构之 二叉查找树(C语言实现)

数据结构之 二叉查找树1. 二叉查找树的定义二叉查找树(binary search tree)是一棵二叉树,或称为二叉搜索树,可能为空;一棵非空的二叉查找树满足一下特征: 每个元素有一个关键字,并且任...
  • men_wen
  • men_wen
  • 2017年03月28日 20:42
  • 594

数据结构—二叉搜索树的创建、结点的插入和删除

代码如下: 头文件StudyBST.h #define TRUE 1 #define ERROR 0 #define OK 1 #define REEO...
  • u012258911
  • u012258911
  • 2015年08月29日 15:52
  • 1062

二叉查找树的C++实现

二叉查找树的插入和删除详解请看:http://blog.csdn.net/sysu_arui/article/details/7865864 前面详细讲解了二叉查找树插入和删除,现在给出完整的C++...
  • sysu_arui
  • sysu_arui
  • 2012年08月21日 18:11
  • 2225

数据结构与算法基础

1、概论基本概念和术语数据(Data)     数据是信息的载体。它能够被计算机识别、存储和加工处理,是计算机程序加工的"原料"。     随着计算机应用领域的扩大,数据的范畴包括:  整数、实数、字...
  • xietangz
  • xietangz
  • 2005年01月19日 10:20
  • 3956

简单数据结构实现——二叉查找树

二叉查找树(Binary Search Tree)具有以下基本性质: 1.若它的左子树不空,则左子树上所有结点的值均小于它的根节点的值; 2.若它的右子树不空,则右子树上所有结点的值均大于...
  • hhhuuu2020
  • hhhuuu2020
  • 2016年09月20日 01:53
  • 155

算法和数据结构基础题集(持续更新中)

注意一题多解,举一反三,从普通算法到最优算法 1.判断一个字符串中的字符是否唯一(即没有重复),不能使用额外的数据结构(使用基本的数据结构) 2.反转一个字符串 3.去掉字符串中的重复字符,不能使用额...
  • hnuzengchao
  • hnuzengchao
  • 2014年11月04日 23:45
  • 934

【数据结构排序算法系列】数据结构八大排序算法

排序算法在计算机应用中随处可见,如Windows操作系统的文件管理中会自动对用户创建的文件按照一定的规则排序(这个规则用户可以自定义,默认按照文件名排序)因此熟练掌握各种排序算法是非常重要的,本博客将...
  • htq__
  • htq__
  • 2016年03月25日 22:36
  • 94397

数据结构(22)--动态查找之二叉排序树(二叉查找树)

参考书籍:数据结构(C语言版)严蔚敏吴伟民编著清华大学出版社 1.动态查找表 特点:表结构在查找过程中动态生成。 要求:对于给定值 key, 若表中存在其关键字等于 key的记录,则查找成功返回,并且...
  • u010366748
  • u010366748
  • 2016年03月07日 18:23
  • 947
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:数据结构基础 之 二叉搜索树的思想与实现
举报原因:
原因补充:

(最多只允许输入30个字)