原创作品,出自 “晓风残月xj” 博客,欢迎转载,转载时请务必注明出处(http://blog.youkuaiyun.com/xiaofengcanyuexj)。
由于各种原因,可能存在诸多不足,欢迎斧正!
近来开始重新读写二叉查找树及其变种(平衡二叉树、红黑树等),整理读书笔记写成博客与大家分享,如有错误或不妥还请斧正!
二叉查找树是这样的一棵树:
(1)、空树是一颗二叉查找树;
(2)、若左子树不为空,则左子树中的全部元素均小于该节点元素;
(3)、若右子树不为空,则右子树中的全部元素均不小于该节点元素;
(4)、若左右子树非空,则左右子树也是一颗二叉查找树。
二叉查找树的基本操作都很简单,在此不做说明,贴上代码。二叉查找树的基本操作(查找、插入、删除)平均时间复杂度均为O(log(N));但是最坏情况下的时间复杂度为O(N),即所有节点只有相同端的分支。此时必须在改变二叉树结构的同时进行调整,于是红黑树、AVL、Treap、伸展树等等诞生了,后面我将谈谈我对这些数据结构的认识及代码实现。
//BinarySearchTreeNode.h头文件
#include<iostream>
using namespace std;
struct BinarySearchTreeNode
{
int key;
BinarySearchTreeNode *leftChild;
BinarySearchTreeNode *rightChild;
BinarySearchTreeNode(int tempKey)
{
key=tempKey;
leftChild=NULL;
rightChild=NULL;
}
};
//BinarySearchTree.cpp
#include<iostream>
#include"BinarySearchTreeNode.h"
using namespace std;
class BinarySearchTree
{
private:
BinarySearchTreeNode *Root;
public:
BinarySearchTree();
BinarySearchTreeNode *GetRoot();
BinarySearchTreeNode *FindBST(int );
void UpdataBSTNode(int,int);
void InsertBSTNode(int);
bool DeleteBSTNode(int);
void DeleteNoOrOneChildBSTNode(BinarySearchTreeNode *,BinarySearchTreeNode *);
void PreOrderBSTPrint(BinarySearchTreeNode *);
void InOrderBSTPrint(BinarySearchTreeNode *);
void SufOrderBSTPrint(BinarySearchTreeNode *);
void RotateBSTPrint(BinarySearchTreeNode *,int);
};
BinarySearchTree::BinarySearchTree()
{
Root=NULL;
}
/**********************************************************
*参数:无
*返回值:空
*功能:返回二叉查找树根节点
************************************************************/
BinarySearchTreeNode *BinarySearchTree::GetRoot()
{
return this->Root;
}
/**********************************************************
*参数:待查找值
*返回值:若找到则返回所在节点,否则返回NULL
*功能:插入新结点
************************************************************/
BinarySearchTreeNode *BinarySearchTree::FindBST(int tempKey)
{
BinarySearchTreeNode *cur=this->Root;
while(cur!=NULL)
{
if(cur->key==tempKey)
break;
else if(cur->key>tempKey)
cur=cur->leftChild;
else cur=cur->rightChild;
}
return cur;
}
/**********************************************************
*参数:待插入值
*返回值:空
*功能:插入新结点
************************************************************/
void BinarySearchTree::InsertBSTNode(int tempKey)
{
BinarySearchTreeNode *pre=NULL,*cur=this->Root;
while(cur!=NULL)
{
pre=cur;
if(cur->key>tempKey)//tempKey插到左子树
cur=cur->leftChild;
else cur=cur->rightChild;//插到左子树
}
BinarySearchTreeNode *tempNode=new BinarySearchTreeNode(tempKey);
if(pre==NULL)//若插入的为根节点
{
this->Root=tempNode;
}
else if(pre->key>tempNode->key)
pre->leftChild=tempNode;
else pre->rightChild=tempNode;
}
/**********************************************************
*参数:待修改数值oldKey,修改后的数值newKey
*返回值:空
*功能:更新节点元素
************************************************************/
void BinarySearchTree::UpdataBSTNode(int oldKey,int newKey)
{
DeleteBSTNode(oldKey);
InsertBSTNode(newKey);
}
/**********************************************************
*参数:pre待删除节点的父节点,cur待删除节点
*返回值:空
*功能:删除左右孩子有为空的情况
************************************************************/
void BinarySearchTree::DeleteNoOrOneChildBSTNode(BinarySearchTreeNode *pre,BinarySearchTreeNode *cur)
{
if(NULL==cur->leftChild&&NULL==cur->rightChild)//左右孩子为空
{
if(NULL==pre)
Root=NULL;
else if(pre->leftChild==cur)
pre->leftChild=NULL;
else pre->rightChild=NULL;
delete cur;
}
else if(cur->rightChild!=NULL)//若右子树不为空
{
if(NULL==pre)
Root=cur->rightChild;
else if(pre->leftChild==cur)
pre->leftChild=cur->rightChild;
else
pre->rightChild=cur->rightChild;
delete cur;
}
else if(cur->leftChild!=NULL)//若左子树不为空
{
if(NULL==pre)
Root=cur->leftChild;
else if(pre->leftChild==cur)
pre->leftChild=cur->leftChild;
else
pre->rightChild=cur->leftChild;
delete cur;
}
}
/**********************************************************
*参数:待删除节点元素
*返回值:空
*功能:删除元素主函数
************************************************************/
bool BinarySearchTree::DeleteBSTNode(int tempKey)
{
BinarySearchTreeNode *pre=NULL,*cur=Root;
while(cur!=NULL)//寻找待删除元素
{
if(cur->key==tempKey)
break;
else
{
pre=cur;
if(cur->key>tempKey)
cur=cur->leftChild;
else cur=cur->rightChild;
}
}
if(NULL==cur)return false;
if(NULL==cur->leftChild||NULL==cur->rightChild)
DeleteNoOrOneChildBSTNode(pre,cur);
else //左右子树都不为空
{
BinarySearchTreeNode *rPre=cur,*rCur=cur->rightChild;//找到右子树最小元素
while(rCur->leftChild!=NULL)
{
rPre=rCur;
rCur=rCur->leftChild;
}
cur->key=rCur->key;
DeleteNoOrOneChildBSTNode(rPre,rCur);
}
}
/**********************************************************
*参数:当前子树根节点
*返回值:空
*功能:前序遍历二叉查找树
************************************************************/
void BinarySearchTree::PreOrderBSTPrint(BinarySearchTreeNode *tempRoot)
{
if(NULL==tempRoot)
return ;
cout<<tempRoot->key<<" ";
PreOrderBSTPrint(tempRoot->leftChild);
PreOrderBSTPrint(tempRoot->rightChild);
}
/**********************************************************
*参数:当前子树根节点
*返回值:空
*功能:中序遍历二叉查找树
************************************************************/
void BinarySearchTree::InOrderBSTPrint(BinarySearchTreeNode *tempRoot)
{
if(NULL==tempRoot)
return ;
InOrderBSTPrint(tempRoot->leftChild);
cout<<tempRoot->key<<" ";
InOrderBSTPrint(tempRoot->rightChild);
}
/**********************************************************
*参数:当前子树根节点
*返回值:空
*功能:后序遍历二叉查找树树
************************************************************/
void BinarySearchTree::SufOrderBSTPrint(BinarySearchTreeNode *tempRoot)
{
if(NULL==tempRoot)
return ;
SufOrderBSTPrint(tempRoot->leftChild);
SufOrderBSTPrint(tempRoot->rightChild);
cout<<tempRoot->key<<" ";
}
/**********************************************************
*参数:当前子树根节点,缩进列数
*返回值:空
*功能:翻转打印二叉查找树
************************************************************/
void BinarySearchTree::RotateBSTPrint(BinarySearchTreeNode *tempRoot,int tempColumn)
{
if(NULL==tempRoot)
return ;
RotateBSTPrint(tempRoot->leftChild,tempColumn+1);
for(int i=0;i<tempColumn;i++)
cout<<" ";
cout<<"---"<<tempRoot->key<<endl;
RotateBSTPrint(tempRoot->rightChild,tempColumn+1);
}
int main()
{
int val;
while(true)
{
BinarySearchTree myBinarySearchTree;
while(cin>>val)
{
if(val==0)break;
myBinarySearchTree.InsertBSTNode(val);
}
cout<<endl<<"*****************************"<<endl;
myBinarySearchTree.PreOrderBSTPrint(myBinarySearchTree.GetRoot());
cout<<endl<<"============================="<<endl;
myBinarySearchTree.InOrderBSTPrint(myBinarySearchTree.GetRoot());
cout<<endl<<"============================="<<endl;
myBinarySearchTree.SufOrderBSTPrint(myBinarySearchTree.GetRoot());
cout<<endl<<"============================="<<endl;
myBinarySearchTree.RotateBSTPrint(myBinarySearchTree.GetRoot(),0);
cout<<endl<<"*****************************"<<endl;
while(cin>>val)
{
if(!val)break;
myBinarySearchTree.DeleteBSTNode(val);
cout<<endl<<"*****************************"<<endl;
myBinarySearchTree.PreOrderBSTPrint(myBinarySearchTree.GetRoot());
cout<<endl<<"============================="<<endl;
myBinarySearchTree.InOrderBSTPrint(myBinarySearchTree.GetRoot());
cout<<endl<<"============================="<<endl;
myBinarySearchTree.SufOrderBSTPrint(myBinarySearchTree.GetRoot());
cout<<endl<<"============================="<<endl;
myBinarySearchTree.RotateBSTPrint(myBinarySearchTree.GetRoot(),0);
cout<<endl<<"*****************************"<<endl;
}
}
system("pause");
return 0;
}