二叉搜索树的算法主要包括:
- 从二叉搜索树中查找元素,并返回其所在节点的地址
- 查找二叉搜索树的最大元素
- 查找二叉搜索树的最小元素
- 二叉搜索树中插入元素
- 二叉搜索树中删除元素
相关代码实现如下:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include"queue.h"
#define NoInfo 0 //用0表示没有节点
//作用:层序生成二叉树
struct TNode* CreatBinTree()
{
int Data;
struct QNode* Q = CreatQueue(10); //创建空队列
struct TNode* T;
struct TNode* BT;
//建立第一个节点,即根节点
scanf("%d", &Data);
if (Data != NoInfo)
{
//动态分配一个结点单元,并存入数据,同时将该结点地址放入队列
BT = (struct TNode *)malloc(sizeof(struct TNode));
BT->Data = Data;
BT->Left = NULL;
BT->Right = NULL;
AddQ(Q, BT);
}
else
{
return NULL;
}
while (!IsEmpty(Q))
{
T = DeleteQ(Q); //从队列中取出一节点地址
scanf("%d", &Data);
if (Data != NoInfo)
{
//动态分配一个结点单元,并存入数据,同时将该结点地址放入队列
T->Left = (struct TNode *)malloc(sizeof(struct TNode));
T->Left->Data = Data;
T->Left->Left = NULL;
T->Left->Right = NULL;
AddQ(Q, T->Left);
}
else
{
T->Left = NULL;
}
//读入右孩子的数据
scanf("%d", &Data);
if (Data != NoInfo)
{
//动态分配一个结点单元,并存入数据,同时将该结点地址放入队列
T->Right = (struct TNode *)malloc(sizeof(struct TNode));
T->Right->Data = Data;
T->Right->Left = NULL;
T->Right->Right = NULL;
AddQ(Q, T->Right);
}
else
{
T->Right = NULL;
}
} //end while (!IsEmpty(Q))
return BT;
}
//作用:在二叉搜索树中查找一个元素
//参数:待查找的元素
//返回值:返回其所在节点的位置
//思路:递归实现
struct TNode* Find(struct TNode* BST,int x)
{
if (BST == NULL)
{
return NULL;
}
if (x > BST->Data)
{
return Find(BST->Right,x); //在右子树中递归查找
}
else if(x < BST->Data)
{
return Find(BST->Left,x);
}
else
{
return BST;
}
}
//作用:在二叉搜索树中查找一个元素
//参数:待查找的元素
//返回值:返回其所在节点的位置
//思路:非递归实现
struct TNode* Find2(struct TNode* BST, int x)
{
while (BST)
{
if (BST == NULL)
{
return NULL;
}
if (x > BST->Data)
{
BST = BST->Right;
}
else if (x < BST->Data)
{
BST = BST->Left;
}
else
{
break;
}
}
return BST;
}
//作用:查找二叉搜索树中最大元素的位置
//思路:只要从根节点开始,当其不为空时,沿着右分支逐个判断各节点
// 的指针,直到遇到空指针为止,从右分支找到的是最大元素
struct TNode* FindMax(struct TNode* BST)
{
if (BST != NULL)
{
while (BST->Right)
{
BST = BST->Right;
}
}
return BST;
}
//作用:查找二叉搜索树中最小元素的位置
//思路:只要从根节点开始,当其不为空时,沿着右分支逐个判断各节点
// 的指针,直到遇到空指针为止,从左分支找到的是最大元素
struct TNode* FindMin(struct TNode* BST)
{
if (BST != NULL)
{
while (BST->Left)
{
BST = BST->Left;
}
}
return BST;
}
//作用:二叉搜索树中插入元素
struct TNode* Insert(struct TNode* BST,int x)
{
if (BST == NULL) //若原树为空,生成并返回一个结点的二叉搜索树
{
BST = (struct TNode*)malloc(sizeof(struct TNode));
BST->Data = x;
BST->Left = NULL;
BST->Right = NULL;
}
else //开始找要插入元素的位置
{
if (x < BST->Data)
{
BST->Left = Insert(BST->Left,x);
}
else if (x > BST->Data)
{
BST->Right = Insert(BST->Right, x);
}
}
return BST;
}
//作用:二叉树的递归中序遍历
void InorderTraversal(struct TNode* BT)
{
if (BT)
{
InorderTraversal(BT->Left);
printf("%d. ", BT->Data);
InorderTraversal(BT->Right);
}
}
//作用:二叉搜索树中删除元素
struct TNode* Delete(struct TNode* BST,int x)
{
struct TNode* Tmp;
if (BST == NULL)
{
printf("要删除的元素未找到.
");
}
else
{
if (x < BST->Data)
{
BST->Left = Delete(BST->Left, x); //从左子树递归删除
}
else if (x > BST->Data)
{
BST->Right = Delete(BST->Right, x); //从右子树递归删除
}
else //BST就是要删除的节点
{
//如果被删除的节点有左右两个节点
if (BST->Left && BST->Right)
{
Tmp = FindMin(BST->Right); //从右子树中找到最小的元素填充删除节点
BST->Data = Tmp->Data;
BST->Right = Delete(BST->Right,BST->Data);
}
else //被删除节点有一个或无子节点
{
Tmp = BST;
if (!BST->Left) //只有右孩子或无子节点
{
BST = BST->Right;
}
else
{
BST = BST->Left;
}
free(Tmp);
}
}
}
return BST;
}
int main()
{
struct TNode* BT = CreatBinTree();
struct TNode* BST = Find(BT, 50);
if (BST != NULL)
{
printf("查找到元素: %d.
", BST->Data);
}
else
{
printf("二叉搜索树中没有要查找的元素.
");
}
struct TNode* BST2 = Find2(BT, 41);
if (BST2 != NULL)
{
printf("查找到元素: %d.
", BST2->Data);
}
else
{
printf("二叉搜索树中没有要查找的元素.
");
}
struct TNode* BSTMAX = FindMax(BT);
if (BSTMAX != NULL)
{
printf("二叉搜索树中最大的元素是: %d.
", BSTMAX->Data);
}
struct TNode* BSTMIN = FindMin(BT);
if (BSTMIN != NULL)
{
printf("二叉搜索树中最小的元素是: %d.
", BSTMIN->Data);
}
Insert(BT,35);
InorderTraversal(BT);
Delete(BT,20);
InorderTraversal(BT);
system("pause");
return 0;
}
实现队列的头文件和.c文件
queue.h
#pragma once
//二叉树的创建需要队列
//该文件实现队列的一系列操作
#pragma once
#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
struct TNode
{
int Data; //节点的数据
struct TNode* Left; //指向左子树
struct TNode* Right; //指向右子树
};
typedef struct TNode* ElementType;
struct QNode
{
ElementType* Data; //存储元素的数组
int Front; //队列的头指针
int Rear; //队列的尾指针
int MaxSize; //队列的最大容量
};
struct QNode* CreatQueue(int MaxSize);
bool IsFull(struct QNode* Q);
bool AddQ(struct QNode* Q, ElementType x);
bool IsEmpty(struct QNode* Q);
ElementType DeleteQ(struct QNode* Q);
queue.c
#include<stdio.h>
#include"queue.h"
//作用:创建一个队列
//参数:队列的大小
struct QNode* CreatQueue(int MaxSize)
{
struct QNode* Q = (struct QNode *)malloc(sizeof(struct QNode));
Q->Data = (ElementType *)malloc(MaxSize * sizeof(int));
Q->Front = Q->Rear = 0;
Q->MaxSize = MaxSize;
return Q;
}
//作用:判断当前队列是否满
//参数:待判断的队列
bool IsFull(struct QNode* Q)
{
return ((Q->Rear + 1) % Q->MaxSize == Q->Front);
}
//作用:向队列中插入元素
//参数:struct QNode* Q 待插入的队列
// int x 待插入的元素
bool AddQ(struct QNode* Q, ElementType x)
{
if (IsFull(Q)) //判断队列是否为空
{
printf("队列满,不能再插入元素
");
return false;
}
else
{
Q->Rear = (Q->Rear + 1) % Q->MaxSize;
Q->Data[Q->Rear] = x;
return true;
}
}
//作用:判断队列是否为空
//参数:
//返回值: true 空
// false 非空
bool IsEmpty(struct QNode* Q)
{
return (Q->Front == Q->Rear);
}
//作用:
//参数:
ElementType DeleteQ(struct QNode* Q)
{
if (IsEmpty(Q))
{
printf("队列为空
");
return NULL;
}
else
{
Q->Front = (Q->Front + 1) % Q->MaxSize;
return Q->Data[Q->Front];
}
}
参考资料:
1 《数据结构》(第二版) 陈越主编