BST(C实现)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/YL970302/article/details/86567283

BST树:(也称二叉排序树或二叉搜索树)

  特点:如果左孩子不空,则左孩子一定比根结点值要小,如果右孩子不空,则右孩子一定比根节点值要大

头结点的组成如下:

Lchild(指向BST最小结点) parent(指向BST的根) data(随机值) Rchild(指向BST最大结点)

一、创建结点:

#include<iostream>
using namespace std;
typedef int ElemType;
typedef struct BstNode
{
	BstNode *LeftChild;
	BstNode *parent;
	BstNode *RightChild;
	ElemType data;
}BstNode;

typedef struct
{
	BstNode *head;
	int Cursize ;
}BSTree;

二、购买结点和释放结点

BstNode *BuyNode(BstNode *parent = NULL, BstNode *Leftchild = NULL, BstNode *Rightchild = NULL)
{
	
	BstNode *p = (BstNode *)malloc(sizeof(BstNode));
	if(NULL == p)
	{
		return NULL;
	}
	p->LeftChild = Leftchild;
	p->parent = parent;
	p->RightChild = Rightchild;
	return p;
}

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

三、初始化:

void InitBSTree(BSTree &bt)
{
	bt.Cursize  = 0;
	bt.head = BuyNode();
}

四、非递归查找某个数值的结点

BstNode *FindValue(BSTree &bt, ElemType x)  //非递归查找
{
	BstNode *p = bt.head->parent;
	while (p!= NULL && p->data != x)
	{
		p = x > p->data ? p->RightChild:p->LeftChild; 
	}
	if(p->data == x)
		return p;
}

五、递归查找某个数值的结点

BstNode *Search(BstNode *p,ElemType x)
{
	if(p == NULL || p->data == x)
		return p;
	else if(p->data > x)
	{
		return Search(p->LeftChild,x);
	}
	else
	{
		return Search(p->RightChild,x);
	}
}
BstNode *SearchValue(BSTree &bt, ElemType x)  //递归查找
{
	return Search(bt.head->parent,x);
}

六、插入结点

bool InsertItem(BSTree &bt, ElemType x)
{
	BstNode *pa = bt.head;  //head
	BstNode *p = bt.head->parent; //root

	while (p!= NULL && p->data != x)   
	{
		pa = p;
		p = x > p->data ? p->RightChild:p->LeftChild; 
	}
	if(p != NULL) 
	{
		return false;
	}
	p = BuyNode(pa);
	p->data = x;

	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(bt.head->LeftChild->data > p->data)  //维护BST树中,头结点左指针指向树中最小值结点
			{
				bt.head->LeftChild = p;
			}
		}
		else
		{
			pa->RightChild = p;
			if(bt.head->RightChild->data < p->data)//维护BST中,头结点右孩子指向树中最大值得结点
			{
				bt.head->RightChild = p;
			}
		}
	}
	bt.Cursize += 1;
	return true;
}

七、非递归中序遍历

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

BstNode * Next(BSTree &bt,BstNode *ptr)
{
	if(NULL == ptr || 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;
	}
}
//非递归遍历
void NiceInOrder(BSTree &bt)
{
	for(BstNode *p = First(bt.head->parent); p != NULL ; p = Next(bt,p))
	{
		cout<<p->data<<" ";
	}
	cout<<endl;
}	

八、递归中序遍历

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;
}

九、删除结点:

   在删除结点的时候要考虑:

(1)空树

(2)是否找得到要删除的结点

(3)叶子结点

(4)单分支

(5)双分支双分支转换为删除它的找它的直接前驱或者直接后继删除,然后进行替换

int GetSize(BSTree &bt)
{
	return bt.Cursize;
}
bool Empty(BSTree &bt)
{
	return GetSize(bt) == 0;
}

bool RemoveItem(BSTree &bt, ElemType x)//删除某一结点
{
	if(Empty(bt))   //二叉树是否为空
	{
		return false;
	}
	BstNode *p = FindValue(bt,x);  //能否找得到要删除的结点
	if(NULL == p)
	{
		return false;
	}
	if(p->LeftChild != NULL && p->RightChild != NULL)  //删除的是有双分支的结点
	{
		BstNode *nt = Next(bt,p);
		p->data = nt->data;
		p = nt;
	}

	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;

}

十、测试

int main()
{
	int ar[]={53,17,78,9,45,65,87,23,81,94,88};
	int n = sizeof(ar)/sizeof(ar[0]);
	int x = 0;
	BSTree myt;
	InitBSTree(myt);

	for(int i = 0;i<n;++i)
	{
		InsertItem(myt,ar[i]);
	}
	NiceInOrder(myt);
	ResNiceInOrder(myt);

	while(cin>>x , x != -1)
	{
		RemoveItem(myt,x);
		NiceInOrder(myt);
	}
	cout<<"InsertItem(myt,16) "<<InsertItem(myt,16)<<endl;
	NiceInOrder(myt);
	BstNode *p1 = FindValue(myt,23);
	cout<<"FindValue(myt,23) "<<p1->data<<endl;
	BstNode *p2 = SearchValue(myt,23);
	cout<<"SearchValue(myt,23) "<<p2->data<<endl;
	return 0;
}

十一、结果展示:

猜你喜欢

转载自blog.csdn.net/YL970302/article/details/86567283
BST