二叉查找树:ios
性质:对于树中的每一个节点X,它的左子树中全部关键字值小于X的关键字值,而它的右子树中全部关键字值大于X的关键字。注意,这意味着该树全部的元素能够用某种统一的方式排序。数据结构
如今给出一般对二叉查找树进行的操做的简要描述。(因为树的递归定义,一般是递归的编写这些例程)。测试
初始化:将第一个元素初始化为单节点树spa
typedef struct TNode { ElemType data; struct TNode *Lchild; struct TNode *Rchild; }TreeNode, *BinaryTree; TNode* MakeEmpty(BinaryTree T) { if(T != NULL) { MakeEmpty(T->Lchild); MakeEmpty(T->Rchild); free(T); } return NULL; }
2. Find操做:这一操做通常须要返回指向树T中具备关键字X的结点指针,若是这样的节点不存在则返回NULL。注意:测试的顺序,关键的问题是首先要对是否为空树进行测试,不然就可能在NULL指针上兜圈子。其他的状况应该使得最不可能的状况安排在最后进行。指针
TNode* Find(BinaryTree T, ElemType e) { if(T == NULL) return NULL; if( e < T->data) T->Lchild = Find(T->Lchild, e); else if(e > T->data) T->Rchild = Find(T->Rchild, e); else return T; }
3. Insert插入操做:进行插入操做的例程在概念上是很简单的,为了将X插入到树T中,能够像Find同样沿着树查找,若找到X,则什么也不作,若没有找到,就将X插入到遍历路径的最后一个点上。code
4. Delete删除操做:正如许多数据结构同样,最困难的操做是删除操做。一旦发现要删除的节点,要考虑一下几种状况:排序
1) 若是节点是一个叶子节点,则能够被当即删除。递归
2) 若是节点有一颗子树,则能够在其父节点调整指针绕过要删除的节点。ci
3) 若是节点有两棵子树,通常的删除策略是:用其右子树的最小节点代替该节点的数据并递归的删除那个节点。it
//二叉排序树的删除操做,删除节点以后获得的还是二叉排序树
TNode* DeleteBinaryTree(BinaryTree T, ElemType e)
{
TNode *position;
if(T == NULL)
{
cout << "error" << endl;
exit(0);
}
else if(T->data > e) //在树中查找要删除的元素
T->Lchild = DeleteBinaryTree(T->Lchild, e);
else if (T->data < e)
T->Rchild = DeleteBinaryTree(T->Rchild, e);
else //找到该元素
{
if(T->Lchild && T->Rchild) //若是要删除的元素有左右子树,则取右子树的最小值来替换要删除的节点
{
//position = FindMin(T->Rchild);
position = T->Rchild;
while(position != NULL)
{
position = position->Lchild;
}
}
else //删除的节点有一个孩子,或没有孩子
{
position = T;
if(T->Lchild == NULL)
T = T->Rchild;
else if(T->Rchild == NULL)
T = T->Rchild;
free(position);
}
}
return T;
}
//中序遍历
void InOrder(BinaryTree T)
{
if(T == NULL)
return;
if(T->Lchild != NULL)
InOrder(T->Lchild);
cout << T->data << " ";
if(T->Rchild != NULL)
InOrder(T->Rchild);
}
5. 二叉查找树的遍历:
1)前序遍历:
void PreorderTree(BinaryTree T) { if(T == NULL) return; cout << T->data << " "; if(T->lchild != NULL) PreorderTree(T->lchild); if(T->rchild != NULL) PreorderTree(T->rchild); }
2)中序遍历
//中序遍历 void InOrder(BinaryTree T) { if(T == NULL) return; if(T->Lchild != NULL) InOrder(T->Lchild); cout << T->data << " "; if(T->Rchild != NULL) InOrder(T->Rchild); }
3)后序遍历
void PostorderTree(BinaryTree T) { if(T == NULL) return; if(T->lchild != NULL) PostorderTree(T->lchild); if(T->rchild != NULL) PostorderTree(T->rchild); cout << T->data << " "; }
4)层次遍历
void LayerOrder(BinaryTree T) { queue<TNode *> Q; TNode *p; p = T; if(T == NULL) cout << "这是一棵空树!"<< endl; else { Q.push(T); while(p != NULL && Q.empty() == 0) { p = Q.front(); cout << p->data << " "; if(p->Lchild != NULL) Q.push(p->Lchild); if(p->Rchild != NULL) Q.push(p->Rchild); Q.pop(); if(Q.empty()) break; else p = Q.front(); } } }
整体代码:
#include<iostream>
using namespace std;
typedef int ElemType;
typedef struct TNode
{
ElemType data;
struct TNode *Lchild;
struct TNode *Rchild;
}TreeNode, *BinaryTree;
TNode* Find(BinaryTree T, ElemType e)
{
if(T == NULL)
return NULL;
if( e < T->data)
T->Lchild = Find(T->Lchild, e);
else if(e > T->data)
T->Rchild = Find(T->Rchild, e);
else
return T;
}
//经过插入建立二叉查找树
TNode* InsertBinaryTree(BinaryTree T, ElemType e)
{
if(T == NULL)
{
T = new TNode();
T->data = e;
T->Lchild = NULL;
T->Rchild = NULL;
}
else if(T->data > e)
{
T->Lchild = InsertBinaryTree(T->Lchild, e);
}
else if(T->data < e)
{
T->Rchild = InsertBinaryTree(T->Rchild, e);
}
else
{
cout << "该节点已存在" << endl;
return NULL;
}
return T;
}
//二叉排序树的删除操做,删除节点以后获得的还是二叉排序树
TNode* DeleteBinaryTree(BinaryTree T, ElemType e)
{
TNode *position;
if(T == NULL)
{
cout << "error" << endl;
exit(0);
}
else if(T->data > e) //在树中查找要删除的元素
T->Lchild = DeleteBinaryTree(T->Lchild, e);
else if (T->data < e)
T->Rchild = DeleteBinaryTree(T->Rchild, e);
else //找到该元素
{
if(T->Lchild && T->Rchild) //若是要删除的元素有左右子树,则取右子树的最小值来替换要删除的节点
{
//position = FindMin(T->Rchild);
position = T->Rchild;
while(position != NULL)
{
position = position->Lchild;
}
}
else //删除的节点有一个孩子,或没有孩子
{
position = T;
if(T->Lchild == NULL)
T = T->Rchild;
else if(T->Rchild == NULL)
T = T->Rchild;
free(position);
}
}
return T;
}
//中序遍历
void InOrder(BinaryTree T)
{
if(T == NULL)
return;
if(T->Lchild != NULL)
InOrder(T->Lchild);
cout << T->data << " ";
if(T->Rchild != NULL)
InOrder(T->Rchild);
}
int main()
{
TNode *T, *p;
p = NULL;
T = NULL;
int value;
//while(cin >> value)
//{
// T = InsertBinaryTree(T, value);
//}
for(int i = 1; i < 8; i++)
T = InsertBinaryTree(T, i);
cout << "输入要删除的节点: "; int dele; cin >> dele; cout << dele << endl; p = DeleteBinaryTree(T, dele); cout << "原来的元素序列:"; InOrder(T); cout << endl; cout << "删除后获得的序列:"; InOrder(p); system("pause"); return 0;}