二叉排序樹的插入、查找和刪除

#include < iostream >
#include
< iomanip >
#include
< cmath >
using namespace std;

#define EQ(a,b) ( (a) == (b) )
#define LT(a,b) ( (a) < (b) )
#define LQ(a,b) ( (a) <= (b) )
#define FALSE 0
#define TRUE 1

typedef
struct treenode
{
struct treenode * left;
int data;
struct treenode * right;
}BiTreenode,
* BiTreep;

// 初始化二叉樹
void init_tree(BiTreep & root)
{
root
= NULL;
cout
<< " 初始化成功! " << endl;
}


int SearchBST(BiTreep & rt, int key, BiTreep father, BiTreep & p)
{
// 在根指針T所指二叉排序樹中遞歸地查找其關鍵字等於key的數據元素,
// 若查找成功,則指針p指向該數據元素結點,並返回TRUE,
// 不然指針p指向查找路徑上訪問的最後一個節點,並返回FALSE,此時指針father指向T的雙親,p=father
// 其初始調用值爲NULL
if ( ! rt) // 查找不成功
{
p
= father;
return FALSE;
}
else if (EQ(key,rt -> data)) // 查找成功
{
p
= rt;
return TRUE;
}
else if (LT(key,rt -> data))
return SearchBST(rt -> left,key,rt,p); // 在左子樹中繼續查找
else
return SearchBST(rt -> right,key,rt,p); // 在右子樹中繼續查找
}
// 建立二叉樹
int InsertBST(BiTreep & rt, int key)
{
// 當二叉排序樹T中不存在關鍵字等於key的數據元素時,插入e並返回TRUE,不然返回FALSE
BiTreep p;
BiTreep s;
if ( ! SearchBST(rt,key,NULL,p))
{
s
= (BiTreep)malloc( sizeof (BiTreenode));
s
-> data = key;
s
-> left = s -> right = NULL;
if ( ! p)
rt
= s; // 被插的樹仍是空樹,被插節點*s作爲根節點
else if (LT(key,p -> data))
p
-> left = s; // 被插節點*s爲左孩子
else
p
-> right = s; // 被插節點*s爲右孩子
return TRUE;
}
else
return FALSE; // 樹中已有關鍵字相同的節點,再也不插入
} // InsertBST

// 中序遍歷二叉樹
void mid_order(BiTreep & rt)
{
if (rt != NULL)
{
mid_order(rt
-> left);
cout
<< rt -> data << " " ;
mid_order(rt
-> right);
}
}


// 查找二叉樹中是否存在某元素
int seach_tree(BiTreep & rt, int key)
{
if (rt == NULL)
return FALSE;
else
{
if (rt -> data == key)
return TRUE;
else if (LT(key,rt -> data))
return seach_tree(rt -> left,key);
else
return seach_tree(rt -> right,key);
}
}

int Delte(BiTreep & p)
{
if ( ! p -> right) // 右子樹空則只須要重接它的左子樹
{
BiTreep q
= p;
p
= p -> left;
free(q);
}
else if ( ! p -> left) // 左子樹空則只須要重接它的右子樹
{
BiTreep q
= p;
p
= p -> right;
free(q);
}
else // 左右子樹均不空
{
BiTreep father
= p;
BiTreep s
= p -> left; // 轉做,而後一直轉右到盡頭,就是要刪除節點的直接前驅
while (s -> right)
{
father
= s;
s
= s -> right;
}
p
-> data = s -> data; // 將直接前驅放置在要刪除的節點上,而後刪除直接前驅
if (p == father)
p
-> left = s -> left; // 若是直接前驅剛好是被刪除節點的左孩子,並且直接前驅的右子樹爲空,
// 這樣就把直接前驅的左子樹連到被刪節點的左孩子上。
else
father
-> right = s -> left ; // 若是不是上面的狀況,那麼此時的直接前驅必定是沒有右孩子的,
// 將其左孩子鏈接到它的雙親的右子樹上。
}
return TRUE;
}

// 刪除節點
int DeletBST(BiTreep & rt, int key)
{
// 若二叉排序樹T中存在關鍵字等於key的數據元素時,則刪除該數據元素節點,並返回TRUE
// 不然返回FALSE
if ( ! rt) // 不存在關鍵字等於key的數據元素
return FALSE;
else
{
if (EQ(key,rt -> data))
return Delte(rt); // 找到關鍵字等於key的數據元素,並刪除
else if ( LT(key,rt -> data) )
return DeletBST(rt -> left,key);
else
return DeletBST(rt -> right,key);
}
}
// DeletBST

int main()
{
BiTreep root;
init_tree(root);
// 初始化樹

// 插入法建立二叉排序樹
InsertBST(root, 45 );
InsertBST(root,
24 );
InsertBST(root,
53 );
InsertBST(root,
45 );
InsertBST(root,
12 );
InsertBST(root,
24 );
InsertBST(root,
90 );
InsertBST(root,
8 );
InsertBST(root,
30 );

// 中序遍歷二叉樹
cout << endl << " 中序遍歷序列是: " << endl;
mid_order(root);
cout
<< endl;

// 刪除節點
DeletBST(root, 12 );
DeletBST(root,
24 );
DeletBST(root,
90 );
mid_order(root);
cout
<< endl;

// 查找二叉樹中是否存在某元素
cout << " 輸入要查找的元素! " << endl;
int key;
cin
>> key;
if (seach_tree(root,key) == 1 )
cout
<< " yes! " << endl;
else
cout
<< " no! " << endl;

return 0 ;

} html

轉自http://www.cnblogs.com/gentleming/archive/2010/08/10/1796841.html node

相關文章
相關標籤/搜索