在尋找這一章,我認為靜態尋找都比較簡單,所以就跳過了,二叉排序樹以及與之相關的一些資料結構還是有一定意義的。二叉排序樹:左子樹小於根節點,右子樹大於根節點。這個原理很簡單,就上面幾行幾個字,實現起來代碼也很簡潔,使用遞迴調用。在節點刪除的時候,到時有不同的情況,需要注意一下。
(1)若待刪除節點是葉子節點,則之間刪除,修改下父節點的指標就可以了。
(2)若只有左子樹或右子樹,直接將其子樹接到待刪除節點的父節點後面就可以了。
(3)若既有左子樹又有右子樹的,相對就麻煩一些。其中有兩種方法:第一,將左子樹接到其父節點上,然後將其右子樹接到左子樹的最右端,這是因為右子樹的節點都是比左子樹大的,所以將右子樹接到左子樹最大的位置,也就是最右端,依次也可以將右子樹接到父節點上,然後將左子樹接到右子樹的最左端。
第二,不改變左子樹和右子樹,為了保持排序樹的特性,將左子樹最大值節點替換待刪除節點,或者是講右子樹最小值節點代替之。
#include <stdio.h>
#include <stdlib.h>
#include "Search.h"
//尋找二叉排序樹
//第一個參數:查詢節點
//第二個參數:尋找的索引值
// 第三個參數:尋找節點的父節點
//第四個參數:用於返回尋找到的節點
int SearchBST(const pNode T,const ElemType key,pNode f,pNode &p)
{
if(!T){ p = f;
return 0; } //節點不存在,返回最後一個節點,在資料插入其後
else if(key == T->data){p = T;
return true; } //該節點在排序樹中
else if(key > T->data)
return SearchBST(T->rchild,key,T,p); //向右子樹尋找
else return SearchBST(T->lchild,key,T,p); //向左子樹尋找
}
//排序樹中插入節點
//待插入節點的父節點,插入元素
int InsertBST(pNode T,const ElemType e)
{
pNode s;
s=(pNode)malloc(sizeof(tNode));
if(!s) return false;
s->data = e;
s->lchild = s->rchild = NULL; //到此構造節點結束
//這裡在調試的時候要考慮樹為空白時的插入
//所以在初始化頭結點的時候用255賦值給data
//左子樹作為第一個節點
if(e < T->data) T->lchild = s; //在此進行插入
else T->rchild = s;
return true;
}
//排序樹刪除一個節點
//在此用引用的好處就是可以改變傳遞進來指標的值
int DeleteBST(pNode &T,ElemType key)
{
if(!T)
return false; //節點不存在
else
{
if(key == T->data)
return Delete( T ); //刪除本節點
else if(key > T->data) return DeleteBST(T->rchild, key); //到右子樹遞迴
else return DeleteBST( T->lchild,key); //到左子樹遞迴
}
}
//進行刪除操作
int Delete(pNode & T)
{
pNode p;
if(!T->rchild) //右子樹有空,直接將左子樹接到上面
{
p = T;
T = T->lchild;
free(p);
}
else if(!T->lchild) //左子樹為空白。直接將右子樹接到上面
{
p = T;
T = T->rchild;
free(p);
}
else //左右子樹都不為空白
{
pNode s; //儲存左子樹的最大值節點
p = T; //儲存s的父節點
s = T->lchild;
while(s->rchild) //根據特性,最右的節點最大
{
p = s;
s= s->rchild;
}
T->data = s->data; //待刪除節點交換資訊,相當於兩節點置換
//當s的父節點就是待刪除節點時,說明s就是T的左孩子
// 此時修改的是T的左孩子
//否則修改s父節點的右孩子
if(p != T)
p->rchild = s->lchild;
else p->lchild = s->lchild;
free(s);
}
return true;
}
int main()
{
tNode head;
head.lchild = NULL; //樹的第一個節點
head.rchild = NULL;
head.data = 0xFF; //可用於統計元素個數,在實現時為了操作簡單,存放length-1;
while(1)
{
ElemType temp;
//pNode f = head.lchild;
pNode p = NULL;
printf("input the key:");
scanf("%d",&temp);
if(SearchBST(head.lchild,temp,&head,p))
{
printf("元素:%d存在樹中!\n",p->data);
}
else
{
InsertBST(p,temp);
head.data++;
printf("I insert the key!\n");
}
}
return 0;
}