数据结构中二叉搜索树相关操作

 二叉搜索树,顾名思义,就是用来方便搜索的二叉树。  

其定义有以下要点 :   

                              一、由于是二叉树,采用链式结构。

                              二、二叉搜索树中存储的信息key不能重复。

                              三、二叉搜索树中的左子树全都比根结点小,右子树全都比根结点大。

有了上述定义,我们引入相关的操作,主要有插入,查找,删除。

 

#pragma once 
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
typedef struct STreeNode{
	int key;
	struct  STreeNode  * pLeft;
	struct  STreeNode  * pRight;
}STreeNode;

// key 不允许重复
// key 不允许更改
//结点左边的值都小于结点,结点右边的值都大于结点

// 是否找到 ,1 找到0 没找到

int Find(STreeNode *Node, int key)
{
	while (Node!=NULL)
	{
		if (Node->key == key){
			return 1;
		}
		if (key<Node->key ){
			Node = Node->pLeft;
		}
		if (key>Node->key){
			Node = Node->pRight;
		}
	}
	return 0;
}
STreeNode * CreadTree(int key){
	STreeNode *pNode = (STreeNode*)malloc(sizeof(STreeNode));
	pNode->key = key;
	pNode->pLeft = pNode->pRight = NULL;
	return pNode;
}
//插入,成功返回1,失败返回0
int Insert(STreeNode ** pNode, int key)
{
	STreeNode * Node = *pNode;
	STreeNode *parent = NULL;
	while (Node!=NULL)
	{
		if (Node->key == key){
			return 0;
		}
		else if (key>Node->key)
		{
			parent = Node;
			Node = Node->pRight;
		}
		else
		{
			parent = Node;
			Node = Node->pLeft;
		}
	}
	//遍历后的parent,若仍为空则是根结点,否则是最后一个叶子结点

	//表示pNode是一颗空树,直接插到根结点处
	if (parent == NULL){
		*pNode = CreadTree(key);
		return 1;
	}
	if (key < parent->key){
		parent->pLeft = CreadTree(key);
	}
	if (key>parent->key)
	{
		parent->pRight = CreadTree(key);
	}
	return 0;
}
//递归查找,成功返回1,失败返回-1
int FindR(STreeNode *Node, int key)
{
	if (Node->key==key)
	{
		return 1;
	}
	else if (key>Node->key)
	{
		return FindR(Node->pRight, key);
	}
	else
	{
		return FindR(Node->pLeft, key);
	}
	return 0;
}
//递归插入,成功返回1,失败返回-1
int InsertR(STreeNode *Node, int key)
{
	if (Node->key==key){
		return -1;
	}
	if (Node==NULL)
	{
		Node = CreadTree(key);
	}
	if (key<Node->key)
	{
		return InsertR(Node->pLeft, key);
	}
	else
	{
		return InsertR(Node->pRight, key);
	}
}
//递归删除,成功返回1.失败返回-1
int RemoveR(STreeNode **pRoot, int key)
{
	if (*pRoot == NULL){
		return -1;
	}
	if (key>(*pRoot)->key)
	{
		return RemoveR(&(*pRoot)->pRight, key);
	}
	if (key<(*pRoot)->key)
	{
		return RemoveR(&(*pRoot)->pLeft, key);
	}
	//没找到,则pRoot会为空,返回-1,表示失败

	//找到的话,就开始删除
	if ((*pRoot)->pLeft==NULL)
	{
		*pRoot = (*pRoot)->pRight;
		return 0;
	}
	if ((*pRoot)->pRight==NULL)
	{
		*pRoot = (*pRoot)->pLeft;
		return 0;
	}
	// 左右孩子都不为空, 替换删除法, 找左子树最大的

	STreeNode *swap = *pRoot;
	while (swap->pRight)//找到最后一个右子树,不能为空
	{
		swap = swap->pRight;
	}
	(*pRoot)->key = swap->key;
	return RemoveR(&((*pRoot)->pLeft), swap->key);
	return 0;
}
void Test()
{
	STreeNode *Node = NULL;
	Insert(&(Node), 3);
	Insert(&(Node), 5);
	Insert(&(Node), 9);
	Insert(&(Node), 3);
	Insert(&(Node), 4);
	Insert(&(Node), 1);
	RemoveR(&Node, 4);
}

 

关于二叉搜索树的主要操作如上所示,其中有递归的方式,但若二叉搜索树过大,则会调用大量栈帧,严重影响效率。

由于代码都为亲力亲为,所思所写。  若有问题,欢迎随时之处。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值