c++类实现二叉查找树的抽象数据结构

本文深入探讨了二叉查找树的原理、操作方法及其在查找、插入、删除等操作上的实现细节,并通过代码实例展示了如何使用二叉查找树进行数据结构管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

说明:
1.0  二叉查找树可以看成是改进的二分查找法:  不需要依赖有序的数组
1.1 对于二叉查找树的前缀/后缀的查找,可能需要改变二叉树的类型,增加parent指针
1.2 对于插入/删除/查找(二分,最值之类)的操作,不需要考虑parent指针的问题
1.3  二叉查找树的平衡度可能很差,可能的解决办法:1.随机读取数组中的数据; 2.重新构建一颗AVL树
<pre name="code" class="cpp">#ifndef BINARYTREE_H
#define BINARYTREE_H
#include<iostream>
using namespace std;

typedef struct linknode {
	int data;
	struct linknode *left;
	struct linknode *right;
	struct linknode *parent;
}*ptree,tree;

class BINARYTREE{
public:
	BINARYTREE(){};
	~BINARYTREE(){};
	void insertTree(ptree _tree, ptree treeNode) const ;  //插入
	ptree createTree(int arr[],int size) ;
	void middleOrder(ptree _tree) const ;      
	void preOrder(ptree _tree) const;
	int BSTsearch(ptree _tree, int value);                //查找
	int BSTsearch2(ptree _tree, int value) ;
	ptree MAX(ptree _tree);                               //查找最大值
	ptree MIN(ptree _tree);
	int DELETE(ptree &valueNode);                         //删除节点
	int deleteNode(ptree &_tree, int value);
	
};

void BINARYTREE::insertTree(ptree _tree, ptree treeNode) const {
	if(_tree->data>=treeNode->data ) {
		if(NULL == _tree->left) {
			_tree->left=treeNode;
			treeNode->parent=_tree;
		}
		else {
			insertTree(_tree->left,treeNode);
		}
	}
	if(_tree->data<treeNode->data  ) {
		if(NULL==_tree->right) {
			_tree->right = treeNode;
			treeNode->parent = _tree;
		}
		else {
			insertTree(_tree->right,treeNode);
		}
	}
	
}

ptree BINARYTREE::createTree(int arr[], int size) {
	int i;
	ptree _tree = new tree;
	_tree->data=arr[0];
	_tree->left=NULL;
	_tree->right=NULL;
	_tree->parent=NULL;
	for( i=1; i<size; ++i ) {
		ptree treeTmp = new tree;
		treeTmp->data=arr[i];
		treeTmp->left=NULL;
		treeTmp->right=NULL;
		treeTmp->parent=NULL;
		insertTree(_tree,treeTmp);
	}
	return _tree;
}

void BINARYTREE::middleOrder(ptree _tree) const {
	if(NULL==_tree) {
		return;
	}
	middleOrder(_tree->left);
	cout<<_tree->data<<"  ";
	middleOrder(_tree->right);
}
void BINARYTREE::preOrder(ptree _tree) const {
	if(NULL==_tree) {
		return;
	}
	cout<<_tree->data<<"  ";
	preOrder(_tree->left);	
	preOrder(_tree->right);
}

int BINARYTREE::BSTsearch(ptree _tree, int value) {
	if(NULL==_tree) {
		return -1;
	}
	if(value>_tree->data) {
		return BSTsearch(_tree->right,value);
	}
	if(value<_tree->data) {
		return BSTsearch(_tree->left,value);
	}
	if(value==_tree->data) {
		return 1;
	}
	return -1;
}

int BINARYTREE::BSTsearch2(ptree _tree, int value) {
	if(NULL == _tree) {
		return -1;
	}
	while( NULL != _tree && value!=_tree->data) {
		_tree=(value<_tree->data?_tree->left:_tree->right);
	}
	if( NULL != _tree ) {
		return 1;
	}
	return -1;


}
ptree BINARYTREE::MAX(ptree _tree) {
	if(NULL == _tree ) {
		return NULL;
	}
	while( NULL != _tree->right ) {
		_tree=_tree->right;
	} 
	return _tree;
}

int BINARYTREE::DELETE(ptree &valueNode){
	//显然此时不存在节点是空的情况
	//1.是叶子节点,直接删除
	//2.只有左/右子树,删除蜕化成单链表的删除(特殊在于,知道该节点的地址,所以只用保留后继即可删除)
	//3.有左+右节点。问题转化成:
	//3.1寻找该节点的前继(该节点的左子树的最大值(左子树的最右边值),同时记录最大值的上一个状态);
	//3.2前继覆盖此节点(模拟删除);
	//3.3删除前继节点:2种情况,见代码
	if(NULL==valueNode->left) {
		ptree tmp = valueNode;
		valueNode=valueNode->right;
		delete tmp;
		tmp=NULL;
	}
	else if(NULL == valueNode->right) {
		ptree tmp= valueNode->left;
		delete valueNode;
		valueNode=tmp;
	}
	else if(NULL!=valueNode->left && NULL!=valueNode->left) {
		ptree parentNode=valueNode;
		ptree tmp = valueNode->left;
		while(tmp->right) {
			parentNode = tmp;
			tmp=tmp->right;
		}
		valueNode->data=tmp->data;
		if(parentNode!=valueNode) {
			parentNode->right=tmp->left;
		}
		else {
			valueNode->left=NULL;
		}
		delete tmp;
		tmp=NULL;
	}
	return 1;
}

int BINARYTREE::deleteNode(ptree &_tree, int value) {
	if(NULL==_tree) {
		return -1;
	}
	if(value == _tree->data) {
		return DELETE(_tree);
	}
	if(value<_tree->data) {
		return deleteNode(_tree->left,value);
	}
	if(value>_tree->data) {
		return deleteNode(_tree->right,value);
	}
	return 1;
}

#endif

#include"search.h"
#include"binaryTree.h"

int main() {
	int arr[]={1,2,3,4,5,6};
	int arr1[]={1,4,5,2,3,6};
	int size=sizeof(arr)/sizeof(int);
	int value=4;
	BINARYTREE * _binarytree = new BINARYTREE;
	
	ptree _tree = _binarytree->createTree(arr1,size);
	ptree maxNode = _binarytree->MAX(_tree);
	cout<<"max number in tree is : " <<maxNode->data<<endl;
	_binarytree->middleOrder(_tree);
	cout<<""<<endl;
	_binarytree->preOrder(_tree);
	cout<<""<<endl;
	_binarytree->deleteNode(_tree,4);
	_binarytree->middleOrder(_tree);
	cout<<""<<endl;
	//_binarytree->preOrder(_tree);

	SEARCH * _search = new SEARCH;
	if(1 == _search->binarySearch1(arr,size,value)) {
		cout<<value<<" in arrary!"<<endl;
	}
	if(1 == _search->binarySearch2(arr,0,size-1,value)) {
		cout<<value<<" in arrary!"<<endl;
	}

	if(1 == _binarytree->BSTsearch(_tree,value)) {
		cout<<value<<" in arrary!"<<endl;
	}
	else {
		cout<<value<<" not in arrary!"<<endl;
	}
    
	cout<<_binarytree->BSTsearch2(_tree,value)<<endl;
	
	system("pause");
	return 1;
<p>}</p><p>
</p><p>
</p><p>参考:http://songlee24.github.io/2015/01/13/binary-search-tree/参考:http://songlee24.github.io/2015/01/13/binary-search-tree/</p>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值