第四章——二叉搜索树
二叉树,虽然方便遍历和初始化存储,但是我们如果要插入呢,要查找里面的数据呢,怎么办,这就需要我们良好的设计这个树了,我们在插入的时候怎麽插,我们可以设计出这样一种树,它的左子树必须小于它的父结点,它的右子树必须大于它的父结点,就这样,我们就可以构造出一颗可以方便我们查找的树了,也可以方便我们插入,在我们插入时,我们只需要将插入的数据跟结点值做比较,如果比他小,就继续跟他的左子树比较,如果比他它大,就跟它的右子树比较,这样依次循环比较,直到这个结点为空,则插入进去(感觉我描述得不是很清楚,我们看代码吧):
#include <stdio.h>
#include <stdlib.h>
typedef struct TNode {
int data;
struct TNode *lchild;
struct TNode *rchild;
}TNode,*Tree;
void InitTree (Tree *T);//初始化树。
void Insert1 (int x, Tree *T);//插入一个数值进去。(我用的二重指针进行的插入)
void Pre (Tree T);//先序遍历树。
Tree Insert (int x, Tree T);//插入一个数值进去。
Tree Find (int x, Tree T);//查找x所在的结点。
Tree FindMin (Tree T);//查找最小值。
Tree FindMax (Tree T);//查找这颗树的最大值。
Tree Delete (int x, Tree T);//删除x所在的结点。
void Delete1 (int x, Tree *T);//删除x所在的结点。(我用的二重指针进行删除的)
/*插入和删除我都用了两种不同的形式,主要是想让自己加强对指针的运用。*/
int main (){//主函数是为用来验证我写的函数功能是否能实现。
Tree T;
InitTree (&T);
Insert1 (1,&T);
Insert1(2,&T);
T = Insert (3,T);
T = Insert (4,T);
Pre (T);
Tree temp;
temp = FindMin(T);
printf("min is %d\n",temp->data);
temp = FindMax(T);
printf("max is %d\n",temp->data);
temp = Find (2,T);
printf("2 is %d \n",temp->data);
T = Delete (2,T);
Delete1 (1,&T);
Pre (T);
return 0;
}
void Delete1 (int x, Tree *T)
{
Tree temp;
if (!(*T)) printf("find failure!\n");
else if (x < (*T)->data) {//如果x小于该结点的值,我们就将x和左子树进行删除操作。
Delete1(x,&(*T)->lchild);
}else if(x > (*T)->data) {//同上。
Delete1 (x,&(*T)->rchild);
}else if((*T)->rchild && (*T)->lchild) {//当该删除结点有左右子树时,我们就找到右子树的最小值来代替。
temp = FindMin ((*T)->rchild);
(*T)->data = temp->data;
Delete1 (temp->data,&(*T)->rchild);//然后我们删除游子的最小值。
}else {
temp = *T;
if (!(*T)->lchild) {//当左子不存在或者两个结点都不存在时。
(*T) = (*T)->rchild;//我们用右子树的结点代替。
}else if(!(*T)->rchild) {//同上。
(*T) = (*T)->lchild;
}
free (temp);
}
}
Tree Delete (int x, Tree T)
{
Tree temp;
if (!T) printf("find failure!\n");
else if (x < T->data) {
T->lchild = Delete (x, T->lchild);
}else if (x > T->data) {
T->rchild = Delete (x, T->rchild);
}else if (T->lchild && T->rchild) {
temp = FindMin(T->rchild);
T->data = temp->data;
T->rchild = Delete(temp->data,T->rchild);
}else {
temp = T;
if (!T->lchild) {
T = T->rchild;
}else if (!T->rchild) {
T = T->lchild;
}
}
return T;
}
Tree Find (int x, Tree T)
{
while (T) {
if (x < T->data) {
T = T->lchild;
}else if (x > T->data) {
T = T->rchild;
}else {
return T;
}
}
return NULL;
}
Tree FindMin (Tree T)
{
if (!T) return NULL;
while (T->lchild ) {
T = T->lchild;
}
return T;
}
Tree FindMax (Tree T)
{
if (!T ) return NULL;
else if (!T->rchild) return T;
else return FindMax(T->rchild);
}
void Pre (Tree T)
{
if (T) {
printf("%d ",T->data);
Pre (T->lchild);
Pre (T->rchild);
}
}
void InitTree (Tree *T)
{
*T = NULL;
}
Tree Insert (int x, Tree T)
{
if (!T) {//若该结点为空,我们就为该结点申请空间并赋值。
T = (Tree) malloc(sizeof(TNode));
T->data = x;
T->lchild = T->rchild = NULL;
}else if (x > T->data) {//若大于该结点,就插入它的右子树。
T->rchild = Insert (x,T->rchild);
}else if (x < T->data) {//若小于该结点,就插入它的左子树。
T->lchild = Insert (x,T->lchild);
}
return T;
}
void Insert1 (int x, Tree *T)
{
if (!(*T)) {
*T = (Tree) malloc (sizeof(TNode));
(*T)->data = x;
(*T)->lchild = (*T)->rchild = NULL;
}else if (x < (*T)->data) {
Insert1 (x,&(*T)->lchild);
}else if (x > (*T)->data) {
Insert1 (x,&(*T)->rchild);
}
}
以上就是二叉搜索树的基本操作,期待下一次!