树 --- 二叉搜索树

定义:二叉搜索树,又称二叉排序树。顾名思义,它是一种树形结构,并且根据名字可以体现出它有排序和搜索两个特征。

  • 排序。对一个二叉排序树进行中序遍历,得到的是有序的序列。
  • 搜索。在二叉排序树中对最大元素和最小元素进行搜索会十分遍历。最小元素在树的最左边,最大元素在树的最右边

对于二叉排序树主要有以下操作:

  1. 购买节点
  2. 释放节点
  3. 初始化树
  4. 插入元素
  5. 查找结点(非递归)
  6. 查找结点(递归)
  7. 中序遍历(递归)
  8. 中序遍历(非递归)
  9. 寻找以某个结点为根,其最左边的节点
  10. 寻找后继节点
  11. 寻找前驱结点
  12. 删除节点

首先我们先定义一下二叉排序树所需要的数据结构。

typedef int KeyType;
//树的节点类型
typedef struct BstNode
{
	BstNode *leftchild;
	BstNode *parent;
	BstNode *rightchild;
	KeyType data;
}BstNode;
//二叉排序树的头节点
typedef struct 
{
	BstNode *head;//根节点;
	int  cursize;//表示树中的节点个数
}BSTree;

1、购买节点

/*
第一个参数:父亲节点
第二个参数:左孩子
第三个参数:右孩子
*/
BstNode * Buynode(BstNode *pa = NULL,BstNode *left=NULL,BstNode *right = NULL)
{
	BstNode *s = (BstNode*)malloc(sizeof(BstNode));
	if(NULL == s) exit(1);
	s->leftchild = left;
	s->parent = pa;
	s->rightchild = right;
	return s;
}

2、释放节点

void Freenode(BstNode *p)
{
	free(p);
}

3、初始化二叉排序树

void InitBSTree(BSTree &bt)
{
	bt.head = Buynode();
	bt.cursize = 0;
}

4、插入元素

bool InsertItem(BSTree &bt,KeyType kx)
{
	BstNode *pa = bt.head; // head
	BstNode *p = bt.head->parent; // root;
	while(p != NULL && p->data != kx)
	{
		pa = p;
		p = kx < p->data? p->leftchild:p->rightchild;
	}
	if(p != NULL) return false;
	p = Buynode(pa);
	p->data = kx;
	if(pa == bt.head)
	{
		bt.head->parent = p;
		bt.head->leftchild = p;
		bt.head->rightchild = p;
	}
	else
	{
		if(p->data < pa->data)
		{
			pa->leftchild = p;
			if(p->data < bt.head->leftchild->data)
			{
				bt.head->leftchild = p;
			}
		}
		else
		{
			pa->rightchild = p;
			if(p->data > bt.head->rightchild->data)
			{
				bt.head->rightchild = p;
			}
		}
	}
	bt.cursize+=1;
	return true;
}

5、查找结点(非递归)

BstNode * FindValue(BSTree &bt,KeyType kx)
{
	BstNode *p = bt.head->parent;
	while(p != NULL && p->data != kx)
	{
		p = kx < p->data? p->leftchild:p->rightchild;
	}
	return p;
}

6、查找结点(递归)

BstNode * Search(BstNode *ptr,KeyType kx)
{
	if(ptr == NULL || ptr->data == kx)
		return ptr;
	else if(kx < ptr->data)
		return Search(ptr->leftchild,kx);
	else
		return Search(ptr->rightchild,kx);
}
BstNode * SearchValue(BSTree &bt,KeyType kx)
{
	return Search(bt.head->parent,kx);
}

7、中序遍历(递归)

void InOrder(BstNode *p)
{
	if(p != NULL)
	{
		InOrder(p->leftchild);
		cout<<p->data<<" ";
		InOrder(p->rightchild);
	}
}
void InOrder(BSTree &bt)
{
	InOrder(bt.head->parent);
	cout<<endl;
}

8、中序遍历(非递归)

void NiceInOrder(BSTree &bt)
{
	for(BstNode *p = First(bt.head->parent);
		           p != NULL; p = Next(bt,p) ) 
	{
		cout<<p->data<<" ";
	}
	cout<<endl;
}

9、寻找以某个结点为根,其最左边的节点

BstNode * First(BstNode *ptr)
{
	while(ptr != NULL && ptr->leftchild != NULL)
	{
		ptr = ptr->leftchild;
	}
	return ptr;
}

10、寻找后继结点

BstNode * Next(BSTree &bt,BstNode *ptr)
{
	if(ptr == NULL || ptr == bt.head) return NULL;
	if(ptr->rightchild != NULL)
	{
		return First(ptr->rightchild);
	}
	else
	{
		BstNode *pa = ptr->parent;
		while(pa != bt.head && pa->leftchild != ptr)
		{
			ptr = pa;
			pa = pa->parent;
		}
		if(pa == bt.head)
		{
			pa = NULL;
		}
		return pa;
	}
}

11、寻找前驱结点

BstNode * Pre(BSTree &bt, BstNode *ptr)
{
	if (ptr == NULL || ptr == bt.head) return NULL;
	BstNode *p = bt.head->parent;
	while (p != NULL && Next(bt, p) != ptr)
	{
		p = Next(bt, p);
	}
	return p;
}

12、删除结点

bool RemoveItem(BSTree &bt,KeyType kx)
{
	if(Empty(bt)) return false;
	BstNode *p = FindValue(bt,kx);
	if(NULL == p) return false;

	if(p->leftchild != NULL && p->rightchild != NULL)
	{
		BstNode *nt = Next(bt,p);
		p->data = nt->data;
		p = nt;
	}// leaf brch
	BstNode *pa = p->parent;
	BstNode *child = p->leftchild != NULL? p->leftchild: p->rightchild;
	if(child != NULL) child->parent = pa;
	if(pa == bt.head)
	{
		bt.head->parent = child;
	}
	else
	{
		if(pa->leftchild == p)
		{
			pa->leftchild = child;
		}
		else
		{
			pa->rightchild = child;
		}
	}
	Freenode(p);
	bt.cursize-=1;
	return true;
}

猜你喜欢

转载自blog.csdn.net/qq_41727218/article/details/86582770