二叉查找树c语言实现

二叉查找树描述

二叉查找树的性质:对于树中的每个结点X,它的左子树中所有关键字值小于X的关键值,而它的右子树中所有关键字大于X的关键值。由于树的递归定义,通常是递归的编写查找树的常用操作例程。对这些常用例程中,主要需要考虑的是插入和删除节点。下面将简要说明。(二叉查找树的平均深度是O(logN),所以一般不需要担心栈空间用尽。)

Insert:为了将X插入到树T中,可以像用Find那样沿着树查找。如果找到X,则什么也不用做。否则,将X插入到遍历的路径上的最后一点上。如下图所示,为了插入5,因而遍历该树,就好像在运行Find。在具有关键字4的节点处需要向右行进,但4的右子树不存在,因此5不在这棵树上,从而这个位置就是所要插入的位置。

Delete:一旦发现要删除的节点,考虑以下三种情况:如果该节点是一片树叶,那么它可以被立即删除;如果节点只有一个儿子,则该节点可以在其父节点调整指针绕过该节点后被删除,如下图:删除只有一个左孩子节点的元素:4。


复杂的情况是处理具有两个儿子的节点。一般的删除策略是用其右子树关键字最小的元素或左子树关键字最大的元素代替该节点的数据并递归的删除那个节点。因为右子树中最小节点不可能有左孩子(左子树的最大值节点则不可能有右孩子),所以第二次Delete变要容易一些。下图是一颗初始的二叉查找树即删除关键字为2的节点后的状态。

二叉查找树的具体代码实现

头文件:searchTree.h

typedef int ElementType;

#ifndef _SEARCH_TREE_
#define _SEARCH_TREE_

struct TreeNode;
typedef TreeNode *Position;
typedef TreeNode *SearchTree;

SearchTree MakeEmpty( SearchTree T );           //释放树中的所有元素
Position Find( ElementType X, SearchTree T );   
Position FindMin( SearchTree T );              //查找最小值
Position FindMax( SearchTree T );
SearchTree Insert( ElementType X, SearchTree T );
SearchTree Delete( ElementType X, SearchTree T );
ElementType Retrieve( Position P );          //提取该位置上关键字
void PrintTree( SearchTree T );              //先序输出

#endif

实现文件:SearchTree.c

#include "searchTree.h"
#include <stdio.h>
#include <stdlib.h>

struct TreeNode
{
	ElementType Element;
	Position Left;
	Position Right;
};

SearchTree MakeEmpty( SearchTree T )
{
	if (T != NULL)
	{
		MakeEmpty(T->Left);
		MakeEmpty(T->Right);
		free(T);
	}
	return NULL;
}

Position Find( ElementType X, SearchTree T )
{
	if (T == NULL)
		return NULL;
	if (T->Element < X)
		return Find(X, T->Right);
	else if(T->Element > X)
		return Find(X, T->Left);
	else 
		return T;
	//非递归实现
	/*while (T != NULL)
	{
		if (T->Element < X)
			T = T->Right;
		else if (T->Element > X)
			T = T->Left;
		else 
			return T;
	}
        return T;*/
 }

Position FindMin( SearchTree T )
{
	if (T == NULL)
		return NULL;
	else if (T->Left == NULL)
		return T;
	else 
		return FindMin(T->Left);
	//非递归实现
	/*Position P = T;
	while (P->Left != NULL)
	{
		P = P->Left;
	}
	return P;*/
}

Position FindMax( SearchTree T )
{
	if (T == NULL)
		return NULL;
	else if (T->Right == NULL)
		return T;
	else 
		return FindMax(T->Right);
	//非递归实现
	/*Position P = T;
	while (P->Right != NULL)
	{
		P = P->Right;
	}
	return P;*/
}

SearchTree Insert( ElementType X, SearchTree T )
{
	if (T == NULL)
	{	//最后该插入X的位置
		T = (Position)malloc(sizeof(struct TreeNode));
		if (T == NULL)
		{
			printf("Out of space!\n");
			return NULL;
		}
		T->Left = T->Right = NULL;
		T->Element = X;
	}
	else if (T->Element < X)
		T->Right = Insert(X, T->Right);
	else if (T->Element > X)
		T->Left = Insert(X, T->Left);
	return T;
}

SearchTree Delete( ElementType X, SearchTree T )
{
	Position TmpCell;
	if (T == NULL)
	        printf("Cannot find element %d\n", X);
	else
	{
		if (X < T->Element)   //在左子树中查找
			T->Left = Delete(X, T->Left);
		else if (X > T->Element)
			T->Right = Delete(X, T->Left);
		else
		{
			//找到值为X的节点,即此时的T,判断该节点的左右孩子是否都存在
			if (T->Left && T->Right)
			{
				TmpCell = FindMin(T->Right);    //找到右子树中的最小者
				T->Element = TmpCell->Element;
				T->Right = Delete(T->Element, T->Right);  //改为删除T右子树中最小者
			}
			else
			{
			        TmpCell = T;
			       if ( T->Left == NULL) 
					T = T->Right;  
			       else if ( T->Right == NULL )  
					T = T->Left; 

			        free(TmpCell);
			}
		}
		
	}
	return T;
} 

void PrintTree( SearchTree T )
{
	if (T != NULL)
	{
		printf("%5d\n", T->Element);
		PrintTree(T->Left);
		PrintTree(T->Right);
	}
}

ElementType Retrieve( Position P )
{
	return P->Element;
}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值