二叉查找树的非递归实现

概述

本文是在学习数据结构时有感而发
二叉搜索树的递归实现性能比较差,所以除了函数DestroyBST()以外均采用循环而非递归实现
作者刚刚步入计算机行业,难免问题众多,欢迎各位大佬斧正

头文件BinarySearchTree.h

包含插入,查找,删除等操作
BinarySearchTree.h

#pragma once
#include<stdlib.h>
#include<stdbool.h>
#define ElementType int

//单向二叉查找树
struct BinarySearchTree
{
	struct BinarySearchTree* leftChild;
	ElementType element;
	struct BinarySearchTree* rightChild;

};

typedef struct BinarySearchTree BST_node;//BST即首字母的组合
typedef struct BinarySearchTree* ptrBST_RootNode;
typedef ptrBST_RootNode Position; 

//为树创建根节点
ptrBST_RootNode CreateBinarySearchTree()
{
	return (ptrBST_RootNode)calloc(1, sizeof(BST_node));
}

//将树销毁
ptrBST_RootNode DestoryBST(ptrBST_RootNode tree)
{
	if (tree)
	{
		DestoryBST(tree->leftChild);
		DestoryBST(tree->rightChild);
		
		free(tree);
	}
	
	return NULL;
}

//查找树的最小值
Position FindMin(ptrBST_RootNode tree)
{
	Position min = tree;
	
	while (min->leftChild)
	{
		min = min->leftChild;
	}

	return min;
}

//查找树的最大值
Position FindMax(ptrBST_RootNode tree)
{
	if (!tree)
	{
		return NULL;
	}
	else
	{
		Position max = tree;

		while (max->rightChild)
		{
			max = max->rightChild;
		}
	
		return max;
	}
}

//二叉搜索树的插入
ptrBST_RootNode InsertBST(ElementType element, ptrBST_RootNode tree)
{
	if (!tree)//检测是否为空树
	{
		tree = (ptrBST_RootNode)calloc(1, sizeof(BST_node));
		if (tree)
		{
			tree->element = element;
		}
		else
			return NULL;
	}
	else
	{
		Position pointer = tree;

		while (true)
		{
			if (pointer->element > element)//向左子树推进
			{
				if (!pointer->leftChild)
				{
					pointer->leftChild = (Position)calloc(1, sizeof(BST_node));
					
					if (pointer->leftChild)
					{
						pointer->leftChild->element = element;
						
						break;
					}
					else
					{
						return NULL;
					}
				}
				else
				{
					pointer = pointer->leftChild;
				}
			}
			if (pointer ->element <element)//向右子树推进
			{
				if (!pointer->rightChild)
				{
					pointer->rightChild = (Position)calloc(1, sizeof(BST_node));
					
					if (pointer->rightChild)
					{
						pointer->rightChild->element = element;
						
						break;
					}
					else
					{
						return NULL;
					}
				}
				else
				{
					pointer = pointer->rightChild;
				}
			}
			if (pointer->element == element)//此节点已存在于树中,无需插入
			{
				break;
			}
		}
	}

	return tree;
} 

//查找的基础函数
Position PositionIsEmpty(ptrBST_RootNode tree, ElementType element)
{
	if (tree)//当tree所指的节点不为null时,返回true,原函数继续向下寻找
	{
		if (element > tree->element)
		{
			return tree->rightChild;
		}
		else
		{
			return tree->leftChild;//注意,这里指针tree改变了原函数中sign所指向的节点
		}
	}
	else//当tree所指的节点为null时,创建一个新的节点,然后返回false,将原函数跳出循环
	{
		tree = InsertBST(element, tree);//注意,这里指针tree改变了原函数中sign所指向的节点
		
		return tree;
	}
}

//查找操作
Position Find_BSTnode(const ptrBST_RootNode const tree, ElementType element)
{
	/*递归实现
	Position sign = NULL;

	if (tree->element == element)
	{
		sign = tree;
		return sign;
	}
	if (tree->element > element )
	{
		sign = Find_BSTnode(tree->rightChild, element);
	}
	if (tree->element < element)
	{
		sign = Find_BSTnode(tree->leftChild, element);
	}

	return sign;*/

	//循环实现
	Position sign = tree;

	while (true)
	{
		if (sign->element == element)
		{
			break;
		}
		if (sign->element > element)
		{
			sign = PositionIsEmpty(sign, element);
			continue;
		}
		if (sign->element < element)
		{
			sign = PositionIsEmpty(sign, element);
			continue;
		}
	}

	return sign;
}
 
//查找目标节点的父节点
Position Find_BSTnodeFather(const ptrBST_RootNode const tree, ElementType element)
{
	Position sign = tree;
	
	if (sign->element == element)//检测根节点
	{
		return NULL;
	}
	
	while (true)
	{
		if (sign->leftChild)//先判断sign的左右孩子是否存在再判断与element的关系
		{
			if (sign->leftChild->element == element)
				break;
		}
		if (sign->rightChild)
		{
			if (sign->rightChild->element == element)
				break;
		}
		
		if (sign->element > element)//进入左子树
		{
			sign = PositionIsEmpty(sign, element);//sign指向下一个节点
			continue;
		}
		if (sign->element < element)//进入右子树
		{
			sign = PositionIsEmpty(sign, element);
			continue;
		}
	}

	return sign;
}

//二叉搜索树的删除操作
Position Delete_BSTnode_element(ptrBST_RootNode tree, ElementType element)
{
	Position pointer = Find_BSTnode(tree, element);//查找要删除的目标节点的位置
	Position pointerfather = Find_BSTnodeFather(tree, element);//查找目标节点的父节点

	if (pointerfather)//当pointerfather不为空,即pointer不是此树的根节点时
	{
		Position left = pointer->leftChild;
		Position right = pointer->rightChild;

		//若目标节点为父节点的右孩子,则删除后,父节点的右孩子指向目标节点的左子树
		//目标节点的左子树的最大节点的右孩子指向目标节点的右子树
		if (pointer->element > pointerfather->element)
		{
			Position left_max = FindMax(pointer->leftChild);

			if (left_max)
			{
				pointerfather->rightChild = pointer->leftChild;
				left_max->rightChild = right;
			}
			else
			{
				pointerfather->rightChild = pointer->rightChild;
			}

		}
		//若目标节点为父节点的左孩子,则删除后,父节点的左孩子指向目标节点的右子树
		//目标节点的右子树的最小节点的左孩子指向目标节点的左子树
		else
		{
			Position right_min = FindMin(pointer->rightChild);
			if (right_min)
			{
				pointerfather->leftChild = pointer->rightChild;
				right_min->leftChild = pointer->leftChild;
			}
			else
			{
				pointerfather->leftChild = pointer->leftChild;
			}
		}

		free(pointer);//销毁节点
	
		return tree;
	}
	else//当pointer是树的根节点时
	{
		Position right_min = FindMin(pointer->rightChild);
		Position left = pointer->leftChild;

		if (right_min)
		{
			right_min->leftChild = pointer->leftChild;//将左子树接入right_min的左孩子
		}
		
		free(pointer);
		return left;
	}
}

测试函数

test.c

#include<stdio.h>
#include"BinarySearchTree.h"

int main()
{
	ptrBST_RootNode MyFirstBST = NULL;

//	MyFirstBST = CreateBinarySearchTree();
	
	MyFirstBST = InsertBST(5, MyFirstBST);
	InsertBST(7, MyFirstBST);
	InsertBST(3, MyFirstBST);
	InsertBST(4, MyFirstBST);
	InsertBST(9, MyFirstBST);
	InsertBST(8, MyFirstBST);
	InsertBST(6, MyFirstBST);
	InsertBST(1, MyFirstBST);
	InsertBST(10, MyFirstBST);
	InsertBST(2, MyFirstBST);
	
	Position place = InsertBST(2, MyFirstBST);
	printf("测试插入重复元素:%p   %d\n", place, place->element);

	printf("此树的最小值为:%d\n", FindMin(MyFirstBST)->element);
	printf("此树的最大值为:%d\n", FindMax(MyFirstBST)->element);

	place = Find_BSTnode(MyFirstBST, 2);
	printf("查找操作测试:\n元素2的位置为:%p   %d\n", place, place->element);
	place = Find_BSTnodeFather(MyFirstBST, 2);
	printf("元素2的父节点位置为:%p   %d\n", place, place->element);

	printf("删除操作测试:\n");
	ptrBST_RootNode new = Delete_BSTnode_element(MyFirstBST, 2);
	printf("删除元素2后根节点的地址为:%p   %d\n", new, new->element);

	DestoryBST(MyFirstBST);
//	printf("\n%p\n", MyFirstBST);

	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值