二叉排序树c++代码及原理(插入、删除、查找、创建)

2023-03-26 20:15:31

 二叉排序树

二叉排序树又称“二叉查找树”、“二叉搜索树”。

二叉排序树:或者是一棵空树,或者是具有下列性质的二叉树:

1. 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;

2. 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;

3. 它的左、右子树也分别为二叉排序树。

二叉排序树通常采用二叉链表作为存储结构中序遍历二叉排序树可得到一个依据关键字的有序序列,一个无序序列可以通过构造一棵二叉排序树变成一个有序序列,构造树的过程即是对无序序列进行排序的过程。每次插入的新的结点都是二叉排序树上新的叶子结点,在进行插入操作时,不必移动其它结点,只需改动某个结点的指针,由空变为非空即可。搜索、插入、删除的时间复杂度等于树高,期望O(logn),最坏O(n)。

虽然二叉排序树的最坏效率是O(n),但它支持动态查找,且有很多改进版的二叉排序树可以使树高为O(logn),如AVL、红黑树等。

排序树的查找算法

在二叉排序树b中查找x的过程为:

 1.若b是空树,则搜索失败,否则:

 2.若x等于b的根节点的数据域之值,则查找成功;否则:

 3.若x小于b的根节点的数据域之值,则搜索左子树;否则:

 4.查找右子树。

二叉排序树的删除算法

在二叉排序树中删去一个结点,分三种情况讨论:

 1.若*p结点为叶子结点,即PL(左子树)和PR(右子树)均为空树。由于删去叶子结点不破坏整棵树的结构,则只需修改其双亲结点的指针即可。

 2.若*p结点只有左子树PL或右子树PR,此时只要令PL或PR直接成为其双亲结点*f的左子树(当*p是左子树)或右子树(当*p是右子树)即可,作此修改也不破坏二叉排序树的特性。

 3.若*p结点的左子树和右子树均不空。在删去*p之后,为保持其它元素之间的相对位置不变,可按中序遍历保持有序进行调整。比较好的做法是,找到*p的直接前驱(或直接后继)*s,用*s来替换结点*p,然后再删除结点*s。

typedef struct node{
     int key;
	 struct node *lchild,*rchild;

}BSTree;
//二叉排序树的插入算法
int insertBST(BSTree* &p,int k){
  if(p==NULL){
	  p = (BSTree*)malloc(sizeof(BSTree));
	  p->key = k;p->rchild=p->lchild=NULL;
	  return 1;
  }
   else if(k==p->key)  return 0;
   else if(k<p->key) return insertBST(p->lchild,k);
   else  return insertBST(p->rchild,k);

}
//二叉排序树的创建
BSTree *CreatBST(vector<int> &a,int n) // 返回树根指针
{	BSTree *bt=NULL; // 初始时bt 为空树
	int i=0;
	while (i<n)
	{ insertBST(bt,a[i]); // 将a[i] 插入二叉排序树T中
		i++;
	}
	return bt; // 返回建立的二叉排序树的根指针
}

//首先查找要删除节点是否在二叉排序树中
void delete_p(BSTree* &p);
int delete_k(BSTree* &root,int k){
	if(root!=NULL){
		if(k==root->key){
			delete_p(root);
			return 1;}
		else if(k<root->key)
			return delete_k(root->lchild,k);
		else
			return delete_k(root->rchild,k);
	}
	else
		return 0;
}
void delete_both(BSTree* p,BSTree* &root)
{
	BSTree* q;
	if(root->rchild!=NULL) 
		delete_both(p,root->rchild); //找到直接前驱
	else{
		p->key = root->key; //值交换
		q =root;root=root->lchild;
		free(q);
	}
}
//如果找到要删除的节点,进行删除
void delete_p(BSTree* & p){
	BSTree *q;
	//删除节点为叶子节点的情况,
	if(p->lchild==NULL&&p->rchild==NULL)
		free(p);
	//删除节点只有右子树的情况,
	else if(p->lchild==NULL){
		q = p;
		p = p->rchild;
		free(q);
	}
	//删除节点只有左子树的情况,
	if(p->rchild==NULL){
		q = p;
		p = p->lchild;
		free(q);
	}
	//删除的节点有左右节点的情况
	else delete_both(p,p->lchild);
}

void print(BSTree* &root){
	if(root){
		print(root->lchild);
		cout << root->key <<" ";
		print(root->rchild);
	}
}

int main()
{
	vector<int> data{ 61, 17, 29, 22, 34, 60, 72, 21, 50, 1, 62 };
	int n = data.size();
	//SI_sort(data,n);
	//shell_sort(data,n);
	//Bibble_sort(data,n);
	//quickSort(data,0,n-1);
	//select_sort(data,n);
	//head_sort(data,n);
	//merge_sort(data,n);
	BSTree *root;
	root = CreatBST(data,n);
	print(root);
   // for (int i = 0; i < n; i++)
   // {
  //      cout << data[i]<<" ";
   // }
   return 0;
}

 

  • 作者:展希希鸿
  • 原文链接:https://blog.csdn.net/qq_28266311/article/details/107872356
    更新时间:2023-03-26 20:15:31