目录

二叉排序树(二叉搜索树)定义:

 二叉排序树的性质:

 二叉排序树的操作:

c语言实现二叉排序树:

C++实现二叉排序树:


二叉排序树(二叉搜索树)定义:

【数据结构和算法笔记】用c和c++分别实现二叉搜索树_算法

【数据结构和算法笔记】用c和c++分别实现二叉搜索树_子树_02

 

【数据结构和算法笔记】用c和c++分别实现二叉搜索树_二叉排序树_03

 二叉排序树的性质:

(1)二叉排序树的中序遍历序列是递增的

          推论:只给出二叉排序树的后序/前序序列,可以唯一确定二叉排序树

(2)根最左下节点值最小,根最右下节点值最大

【数据结构和算法笔记】用c和c++分别实现二叉搜索树_数据结构_04

 二叉排序树的操作:

1在二叉排序树中查找一个元素k:

      过程类似于二分查找:如果mid=k,返回mid;如果mid>k,向左区间中查找;如果mid<k,向右区间中查找

时间复杂度:O(log2n)

①递归出口:如果根节点为空,或者根节点值等于待查找的元素,返回根节点

②如果根节点的值<k,向左子树中查找

③如果根节点的值>k,向右子树中查找

伪代码:

search(root,k):if root==null or k==root的值 return root if root的值>k 递归调用函数search(root->left,k) if root的值<k 递归调用函数search(root->right,k)


 2 在二叉排序树中插入一个值为k元素

在二叉排序树中插入一个关键字为k的节点要保证插入后仍满足二叉排序树有序的性质

时间复杂度:O(log2n)

【数据结构和算法笔记】用c和c++分别实现二叉搜索树_数据结构_05

伪代码:

insert(root,k):if root==NULL 新建一个值为k的node return node if k==root的值 无需插入 if k<root的值 //k插入到左子树 insert(root->left,k) else //k插入到右子树 insert(root->right,k)

3 由一个数组创建一个二叉排序树

创建二叉排序树的根节点,扫描数组,并逐个插入到二叉排序树中

create(root,int a[]){ 为root申请内存空间 for(i:a) insert(root,a[i]) }

4在二叉排序树中删除一个元素k

递归实现:

递归调用:①如果k<根节点的值,向左子树中删除k

递归调用:②如果k>根节点的值,向右子树删除k

递归出口:③如果k=根节点的值,分三种情况讨论

        Ⅰ根节点既有左子树又有右子树,用根节点的中序后继节点替代根节点

                在二叉排序树中, 根节点的中序后继节点为根节点右子树的最左下节点(因为该节点的值是右子树中大于根节点的最小的值)

        Ⅱ根节点左子树为空,用右子树替代根节点,即返回右子树

        Ⅲ根节点右子树为空,用左子树替代根节点,即返回左子树

        Ⅳ根节点左右子树均为空即根节点是叶子节点,返回空

例:

【数据结构和算法笔记】用c和c++分别实现二叉搜索树_子树_06

5.判定一棵树是否是二叉排序树

利用二叉排序中序遍历递增的性质:中序遍历该树,判断该中序序列是否是递增序列

c语言实现:

声明二叉排序树结点类型

typedef struct node
{
	KeyType key;              		//关键字项
	InfoType data;             		//其他数据域
	struct node *lchild,*rchild;	//左右孩子指针
} BSTNode;           				//二叉排序树结点类型
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

 二叉排序树的插入:

bool InsertBST(BSTNode *&bt,KeyType k)	
//在二叉排序树bt中插入一个关键字为k的结点。插入成功返回真,否则返回假
{	if (bt==NULL)						//原树为空,新插入的结点为根结点
	{	bt=(BSTNode *)malloc(sizeof(BSTNode));
		bt->key=k; bt->lchild=bt->rchild=NULL;
		return true;
	}
	else if (k==bt->key) 				//树中存在相同关键字的结点,返回假
		return false;
	else if (k<bt->key) 
		return InsertBST(bt->lchild,k);	//插入到左子树中
	else
		return InsertBST(bt->rchild,k);	//插入到右子树中
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.

二叉排序树的建立:

BSTNode *CreateBST(KeyType A[],int n)		//创建二叉排序树
//返回BST树根结点指针
{	BSTNode *bt=NULL;				//初始时bt为空树
	int i=0;
	while (i<n)
	{	InsertBST(bt,A[i]);			//将关键字A[i]插入二叉排序树bt中
		i++;
	}
	return bt;						//返回建立的二叉排序树的根指针
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

二叉排序树的查找:

STNode *SearchBST(BSTNode *bt,KeyType k)
{ 
    if (bt==NULL || bt->key==k)      	//递归终结条件
		return bt;
	if (k<bt->key)
       	return SearchBST(bt->lchild,k);  //在左子树中递归查找
    else
     	return SearchBST(bt->rchild,k);  //在右子树中递归查找
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

二叉排序树的删除:

void Delete1(BSTNode *p,BSTNode *&r)  //当被删p结点有左右子树时的删除过程
{
	BSTNode *q;
	if (r->rchild!=NULL)
		Delete1(p,r->rchild);	//递归找最右下结点r,r结点的值是p结点的中序后缀结点
	
    else						//找到了最右下结点r
	{	p->key=r->key;			//将*结点的值赋给结点p
		q=r;					
		r=r->lchild;			//直接将其左子树的根结点放在被删结点的位置上
		free(q);				//释放原结点r的空间
	}
}
void Delete(BSTNode *&p)		//从二叉排序树中删除p结点
{
	BSTNode *q;
	if (p->rchild==NULL)		//p结点没有右子树的情况
	{
		q=p;
		p=p->lchild;			//直接将其右子树的根结点放在被删结点的位置上
		free(q);  
	}
	else if (p->lchild==NULL)	//p结点没有左子树的情况
	{
		q=p;
		p=p->rchild;			//将p结点的右子树作为双亲结点的相应子树
		free(q);  
	}
	else Delete1(p,p->lchild);	//p结点既没有左子树又没有右子树的情况
}
int DeleteBST(BSTNode *&bt,KeyType k)	//在bt中删除关键字为k的结点
{
	if (bt==NULL) 
		return 0;				//空树删除失败
	else 
	{	
		if (k<bt->key) 
			return DeleteBST(bt->lchild,k);	//递归在左子树中删除为k的结点
		else if (k>bt->key) 
			return DeleteBST(bt->rchild,k);	//递归在右子树中删除为k的结点
		else 
		{
			Delete(bt);		//调用Delete(bt)函数删除*bt结点
			return 1;
		}
	}
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.

C++实现二叉排序树:

声明节点类型

struct TreeNode {
 int val;//结点值
 TreeNode *left;//左孩子结点
 TreeNode *right;//右孩子节点
 TreeNode() : val(0), left(nullptr), right(nullptr) {}//构造函数1
 TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}//构造函数2
 TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}//构造函数3
};
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

二叉排序树的插入:

class Solution {
public:
    TreeNode* insertIntoBST(TreeNode* root, int val) {
//如果根节点为空,返回以val创建的根节点
if(root==NULL)
{
    TreeNode *node=new TreeNode(val);
    return node;
}
//如果根节点的值小于val,val插入到右子树,
if(root->val<val)
{
  TreeNode*r=insertIntoBST(root->right,val);//返回插入后右子树的根节点
   root->right=r;
   return root;
}
//如果根节点的值大于Val,val插入到左子树,
else
{
     TreeNode*l=insertIntoBST(root->left,val);//返回插入后左子树的根节点
     root->left=l;
     return root;
}
    }
};
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.

二叉排序树的查找:
 

class Solution {
public:
    TreeNode* searchBST(TreeNode* root, int val) {
if(root==NULL)
return NULL;
if(root->val==val)
return root;
if(root->val<val)
{
    return searchBST(root->right,val);
}
else
{
    return searchBST(root->left,val);
}
    }
};
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.

二叉排序树的删除:
 

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* deleteNode(TreeNode* root, int key) {
//如果根节点为空,没有节点可以删除,返回空
if(root==NULL)
{
    return NULL;
}
//如果key<根节点的值,在左子树中删除
if(key<root->val)
{
    //递归调用函数删除左子树中的key,返回左子树的根节点
    root->left=deleteNode(root->left,key);
}
//如果key>根节点的值,在右子树中删除
else if(key>root->val)
{
    //递归调用函数删除右子树中的Key,返回右子树的根节点
    root->right=deleteNode(root->right,key);
}
//找到了待删除的节点
else{
//如果该节点既有左孩子节点又有右孩子节点,则寻找当前节点的中序后继节点,即右子树中最左下节点
if(root->left&&root->right)
{
TreeNode *pre=root;
TreeNode *next=root->right;
while(next->left!=NULL)
{
    pre=next;
    next=next->left;
}
//pre为右子树最左下节点的前一个节点,next为右子树的最左下节点


//如果右子树的最左下节点为本身
if(pre==root)
{
    pre->right=next->right;
}

else{
    pre->left=next->right;
}
root->val=next->val;

}
//左子树为空(以保证左右子树至少有一个为空)
else if(root->left==NULL)
{
    return root->right;
}

else{
    return root->left;
}}
return root;
    }
};
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.

判定二叉搜索树:
 

class Solution {
public:
  vector<int>vec;
//将树的中序遍历存放在vec数组中
  void inorder(TreeNode *root)
  {
      if(root==NULL)return;
      inorder(root->left);
      vec.push_back(root->val);
      inorder(root->right);
  }
    bool isValidBST(TreeNode* root) {
        inorder(root);
//判断数组是否递增
for(int i=0;i<vec.size()-1;i++)
{
    
    if(vec[i]>=vec[i+1])
    return false;
}
return true;
    }
};
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.