查找

静态查找

不涉及插入和删除操作的查找
例:线性表 (顺序查找 折半查找)

动态查找

设计插入和删除操作的查找
例:树表(二叉排序树的查找技术)
静态查找和动态查找均适用 :散列表

二叉排序树

(也称为二叉查找树):或者是一颗空二叉树,或者是具有下列性质的二叉树;
(1):若它的左子树不空,则左子树上所有节点的值均小于根节点的值;
(2):若它的右子树不空,则右子树上所有节点的值均大于根节点的值;
(3):它的左右子树也都是二叉排序树
想要得到一个按关键码有序的序列只需要中序遍历这个二叉排序树

二叉排序树的插入:若二叉排序树为空树,则新插入的节点为新的根节点,否则,新插入的节点必为一个新的叶子节点,其插入位置由查找过程得到。

一个无序序列可以通过构造一颗二叉排序树编程一个有序序列;
每次插入新的节点都是二叉排序树上新的叶子节点;
找到插入位置后,不必移动其他节点,仅需修改某个结点的指针;
在左子树/右子树的查找过程与在整棵树上查找过程相同;
新插入的节点没有破坏原有节点之间的关系。

二叉排序树的查找
早二叉排序树中查找给定值K的过程:
(1)如果root是空树,则查找失败;
(2)若k = root->data,则查找成功;
(3)若k<root ->data,则查找成功,则在root的左子树上查找
(4)在root的右子树上查找
上述过程一直持续到k被找到或者待查找的子树为空,如果待查找的子树为NULL,则查找失败
二叉排序树查找效率在于只需查找两个子树之一

平均查找长度(ASL)体现了查找算法的关键码的比较次数,

为了提高二叉排序树的搜索效率,将二叉排序树进行平衡化变成二叉平衡树

二叉排序树的删除:在二叉排序树上删除某个结点后,仍然保持二叉排序树的特性。
(1):被删除的节点是叶子节点;
(2):被删除的节点只有左子树或者只有右子树
(3):被删除的节点既有左子树也有右子树
最简单的一种:
情况1:被删除的节点是叶子节点
操作:将双亲节点中相应指针域的值改为空
情况2:被删除的节点只有左子树或者只有右子树
操作:
将双亲节点的相应指针域的值指向被删除节点的左子树(或者右子树)。
情况3:被删除的节点既有左子树也有右子树
操作:以其左子树中最大的节点(或者右子树中最小值的节点)替代之,然后再删除该节点。
在这里插入图片描述

来看源码:

#define _CRT_SECURE_NO_WARNINGS 
#define DataType int
#include<iostream>
#define N 10

using namespace std;

struct BiNode
{
	DataType data;
	BiNode* lchild, *rchild;
};

class BiSortTree {
private:
	BiNode* root;
private:
	void insertBST(BiNode* &bt, DataType key);
	void release(BiNode* bt);
	bool deleteBST(BiNode* &bt, DataType key);
	void deleteNode(BiNode* &bt);
	BiNode *searchBST(BiNode *bt, DataType key);

public:
	BiSortTree(DataType array[], int arrayLength);
	~BiSortTree() { release(root); }
	BiNode* searchBST(int key)
	{
		searchBST(root, key);
	}
	bool deleteBST(int key)
	{
		return deleteBST(root, key);
	}
	void inOrder() {
		inOrder(root);
	}
	void inOrder(BiNode *bt);
	BiNode* getRoot()
	{
		return this->root;
	}

};

void BiSortTree::insertBST(BiNode* &bt, DataType key)
{
	if (bt == NULL)
	{
		bt = new BiNode;
		bt->data = key;
		bt->lchild = NULL;
		bt->rchild = NULL;
	}
	else
	{
		if (key < bt->data)
			insertBST(bt->lchild, key);
		else
			insertBST(bt->rchild, key);
	}

}
BiSortTree::BiSortTree(DataType array[], int arrayLength)
{
	root = NULL;
	for (int i = 0; i < arrayLength; ++i)
	{
		insertBST(root, array[i]);
	}
}
BiNode* BiSortTree::searchBST(BiNode *bt, DataType key)
{
	if (bt == NULL)
	{
		return NULL;
	}
	else
	{
		if (key == bt->data)
			return bt;
		else if (key < bt->data)
			return searchBST(bt->lchild,key);
		else
			return searchBST(bt->rchild, key);

	}

}
bool BiSortTree::deleteBST(BiNode* &bt, DataType key)
{
	if (bt == NULL)
		return false;
	else
	{
		if (bt->data == key)
		{
			deleteNode(bt);
		}
		else if (key < bt->data)
		{
			return deleteBST(bt->rchild, key);
		}
		else
		{
			return deleteBST(bt->rchild, key);
		}
		return true;
	}
}

void BiSortTree::deleteNode(BiNode* &bt)
{
	BiNode *p,*parent,*pre;
	if (bt->lchild == NULL && bt->rchild == NULL) //叶子节点
	{
		p = bt;
		bt = NULL; //预防野指针
		delete p;
	}
	else if (bt->rchild == NULL)
	{
		p = bt;
		bt = bt->lchild;
		delete p;
	}
	else if (bt->lchild == NULL)
	{
		p = bt;
		bt = bt->rchild;
		delete p;
	}
	else   //左右子树均不为空
	{
		parent = bt;
		pre = bt->lchild;
		while (pre->rchild) //转左,然后向右到尽头(找到右子树中最大节点)
		{
			parent = pre;
			pre = pre->rchild;
		}
		bt->data = pre->data;
		if (parent != bt)  //判断是否只有一层
		{
			parent->lchild = pre->lchild;
		}
		else
		{
			parent->lchild = pre->lchild;
		}
		delete pre;
	}
}


void BiSortTree::release(BiNode *bt)
{
	if (bt == NULL)
		return;
	else
	{ 
		release(bt->lchild);
		release(bt->rchild);
		free(bt);
	}
}

void BiSortTree::inOrder(BiNode *bt)
{
	if (bt == NULL)
		return;
	else
	{
		inOrder(bt->lchild);
		cout << bt->data << " ";
		inOrder(bt->rchild);
	}
}
int main()
{

	int arr[N];
	for (int i = 0;i < 10;++i)
	{
		arr[i]	= rand() % 10;
	}
	BiSortTree res(arr, N);
	res.inOrder(res.getRoot());
	system("pause");
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值