二叉搜索树的相关算法

二叉搜索树的算法主要包括:

  • 从二叉搜索树中查找元素,并返回其所在节点的地址
  • 查找二叉搜索树的最大元素
  • 查找二叉搜索树的最小元素
  • 二叉搜索树中插入元素
  • 二叉搜索树中删除元素

相关代码实现如下:

#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 《数据结构》(第二版) 陈越主编

原文地址:https://www.cnblogs.com/Manual-Linux/p/11338576.html