BinarySearchTree(2)二叉查找树链式非递归实现

binary_search_tree.h


/*-----------------------------------------------   
Created By EverSteins   
Email:EverSteins@gmail.com  
转载请注明出处  
------------------------------------------------*/ 

#ifndef BINARY_SEARCH_TREE_H
#define BINARY_SEARCH_TREE_H

typedef int ElemType;

class BinarySearchTree
{
public:
	BinarySearchTree():root_(NULL){}
	~BinarySearchTree();

	bool Insert(const ElemType& entry);
	bool Remove(const ElemType& entry);
	bool Search(const ElemType& target) const;
	
	void InOrderTraverse() const;
	bool IsEmpty() const;
	

private:
	struct TreeNode
	{
		TreeNode(const ElemType& entry,TreeNode *left,TreeNode *right):entry_(entry),left_(left),right_(right){}
		ElemType entry_;
		TreeNode *left_;
		TreeNode *right_;
	};

	void RemoveAllNodes(TreeNode *node);
	bool Search(const ElemType& target,TreeNode **&node_ptr) const;
	void InOrderTraverseRecursive(TreeNode *node) const;
	

	TreeNode *root_;


#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
  TypeName(const TypeName&);               \
  void operator=(const TypeName&)

	DISALLOW_COPY_AND_ASSIGN(BinarySearchTree);

#undef DISALLOW_COPY_AND_ASSIGN
};

#endif

binary_search_tree.cc


/*-----------------------------------------------   
Created By EverSteins   
Email:EverSteins@gmail.com  
转载请注明出处  
------------------------------------------------*/ 

#include "stdafx.h"
#include <iostream>
#include "utility.h"
#include "binary_search_tree.h"
using namespace std;

BinarySearchTree::~BinarySearchTree()
{
	RemoveAllNodes(root_);
}

void BinarySearchTree::RemoveAllNodes(TreeNode *node)
{
	//采用递归后续遍历删除所有结点
	if (node == NULL)
		return;

	RemoveAllNodes(node->left_);
	RemoveAllNodes(node->right_);
	delete node;
}

bool BinarySearchTree::Insert(const ElemType& entry)
{
	TreeNode **node_ptr = &root_;
	bool isFind = Search(entry,node_ptr);
	if (!isFind)   //不存在相同元素则插入
	{
		*node_ptr = new TreeNode(entry,NULL,NULL);
		return true;
	}
	return false;  //不允许插入相同元素
}

bool BinarySearchTree::Remove(const ElemType& entry)
{
	TreeNode **parent_node_ptr = &root_;
	bool isFind = Search(entry,parent_node_ptr);
	if (isFind)
	{
		TreeNode *remove_node = *parent_node_ptr;           //remove_node为待删结点
		TreeNode *left_tree_node = remove_node->left_;      //left_tree_node为待删结点的左子树结点
		TreeNode *right_tree_node = remove_node->right_;    //right_tree_node为待删结点的右子树结点
		if (right_tree_node == NULL)                        //remove_node右子树为空只需重接remove_node的左子树
		{
			*parent_node_ptr =  left_tree_node;
			delete remove_node;
		}
		else if (left_tree_node == NULL)                    //remove_node左子树为空只需重接remove_node的右子树
		{
			*parent_node_ptr =  right_tree_node;
			delete remove_node;
		}
		else                                                //remove_node左右子树均不为空
		{
			TreeNode *left_max_parent_node = remove_node;   //left_max_parent_node为左子树最大结点的父结点
			TreeNode *left_max_node = left_tree_node;       //left_max_node为左子树最大结点
			while (left_max_node->right_ != NULL)           //key:寻找左子树最大结点,即remove_node的直接前驱
			{
				left_max_parent_node = left_max_node;
				left_max_node = left_max_node->right_;

			}
			remove_node->entry_ = left_max_node->entry_;    //key:这里不是重新链接,而是替换remove_node的内容,将左子树最大结点数据内容赋值给remove_nove的数据区
			if (left_max_parent_node != remove_node)        //比left_tree_node大的结点至少有一个
				left_max_parent_node->right_ = left_max_node->left_;
			else                                            //没有比left_tree_node大的结点
				left_max_parent_node->left_ = left_max_node->left_;    //此时的left_max_parent_node即为remove_node,left_max_node为left_tree_node


			delete left_max_node;
		}
		return true;
	}
	else
		return false;
}

bool BinarySearchTree::Search(const ElemType& target,TreeNode **&node_ptr) const
{
	
	//pre:node=&root_
	//post:若查找失败,返回false,node_ptr为查找路径上最后一个结点即叶结点的指向TreeNode*指针(依比较大小可能是<或>)(特别:root_=NULL时,node_ptr=root_)
	//post:若查找成功,返回true,node_ptr为查找成功元素的父结点的指向TreeNode*指针(依比较大小可能是<或>)
	//key:node_ptr为**&类型,来作为返回值
	//if (*node_ptr == NULL) //树为空或传递的参数错误
	//	return false;

#ifndef NDEBUG
	cout<<(void*)node_ptr<<endl;
#endif
	while (*node_ptr != NULL)  //树至少有一个结点,则进入循环体
	{
		TreeNode *node = *node_ptr;   //node为下一个要查找的结点
		if (node->entry_ == target)
			return true;
		else if (target < node->entry_)
			node_ptr = & node->left_;
		else
			node_ptr = & node->right_;
		
#ifndef NDEBUG
	cout<<(void*)node_ptr<<endl;
#endif
	}
	return false;
}

bool BinarySearchTree::Search(const ElemType& target) const
{
	TreeNode *node = root_;
	while (node != NULL)
	{
		if (target == node->entry_)
			return true;
		else if (target < node->entry_)
			node = node->left_;
		else
			node = node->right_;
	}

	return false;
}


void BinarySearchTree::InOrderTraverse() const
{
	InOrderTraverseRecursive(root_);
}

void BinarySearchTree::InOrderTraverseRecursive(TreeNode *node) const
{
	if (node == NULL)
		return;

	InOrderTraverseRecursive(node->left_);
	cout<<node->entry_<<',';
	InOrderTraverseRecursive(node->right_);
}

bool BinarySearchTree::IsEmpty() const
{
	return (root_ == NULL)? true : false;
}

utility.h


/*-----------------------------------------------   
Created By EverSteins   
Email:EverSteins@gmail.com  
转载请注明出处  
------------------------------------------------*/ 

#ifndef UTILITY_H
#define UTILITY_H

#include <cstddef>
#include <cassert>
#include <cstdlib>
#include <stdlib.h>

#endif

main.cc


/*-----------------------------------------------   
Created By EverSteins   
Email:EverSteins@gmail.com  
转载请注明出处  
------------------------------------------------*/ 

#include "stdafx.h"
#include <iostream>
#include "utility.h"
#include "binary_search_tree.h"
using namespace std;

typedef int ElemType;

int _tmain(int argc, _TCHAR* argv[])
{
	BinarySearchTree btree;
	int input;
	for (int i=0;i<7;++i)
	{
		cin>>input;
		btree.Insert(input);
	}
	
	;
	btree.Remove(20);
	//btree.Remove(9);
	btree.InOrderTraverse();
	cout<<btree.IsEmpty()<<endl;

	//cout<<btree.Search(-5)<<endl;

	system("pause");
	return 0;
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值