数据结构 二叉排序树

二叉排序树(Binary Sort Tree),又称为二叉查找树。它或者是一棵空树,或者是具有下列性质的二叉树:
   如果它的左子树不空,则左子树上所有结点的值均小于它的根结点的值
   如果它的右子树不空,则右子树上所有结点的值均大于它的根结点的值。

 

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

#define TRUE        1
#define FALSE       0
#define OVERFLOW    -2

typedef int TElemType;

typedef struct BiTNode
{
	TElemType data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

/****************二叉排序树的查找*******************
参数说明:
    T     二叉排序树
	key   待查找的关键字
	f     指向T的双亲
	p     查找成功则指向该关键字的结点,返回TRUE,
	失败则指向查找路径的最后一个结点,返回FALSE
****************************************************/
int SearchBST(BiTree T, TElemType key, BiTree f, BiTree &p)
{
	if (!T)
	{//查找失败
		p = f;
		return FALSE;
	}
	else if(key == T->data)
	{//查找成功
		p = T;
		return TRUE;
	}
	else if (key < T->data)
	{//关键字小于当前结点的值,则查找其左子树
		SearchBST(T->lchild,key, T, p);
	}
	else
	{//关键字大于当前结点的值,则查找其右子树
		SearchBST(T->rchild,key, T, p);
	}
}

/****************二叉排序树的插入*******************
二叉排序树的中序遍历是一个有序序列
参数说明:
    T     二叉排序树
	key   待插入的关键字
	插入成功返回TRUE,失败返回FALSE
****************************************************/

int InsertBST(BiTree &T, TElemType key)
{
	BiTree p,s;
	if (!SearchBST(T,key,NULL,p))
	{//如果该二叉排序树没有该关键字则插入
		s = (BiTree)malloc(sizeof(BiTNode));
		if (!s)
		{
			exit(OVERFLOW);
		}
		s->data = key;
		s->lchild = NULL;
		s->rchild = NULL;   //插入新的结点

		if (!p)
		{//如果当前是一棵空树
			T = s;   //插入s为新的根结点
		}
		else if (key < p->data)
		{//关键字小则为其左子树
			p->lchild = s;
		}
		else 
		{//关键字大则为其右子树
			p->rchild = s;
		}
		return TRUE;
	}
	else
	{//插入失败,即二叉树包含有该关键字的结点
		return FALSE;
	}
}

/****************二叉排序树的删除*******************
函数int Delete(BiTree &p);p是待删除的结点,并整理其左右子树
函数int DeleteBST(BiTree &T, int key)删除值为key的结点
****************************************************/

/*
int Delete(BiTree &p)
{
	BiTree q,s;
	if (p->rchild == NULL)
	{//如果右子树为空,则直接拼接左子树
		q = p;
		p = p->lchild;
		free(q);
	}
	else if (p->lchild == NULL)
	{//如果左子树为空,则直接拼接右子树
		q = p;
		p = p->rchild;
		free(q);
	}
	else
	{//左右子树均不为空的情况,找到其中序序列的直接前驱
		q = p;
		s = p->lchild;
		while (s->rchild)
		{//转左,然后向右到尽头(找待删结点的前驱)
			q = s;
			s = s->rchild;
		}
		p->data = s->data ;   //s指向被删结点的直接前驱
		if (q != p)
		{//重接q的右子树
			q->rchild = s->lchild ;
		}
		else
		{//重接q的左子树
			q->rchild = s->lchild ;
		}
		free(s);
	}

	return TRUE;
}
*/


int Delete(BiTree &p)
{
	BiTree q,s;
	if (p->rchild == NULL)
	{//如果右子树为空,则直接拼接左子树
		q = p;
		p = p->lchild;
		free(q);
	}
	else if (p->lchild == NULL)
	{//如果左子树为空,则直接拼接右子树
		q = p;
		p = p->rchild;
		free(q);
	}
	else
	{//左右子树均不为空的情况,找到其中序序列的直接前驱
		q = p;
		s = p->rchild;
		while (s->lchild)
		{//转左,然后向右到尽头(找待删结点的前驱)
			q = s;
			s = s->lchild;
		}
		p->data = s->data ;   //s指向被删结点的直接前驱
		if (q != p)
		{//重接q的左子树,不相等,则说明q->lchild = s;
			q->lchild = s->rchild ;
		}
		else
		{//重接q的右子树,相等,则说明s = q->rchild,即只有一个结点的时候;
			q->rchild = s->rchild ;
		}
		free(s);
	}

	return TRUE;
}

int DeleteBST(BiTree &T, int key)
{
	if (!T)
	{
		return FALSE;
	}
	else
	{
		if (key == T->data)
		{
			return Delete(T);
		}
		else if (key < T->data)
		{
			return DeleteBST(T->lchild, key);
		}
		else
		{
			return DeleteBST(T->rchild, key);
		}
	}
}

void InOrderTraverse(BiTree T)
{
	if (T == NULL)
	{
		return;
	}
	InOrderTraverse(T->lchild);//访问左子树
	printf("%d ",T->data);//访问根结点
	InOrderTraverse(T->rchild);//访问右子树
}


int main()
{
	int i,n;
	int a[] = {62,88,58,47,35,73,51,99,37,93,29,37,36,49,56,48,50};
	BiTree T = NULL,p;
	for (i=0; i<sizeof(a) / sizeof(a[0]); i++)
	{
		InsertBST(T,a[i]);
	}
	printf("该二叉排序树的中序遍历:");
	InOrderTraverse(T);
	printf("\n");
	printf("请输入您要查找的关键字:");
	scanf("%d",&n);
	if (SearchBST(T,n,NULL,p))
	{
		printf("查找成功!\n");
	}
	else
	{
		printf("查找失败,待查序列中不包含该关键字\n");
	}
	printf("请输入您要插入的关键字:");
	scanf("%d",&n);
	InsertBST(T,n);
	printf("插入关键字 %d 后的二叉树的中序遍历:",n);
	InOrderTraverse(T);
	printf("\n");
	printf("请输入您要删除的关键字:");
	scanf("%d",&n);
	if (DeleteBST(T,n))
	{
		printf("删除关键字 %d 后的二叉树的中序遍历:",n);
		InOrderTraverse(T);
		printf("\n");
	}
	else
	{
		printf("二叉树不包含关键字 %d\n!",n);
	}

	return 0;
}


 

二叉排序树,也称为二叉搜索树(Binary Search Tree,简称BST),是一种特殊的二叉树结构,它具有以下性质: 1. 对于二叉排序树的任意一个非叶子节点,其左子树的所有节点的值都小于该节点的值,右子树的所有节点的值都大于该节点的值。 2. 对于二叉排序树的任意一个节点,其左子树和右子树都是二叉排序树。 下面是一个示例代码,演示了如何构建一个二叉排序树,并进行插入和查找操作: ```python class TreeNode: def __init__(self, val): self.val = val self.left = None self.right = None def insert(root, val): if root is None: return TreeNode(val) if val < root.val: root.left = insert(root.left, val) else: root.right = insert(root.right, val) return root def search(root, val): if root is None or root.val == val: return root if val < root.val: return search(root.left, val) else: return search(root.right, val) # 构建二叉排序树 root = None values = [5, 3, 8, 2, 4, 7, 9] for val in values: root = insert(root, val) # 查找节点 target = 4 result = search(root, target) if result: print("找到了节点", target) else: print("未找到节点", target) ``` 这段代码首先定义了一个`TreeNode`类,表示二叉排序树的节点。然后定义了`insert`函数,用于向二叉排序树中插入节点。最后定义了`search`函数,用于在二叉排序树中查找指定的节点。通过构建二叉排序树并进行查找操作,可以实现对数据的快速插入和查找。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值