Chapter 8: 6. Binary Sort Tree

This article refers to "Dahua Data Structure", thanks to the author Mr. Cheng Jie.

One: The
so-called advantage is just thinking more deeply than others.

Two:
The advantages of binary sort tree:
*The efficiency of insertion and deletion and the efficiency of element search are very high, and the time complexity is O(logN);

Three:
The creation of a binary sort tree:
When we need to search for the set {62, 88, 58, 47, 35, 73, 51, 99, 37, 93},
we should consider the binary tree structure when creating this set. And the binary tree that is sorted in time:
Insert picture description here
Four:
Binary sort tree, also known as binary search tree.
It is either an empty tree or a binary tree with the following properties:
1. If its left subtree is not empty, the values ​​of all nodes on the left subtree are less than the value of its root structure;
2. If Its right subtree is not empty, then the values ​​of all nodes on the right subtree are greater than the value of its root structure;
3. Its left and right subtrees are also binary sorted trees respectively;

Five: Summary:
1. The binary sort tree is stored in a linked manner, maintaining the advantage that the linked storage structure
does not need to move elements when inserting and deleting operations . As long as the appropriate insertion and deletion positions are found, only the connection pointer needs to be modified. That's it.
2. The time performance of insertion and deletion is better, and for the search of binary sorting tree, the path from the root node to the node to
be found is taken , and the number of comparisons equal to the number of layers of the binary sorting tree in the binary sorting tree.

Six: Implementation code:

/*
 
本篇文章参考的是《大话数据结构》,感谢作者程杰先生。

*/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>

#include "bigtalk_data_structure.h"
#include "stdio.h"    
#include "stdlib.h"   

#include "math.h"  
#include "time.h"

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 100 /* 存储空间初始分配量 */

typedef int Status;	/* Status是函数的类型,其值是函数结果状态代码,如OK等 */ 

/* 二叉树的二叉链表结点结构定义 */
typedef  struct BiTNode	/* 结点结构 */
{
    
    
	int data;	/* 结点数据 */
	struct BiTNode *lchild, *rchild;	/* 左右孩子指针 */
} BiTNode, *BiTree;


/* 递归查找二叉排序树T中是否存在key, */
/* 指针f指向T的双亲,其初始调用值为NULL */
/* 若查找成功,则指针p指向该数据元素结点,并返回TRUE */
/* 否则指针p指向查找路径上访问的最后一个结点并返回FALSE */
Status SearchBST(BiTree T, int key, BiTree f, BiTree *p) 
{
    
      
	if (!T)	/*  查找不成功 */
	{
    
     
		*p = f;  
		return FALSE; 
	}
	else if (key==T->data) /*  查找成功 */
	{
    
     
		*p = T;  
		return TRUE; 
	} 
	else if (key<T->data) 
	{
    
    
		return SearchBST(T->lchild, key, T, p);  /*  在左子树中继续查找 */	
	}		
	else  
	{
    
    
		return SearchBST(T->rchild, key, T, p);  /*  在右子树中继续查找 */		
	}		
}


/*  当二叉排序树T中不存在关键字等于key的数据元素时, */
/*  插入key并返回TRUE,否则返回FALSE */
Status InsertBST(BiTree *T, int key) 
{
    
      
	BiTree p,s;
	
	if (!SearchBST(*T, key, NULL, &p)) /* 查找不成功 */
	{
    
    
		s = (BiTree)malloc(sizeof(BiTNode));
		
		s->data = key;  
		s->lchild = s->rchild = NULL; 
		
		if (!p) 
		{
    
    
			*T = s;			/*  插入s为新的根结点 */			
		}			
		else if (key<p->data) 
		{
    
    
			p->lchild = s;	/*  插入s为左孩子 */			
		}			
		else 
		{
    
    
			p->rchild = s;  /*  插入s为右孩子 */			
		}			
		return TRUE;
	} 
	else 
	{
    
    
		return FALSE;  /*  树中已有关键字相同的结点,不再插入 */		
	}		
}

/* 从二叉排序树中删除结点p,并重接它的左或右子树。 */
Status Delete(BiTree *p)
{
    
    
	BiTree q,s;
	
	if((*p)->rchild == NULL) /* 右子树空则只需重接它的左子树(待删结点是叶子也走此分支) */
	{
    
    
		q = *p;
		*p = (*p)->lchild; 
		free(q);
	}
	else if((*p)->lchild == NULL) /* 只需重接它的右子树 */
	{
    
    
		q = *p; 
		*p = (*p)->rchild; 
		free(q);
	}
	else /* 左右子树均不空 */
	{
    
    
		q = *p; 
		s = (*p)->lchild;
		
		while(s->rchild) /* 转左,然后向右到尽头(找待删结点的前驱) */
		{
    
    
			q = s;
			s = s->rchild;
		}
		
		(*p)->data = s->data; /*  s指向被删结点的直接前驱(将被删结点前驱的值取代被删结点的值) */
		if(q != *p)
		{
    
    
			q->rchild = s->lchild; /*  重接q的右子树 */ 			
		}			
		else
		{
    
    
			q->lchild = s->lchild; /*  重接q的左子树 */			
		}		
		free(s);
	}
	return TRUE;
}

/* 若二叉排序树T中存在关键字等于key的数据元素时,则删除该数据元素结点, */
/* 并返回TRUE;否则返回FALSE。 */
Status DeleteBST(BiTree *T,int key)
{
    
     
	if(!*T) /* 不存在关键字等于key的数据元素 */ 
	{
    
    
		return FALSE;		
	}		
	else
	{
    
    
		if (key == (*T)->data) /* 找到关键字等于key的数据元素 */ 
		{
    
    
			return Delete(T);			
		}			
		else if (key<(*T)->data)
		{
    
    
			return DeleteBST(&(*T)->lchild,key);			
		}			
		else
		{
    
    
			return DeleteBST(&(*T)->rchild,key);			
		}					
	}
}

//中序遍历二叉树
Status RecursionBST(BiTree *T)
{
    
    
	if(!*T) /* 不存在关键字等于key的数据元素 */ 
	{
    
    
		return FALSE;		
	}

	RecursionBST(&(*T)->lchild);
	//printf("[%s:%d]:[yang](*T)->data = %d\n",__FUNCTION__,__LINE__,(*T)->data);
	printf("%d, ",(*T)->data);
	RecursionBST(&(*T)->rchild);
	return TRUE;
}



//二叉排序树:
int test_main_8_6()
{
    
     
	printf("[%s:%d]:[yang] ******************* 我是分割线******************* \n",__FUNCTION__,__LINE__);	   
	
	int i;
	int a[10]={
    
    62,88,58,47,35,73,51,99,37,93};
	BiTree T = NULL;
	
	for(i = 0; i < 10; i++)
	{
    
    
		InsertBST(&T, a[i]);
		
		printf("i+1 = %d: ", i + 1);
		RecursionBST(&T);
		printf("\n");
	}
	printf("[%s:%d]:[yang] ******************* 我是分割线******************* \n",__FUNCTION__,__LINE__);	   

	RecursionBST(&T);
	printf("\n");

	printf("[%s:%d]:[yang] ******************* 我是分割线******************* \n",__FUNCTION__,__LINE__);	   
	DeleteBST(&T,93);

	RecursionBST(&T);
	printf("\n");
	
	printf("[%s:%d]:[yang] ******************* 我是分割线******************* \n",__FUNCTION__,__LINE__);	   
	
	DeleteBST(&T,47);
	
	RecursionBST(&T);
	printf("\n");

	#if 0
	
	
	#endif
	printf("[%s:%d]:[yang] ******************* 我是分割线******************* \n",__FUNCTION__,__LINE__);	   

	
	return 0;
}



print:

[main:14]:[yang] ***************************************** 
[test_main_8_6:183]:[yang] ******************* 我是分割线******************* 
i+1 = 1: 62, 
i+1 = 2: 62, 88, 
i+1 = 3: 58, 62, 88, 
i+1 = 4: 47, 58, 62, 88, 
i+1 = 5: 35, 47, 58, 62, 88, 
i+1 = 6: 35, 47, 58, 62, 73, 88, 
i+1 = 7: 35, 47, 51, 58, 62, 73, 88, 
i+1 = 8: 35, 47, 51, 58, 62, 73, 88, 99, 
i+1 = 9: 35, 37, 47, 51, 58, 62, 73, 88, 99, 
i+1 = 10: 35, 37, 47, 51, 58, 62, 73, 88, 93, 99, 
[test_main_8_6:197]:[yang] ******************* 我是分割线******************* 
35, 37, 47, 51, 58, 62, 73, 88, 93, 99, 
[test_main_8_6:202]:[yang] ******************* 我是分割线******************* 
35, 37, 47, 51, 58, 62, 73, 88, 99, 
[test_main_8_6:208]:[yang] ******************* 我是分割线******************* 
35, 37, 51, 58, 62, 73, 88, 99, 
[test_main_8_6:219]:[yang] ******************* 我是分割线*******************

Guess you like

Origin blog.csdn.net/yanghangwww/article/details/111411729