二叉排序树的实现

二叉排序树(Binary Sort Tree)又称二叉查找树。 
它是一棵空树,或者是具有下列性质的二叉树: 
(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值; 
(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值; 
(3)左、右子树也分别为二叉排序树;
二叉排序树是一种动态树表。

vs2008运行正确,如有误,请各位大牛指正!
实现代码如下:
// MyBiSortTree.cpp : 定义控制台应用程序的入口点。
// 二叉查找树的各种操作
//实现功能:建树,查找,插入,删除,求最大值最小值,求双亲结点
//        ,获取中序遍历的前驱结点后继结点,用栈实现非递归的先序中序后序遍历算法,
#include "stdafx.h"
#include<iostream>
using namespace std;

int a[100];//存放结点数据的数组
const int STACK_MAXSIZE = 30;
//二叉排序树的结点类型
class BSNode
{
public:
	BSNode(){};
	BSNode(int item):data(item), m_lchild(NULL), m_rchild(NULL){}

	int data;//数据域	
	BSNode *m_lchild;//左孩子
	BSNode *m_rchild;//右孩子
};

//二叉排序树类型
class BSTree
{
public://定义接口
	BSTree();
	//建树:创建一棵结点个数为n的二叉排序树
	void CreateTree();
	//查找:在以root为根的树上查找值为item的结点,返回给Node,找到返回true,否则为false
	bool FindNode(int item);
	//插入:在以root为根的树上插入值为item的结点
	void InsertNode(int item);
	//删除:在以root为根的树上插入值为item的结点
	void DeleteNode(int item);
	//求最大值:返回以root为根的树中结点的最小值,结点返回给minNode
	int MinNode();
	//求最小值:返回以root为根的树中结点的最大值,结点返回给maxNode
	int MaxNode();
	//求双亲结点:返回值为item的结点的双亲结点
	BSNode *GetParent(int item);
	//获取中序遍历的前驱结点
	BSNode *GetInOrderPre(int item);
	//获取中序遍历的后继结点
	BSNode *GetInOrderPost(int item);
	//用栈实现非递归的先序遍历
	void PreOrderVisit();
	//用栈实现非递归的中序遍历
	void InOrderVisit();
	//用栈实现非递归的后序遍历
	void PostOrderVisit();

private:
	BSNode *root; //树的根结点
	//建树:创建一棵结点个数为n的二叉排序树
	void Create(BSNode *&root,int *a, int n);
	//查找:在以root为根的树上查找值为item的结点,返回给Node,找到返回true,否则为false
	bool Find(BSNode *&root, BSNode *&Node, int item);
	//插入:在以root为根的树上插入值为item的结点
	void Insert(BSNode *&root, int item);
	//删除:在以root为根的树上插入值为item的结点
	void Delete(BSNode *&root, int item);
	//求最大值:返回以root为根的树中结点的最小值,结点返回给minNode
	int Min(BSNode *root, BSNode *&minNode);
	//求最小值:返回以root为根的树中结点的最大值,结点返回给maxNode
	int Max(BSNode *root, BSNode *&maxNode);
	//求双亲结点:返回值为item的结点的双亲结点
	BSNode *getParent(BSNode *root, int item);
	//获取中序遍历的前驱结点
	BSNode *getInOrderPre(BSNode *root, int item);
	//获取中序遍历的后继结点
	BSNode *getInOrderPost(BSNode *root, int item);
	//用栈实现非递归的先序遍历
	void PreOrder(BSNode *root);
	//用栈实现非递归的中序遍历
	void InOrder(BSNode *root);
	//用栈实现非递归的后序遍历
	void PostOrder(BSNode *root);
};

BSTree::BSTree()
{
   root = NULL;
}

//建树:创建一棵结点个数为n的二叉排序树
void BSTree::CreateTree()
{
	int n = 0;
    Create(root, a, n);
}

//建树:创建一棵结点个数为n的二叉排序树
void BSTree::Create(BSNode *&root,int *a, int n) //待续,要利用插入算法
{
	cout << "请输入树的结点个数:" ;
	cin >> n;
	cout << endl << "请依次输入结点的数值:" << endl;	 
	BSNode *newNode = NULL;
	for (int i=0; i<n; i++)
	{
		cin >> a[i];
        InsertNode(a[i]);
	}
}

//查找:在以root为根的树上查找值为item的结点,返回给Node,找到返回true,否则为false
bool BSTree::FindNode(int item)
{
	BSNode *Node = NULL;	
	return Find(root, Node, item);	
}

//查找:在以root为根的树上查找值为item的结点,返回给Node,找到返回true,否则为false
bool BSTree::Find(BSNode *&root, BSNode *&findNode, int item)
{	
	if (root == NULL)//树空
	{
		findNode = NULL;//没有找到结点		
		return false;
	}
	else
	{
		if (root->data == item)
		{
			findNode = root;	//找到结点		
			return true;
		}
		else if (root->data > item)//数值小于根结点的数值,则在左子树中递归查找
		{
			return Find(root->m_lchild, findNode, item);
		}
		else //数值大于根结点的数值,则在右子树中递归查找
		{
			return Find(root->m_rchild, findNode, item);
		}
	}	
}

//插入:在以root为根的树上插入值为item的结点
void BSTree::InsertNode(int item)
{
     Insert(root, item);
}

//插入:在以root为根的树上插入值为item的结点
//根为空,则直接插入;根不空,则在插入之前先要查找该数值的结点是否存在
void BSTree::Insert(BSNode *&root, int item)
{	
     BSNode *newNode = NULL;
	 if (root == NULL)//树为空,则先建立根结点
	 {		
		 newNode = new BSNode(item);
		 root = newNode;
		 cout << item << "已被插入二叉排序树中!" << endl;
	 }
	 else
	 {
		 if (FindNode(item))//如果找到该数值的结点,直接返回
		 {   
		    cout << "数值" << item << "已经存在!" << endl;
			return;
		 }

		 if (item > root->data)//当前数值比根结点大,则插入树的右子树
		 {
			 Insert(root->m_rchild, item);
		 }
		 else 
		 {
			 Insert(root->m_lchild, item);
		 }
	 }
}

//删除:在以root为根的树上删除值为item的结点
void BSTree::DeleteNode(int item)
{
     Delete(root, item);
}

//删除:在以root为根的树上删除值为item的结点
void BSTree::Delete(BSNode *&root, int item)
{
	BSNode *pNode = NULL;
	if (root == NULL)
	{
		cout << "树空!" << endl;
		return;
	}

	if (Find(root, pNode, item))
	{
		BSNode *pParent = NULL;
		//情况一:叶子结点		
		if (pNode->m_lchild == NULL && pNode->m_rchild == NULL)//被删除结点是叶子结点
		{
			if (pNode == root)//且是根结点
			{
				root = NULL;
			}
			else//且不是根结点
			{
                pParent = GetParent(item);
				if (pParent->m_lchild == pNode)//为其父亲结点的左孩子
				{
					pParent->m_lchild = NULL;
				}
				else//为其父亲结点的右孩子
				{
					pParent->m_rchild = NULL;
				}
			}
		}

		//情况二:只有一个孩子结点			
		else if (pNode->m_rchild != NULL && pNode->m_lchild == NULL)//被删除结点有右孩子,无左孩子
		{
			if (pNode == root)//且是根结点
			{
				root = pNode->m_rchild;
			}
			else//且不是根结点
			{
                 pParent = GetParent(item);//找到给结点的父亲节点
                 if (pParent->m_lchild == pNode)
                 {
					 pParent->m_lchild = pNode->m_rchild;
                 }
				 else
				 {
					 pParent->m_rchild = pNode->m_rchild;
				 }
			}			
		}
		else if (pNode->m_lchild != NULL && pNode->m_rchild == NULL)//被删结点有左孩子,无右孩子
		{
			if (pNode == root)//且是根结点
			{
				root = pNode->m_lchild;
			}
			else//且不是根结点
			{
				pParent = GetParent(item);//找到给结点的父亲节点
				if (pParent->m_lchild == pNode)
				{
					pParent->m_lchild = pNode->m_lchild;
				}
				else
				{
					pParent->m_rchild = pNode->m_lchild;
				}                   
			}			
		}
		//情况三:有两个孩子结点		
		else if (pNode->m_lchild != NULL && pNode->m_rchild != NULL)//被删结点有左孩子和右孩子
		{			
            //解法一:找到该结点的前驱结点(右孩子必为空)			
			BSNode *maxNode = NULL;
			int max = Max(pNode->m_lchild, maxNode);//找到以该结点左孩子为根的子树上最大的结点,即为其前驱结点
			BSNode *father = GetParent(max);
			pNode->data = max;//将前驱结点的值赋给该结点
			if (father != pNode)
			{
				father->m_rchild = maxNode->m_lchild;
			}
			else
			{
				father->m_lchild = maxNode->m_lchild;
			}

			//解法二:找到该结点的后继结点(左子树必为空)
			//BSNode *minNode = NULL;
			//int min = Min(pNode->m_rchild, minNode);//找到以该结点右孩子为根的子树上最小的结点,即为其后继结点
			//BSNode *father = GetParent(min);
			//pNode->data = min;//将后继结点的值赋给该结点
   //         if (father != pNode)
   //         {
			//	father->m_lchild = minNode->m_rchild;
   //         }
			//else
			//{
			//	father->m_rchild = minNode->m_rchild;
			//}

			//解法三:让该结点的左子树为其父亲结点的左子树(或右子树,取决于该结点是父亲结点的左子树还是右子树),
			//        其右子树为其前驱结点(以该结点左孩子为根的子树中最大值结点)的右子树
    //         BSNode *Father = GetParent(item);
			 //if (Father == NULL)//该结点是根结点
			 //{
    //             root = pNode->m_lchild;
				// BSNode *maxNode = NULL;
				// int max = Max(pNode->m_lchild, maxNode);
				// maxNode->m_rchild = pNode->m_rchild;
			 //}
			 //else//该结点不是根结点
			 //{
				// if (Father->m_lchild == pNode)
				// {
				//	 Father->m_lchild = pNode->m_lchild;
				// }
				// else
				// {
				//	 Father->m_rchild = pNode->m_lchild;
				// }
				// //BSNode *maxNode = GetInOrderPre(item);
				// BSNode *maxNode = NULL;
				// int max = Max(pNode->m_lchild, maxNode);
				// maxNode->m_rchild = pNode->m_rchild;
			 //} 			
		}
		if (root == NULL)
		{
			cout << "删除结点后,二叉排序树为空!" << endl;
		}
		else
		{
			cout << "结点" << item << "删除成功!" << endl;
		}
	}
	else
	{
		cout << "数值为" << item << "的结点不存在!" << endl;
	}	
}

//求最小值:返回以root为根的树中结点的最小值,结点返回给minNode
int BSTree::MinNode()
{
	BSNode *minNode;
    return Min(root, minNode);
}

//求最小值:返回以root为根的树中结点的最小值,结点返回给minNode
int BSTree::Min(BSNode *root, BSNode *&minNode)
{
	int min = 0;
	BSNode *p = root;
	if (p == NULL)
	{
		cout << "树空!" <<endl;
		return -1;//结果为-1表示树空,最小值不存在
	}
	else
	{
		while(p->m_lchild)
		{
           p = p->m_lchild;
		}
		minNode = p;
		return minNode->data;
	}
	return min;
}

//求最大值:返回以root为根的树中结点的最大值,结点返回给maxNode
int BSTree::MaxNode()
{
	BSNode *maxNode = NULL;
    return Max(root, maxNode);
}

//求最大值:返回以root为根的树中结点的最大值,结点返回给maxNode
int BSTree::Max(BSNode *root, BSNode *&maxNode)
{
	int max = 0;
	BSNode *p = root;
	if (p == NULL)
	{
		cout << "树空!" <<endl;
		return -1;//结果为-1表示树空,最大值不存在
	}
	else
	{
		while(p->m_rchild)
		{
			p = p->m_rchild;
		}
		maxNode = p;
		return maxNode->data;
	}
	return max;
}

//求双亲结点:返回值为item的结点的双亲结点
BSNode *BSTree::GetParent(int item)
{
    return getParent(root, item);
}

//求双亲结点:返回值为item的结点的双亲结点
BSNode *BSTree::getParent(BSNode *root, int item)
{
	BSNode *pParent = NULL;//指向双亲结点的指针
	BSNode *pNode = NULL;
	if (Find(root, pNode, item))//找到值为item的结点
	{
		if ((root == NULL) || (root == pNode))//树空,或该结点为根结点,则不存在双亲结点
		{
			pParent = NULL;			
		}
		else//树不空且该结点不是根结点
		{	
			if (root->m_lchild == pNode || root->m_rchild == pNode)
			{
				pParent = root;				
			}
			else if (root->data > item)
			{
				pParent = getParent(root->m_lchild, item);				
			}
			else 
			{
				pParent = getParent(root->m_rchild, item);				
			}
		}
		return pParent;
	}
	else
	{
		cout << "不存在值为" << item << "的结点!";
        return pParent;
	}	
}

//获取中序遍历的前驱结点
BSNode *BSTree::GetInOrderPre(int item)
{
    return getInOrderPre(root, item);
}

//获取中序遍历的前驱结点
//思想:先找到对应的结点,如果该结点的左孩子不空,找到以它的左孩子为根的子树中的最大值结点
//                        否则如果该结点的左孩子空,找到第一个有右孩子的祖先结点
BSNode *BSTree::getInOrderPre(BSNode *root, int item)
{
	BSNode *pPre = NULL;//指向该结点的前驱结点的指针
	BSNode *pNode = NULL;
    if (Find(root, pNode, item))//找到对应的结点
    {
        if (pNode->m_lchild != NULL)//该结点的左孩子不空
        {
			BSNode *maxNode = NULL;
			int max = Max(pNode->m_lchild, maxNode);//找到以它的左孩子为根的子树中的最大值结点
            pPre = maxNode;
        }
		else//该结点的左孩子为空
		{
            //找到第一个有右孩子的祖先结点
			BSNode *pParent = GetParent(item);
;
			while(pParent->m_rchild == NULL)//右孩子为空
			{
				pParent = GetParent(pParent->data);
			}

			pPre = pParent;
		}
		return pPre;
    }
	else 
	{
		cout << "数值为" << item << "的结点不存在!";
		return pNode;
	}	
}


//获取中序遍历的后继结点
//思想:先找到对应的结点,如果右孩子节点非空,则找到右子树的最小值节点
//否则如果右孩子节点为空,则找到第一个有左孩子节点的其祖辈节点
BSNode *BSTree::GetInOrderPost(int item)
{
    return getInOrderPost(root, item);
}

//获取中序遍历的后继结点
BSNode *BSTree::getInOrderPost(BSNode *root, int item)
{
	BSNode *pPost = NULL;//指向后继结点的指针
	BSNode *pNode = NULL;
	if (Find(root, pNode, item))
	{
        if (pNode->m_rchild != NULL)//该结点的右孩子不空
        {
			//找到以其右孩子为根的子树中最小值的结点
			BSNode *minNode = NULL;
			int mint = Min(pNode->m_rchild, minNode);
			pPost = minNode;
        }
		else//该结点的右孩子为空
		{
           //找到第一个有左孩子的祖先结点
			BSNode *pParent = GetParent(item);
			while(pParent->m_lchild == NULL)
			{
				pParent = GetParent(pParent->data);
			}

			pPost = pParent;
		}
		return pPost;		         
	}
	else
	{
		cout << "数值为" << item << "的结点不存在!" << endl;
		return pPost;
	}	
}

//用栈实现非递归的先序遍历
void BSTree::PreOrderVisit()
{
    PreOrder(root);
}

//用栈实现非递归的先序遍历
void BSTree::PreOrder(BSNode *root)
{
	//定义栈
	BSNode* stack[STACK_MAXSIZE];
	int top = 0;//top为0表示栈空,指向栈顶的下一个位置

	BSNode *p = root;
	cout << "二叉树的先序遍历:";
	while(p || (top != 0))//指针不空或栈不空
	{
		if (p)
		{
			stack[top++] = p;//入栈
			cout << p->data << " ";//访问该结点
			p = p->m_lchild;
		}
		else
		{
			p = stack[--top];//出栈
			p = p->m_rchild;
		}
	}
	cout << endl;
}

//用栈实现非递归的中序遍历
void BSTree::InOrderVisit()
{
   InOrder(root);
}

//用栈实现非递归的中序遍历
void BSTree::InOrder(BSNode *root)
{
	//定义栈
	BSNode* stack[STACK_MAXSIZE];
	int top = 0;//top为0表示栈空,指向栈顶的下一个位置

	BSNode *p = root;
	cout << "二叉树的中序遍历:";
	while(p || (top != 0))//指针不空或栈不空
	{
		if (p)
		{
			stack[top++] = p;//入栈			
			p = p->m_lchild;
		}
		else
		{
			p = stack[--top];//出栈
			cout << p->data << " ";//访问该结点
			p = p->m_rchild;
		}
	}
	cout << endl;
}

//用栈实现非递归的后序遍历,后序遍历较为复杂,需要用到两个栈
void BSTree::PostOrderVisit()
{
   PostOrder(root);
}

//用栈实现非递归的后序遍历,后序遍历较为复杂,需要用到两个栈
void BSTree::PostOrder(BSNode *root)
{
	//定义栈
	BSNode* stack1[STACK_MAXSIZE];
    BSNode* stack2[STACK_MAXSIZE];
	int top1 = 0;//top为0表示栈空,指向栈顶的下一个位置
    int top2 = 0;
	BSNode *p = root;

	cout << "二叉树的后序遍历:";
	while(p || (top1 != 0))//指针不空或栈不空
	{
		if (p)
		{
			stack1[top1++] = p;//入栈1
			stack2[top2++] = p;//入栈2
			p = p->m_rchild;//注意此处是指向右孩子
		}
		else
		{
			p = stack1[--top1];//栈1的栈顶元素出栈,栈2元素不出栈			
			p = p->m_lchild;
		}
	}
    
	while(top2 != 0)
	{
		p = stack2[--top2];//栈2栈顶元素出栈
        cout << p->data << " ";//访问该结点       
	}
	
	cout << endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
     BSTree tree;
	 tree.CreateTree();
	 tree.PreOrderVisit();
	 tree.InOrderVisit();
	 tree.PostOrderVisit();
	 int item = 0;
	 cout << "请输入要查找的结点值:";
	 cin >> item;
	 cout << item << "存在返回1,否则返回0.结果是:" << tree.FindNode(item) << endl;
	 cout << item << "的双亲是:" ;
	 if (tree.GetParent(item))
	 {
		 cout << tree.GetParent(item)->data << endl;
	 }
	 else
	 {
		 cout << "该结点为根结点,不存在双亲!" << endl;
	 }
	 cout << item << "中序遍历序列中前驱结点值是:" << tree.GetInOrderPre(item)->data << endl;
	 cout << item << "中序遍历序列中后继结点值是:" << tree.GetInOrderPost(item)->data << endl;
	 tree.InsertNode(100);
	 tree.InsertNode(48);
	 tree.DeleteNode(50);
	 tree.DeleteNode(45);
	 tree.DeleteNode(55);
	 tree.InOrderVisit();
	 cout << "二叉排序树中,最大值为:" << tree.MaxNode() << endl;
	 cout << "二叉排序树中,最小值为:" << tree.MinNode() << endl;

	 system("pause");
	 return 0;
}










  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
单词检查是指对一段文本中出现的单词进行检查,以确定它们是否在一个指定的单词列表中出现过。这个问题可以使用二叉排序树来解决。 二叉排序树是一种有序的二叉树,它满足以下条件: - 对于二叉树中的每个节点,其子树中的所有节点的值都小于该节点的值,而右子树中的所有节点的值都大于该节点的值。 - 每个节点都没有重复的值。 我们可以将单词列表中的单词插入到二叉排序树中,并对文本中出现的每个单词进行查找。如果单词存在于二叉排序树中,则说明它出现在单词列表中,否则它不在单词列表中。 下面是一个简单的实现: ```c++ #include <iostream> #include <string> using namespace std; // 二叉排序树节点 struct Node { string word; Node* left; Node* right; Node(const string& w) : word(w), left(nullptr), right(nullptr) {} }; // 插入单词到二叉排序树中 Node* insert(Node* root, const string& word) { if (root == nullptr) { return new Node(word); } if (word < root->word) { root->left = insert(root->left, word); } else if (word > root->word) { root->right = insert(root->right, word); } return root; } // 在二叉排序树中查找单词 bool search(Node* root, const string& word) { if (root == nullptr) { return false; } if (word == root->word) { return true; } else if (word < root->word) { return search(root->left, word); } else { return search(root->right, word); } } int main() { // 构建单词列表 string words[] = {"apple", "banana", "cherry", "date", "elderberry"}; Node* root = nullptr; for (const auto& word : words) { root = insert(root, word); } // 在文本中查找单词 string text = "The apple is a fruit. The banana is also a fruit. The cherry is a kind of berry. The date is a sweet fruit. The elderberry is used to make jam."; string word; for (int i = 0; i < text.size(); i++) { if (isalpha(text[i])) { word += tolower(text[i]); } else { if (!word.empty()) { if (search(root, word)) { cout << word << " is in the word list." << endl; } else { cout << word << " is not in the word list." << endl; } word.clear(); } } } return 0; } ``` 在上面的代码中,我们首先构建了一个单词列表,并将它们插入到二叉排序树中。然后,我们对文本中的每个单词进行查找,如果单词在单词列表中,则输出它在列表中,否则输出它不在列表中。 需要注意的是,在实际应用中,我们可能需要使用更高效的数据结构来存储单词列表,例如散列表。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值