二叉查找樹: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;}