二叉排序树的构建与遍历-----数据结构与算法笔记

1、二叉排序树

参考书:《数据结构(C语言)》–严蔚敏等编著,清华大学出版社。
二叉排序树的特征

--二叉排序树是一棵空树或者具有以下特性的二叉树:
--若它的左子树不为空,则左子树上所有节点的值均小于它的根节点的值;
--若它的右子树不为空,则右子树上所有节点的值均大于等于它的根节点的值;
--它的左右子树也分别为一棵二叉排序树;

二叉排序树的存储结构与二叉树类似,加入了关键字存储结构,如下:

typedef struct {
	KeyType key;	//关键字域
	InfoType otherinfo;		//其他关键字域
}ElemType;

typedef struct BSTNode{
	ElemType data;	//数据域
	struct BSTNode *lchold, *rchild;	//左右孩子指针
}BSTNode, *BSTree;

2、二叉排序树的构建过程

二叉排序树是一种动态树表,树的结构通常不是一次性构成的,它是在查找的过程中,当树中不存在其关键字的时候,便向树中插入,使其满足二叉排序树的特点。新插入的节点一定是一个新添加的叶子结点,并且此节点是在查找不成功时的路径的最后一个节点的左孩子或者右孩子上。二叉排序树的构建过程如下:
给定查找的关键字序列为;注:每次的插入操作都会看成是一次二叉排序树的查找,有就不再插入,没有就插入
在这里插入图片描述
(1)、当前树为NULL,首先从第一个关键字开始进行构建
在这里插入图片描述
(2)、插入24关键字,24 < 45,所以为45的左孩子,在插入构建的过程中一定注意二叉排序树的特点:左孩子 < 根节点 < 右孩子
在这里插入图片描述
(3)、依次插入到45节点后;
在这里插入图片描述
每次的插入操作都会看成试一次二叉排序树的查找,当对第二个45关键字进行插入时会发现此时的二叉排序树的根节点的值与此关键字相等,就不在进行插入;
(4)、插入12关键字,顺着45 -> 24查找(12<45 且12<24),没有就进行插入;
在这里插入图片描述
24关键字也是一样,在树中45关键字的左孩子上查找到就不在进行插入;
(5)、插入90关键字,竖着45 -> 53 查找(90>45 且 90>53),没有就进行插入;
在这里插入图片描述
这样就构建完成,对于给定的一个关键字也是一样,若存在就此返回,若不存在就进行插入。

由此可以看出二叉排序树具有以下重要的两点性质

二叉排序树的左--右遍历 (中序遍历) 是一个递增序列,如上图:12,24,45,53,90
二叉排序树的右--左遍历是一个递减序列,如上图:90,53,45,45,24,12

也就是说,一个无序序列可以通过构造一棵二叉排序树变成一个有序序列,即为排序;
二叉排序树的操作有查找、删除、插入,如何删除下期见;

3、二叉排序树的查找ASL

二叉排序树的ASL是根据它的形态决定的,也就是无序序列的顺序决定,比如以下两棵树的ASL不一:
二叉排序树的总根节点永远是第一个关键字作为树的总根节点;

在这里插入图片描述
含有n个节点的二叉排序树的平均查找长度ASL和树的形态有关。
最好情况下:ASL= log ⁡ 2 \log_2 log2(n+1) -1 (形态比较均衡) O( log ⁡ 2 n \log_2^n log2n);

最坏情况下:ASL= n + 1 2 \frac{n+1}{2} 2n+1 (单支树的形态,与顺序表效率相同) O(n);

相关代码:

#include "stdio.h"
#include "stdlib.h"
#define OK 		1
#define ERROR 	0
#define OVERFLOW -2

typedef int Status;
typedef int KeyType;
typedef struct {
	KeyType key;	//关键字域
} ElemType;

typedef struct BSTNode {
	ElemType data;	//数据域
	struct BSTNode *lchild, *rchild;	//左右孩子指针
} BSTNode, *BSTree;

Status InsertBST(BSTree &T,KeyType key);
Status InsertBST(BSTree &T,KeyType key) {
	if(T == NULL) {
		T = new BSTNode;
		T->data.key = key;	//插入节点 
		T->lchild = T->rchild = NULL;	//插入后的节点的左右孩子均为NULL 
		return OK;
	} 
	else if(key == T->data.key) return ERROR;	//说明次二叉排序树中有此关键字 
	else if(key > T->data.key) return InsertBST(T->rchild,key);	//递归插入右边 
	else return InsertBST(T->lchild,key);		//递归插入左边 	
}

Status CreateBST(BSTree &T);
Status CreateBST(BSTree &T) {
	T = NULL;
	int key;
	while(1) {
		scanf("%d",&key);
		if(key == -1) break;	//-1 作为输入结束标志
		InsertBST(T,key);
	}
	return OK;
}

Status RightOrderTraverse(BSTree T);
//右-->根-->左
Status RightOrderTraverse(BSTree T) {
	if(T == NULL) return OK;
	else {
		RightOrderTraverse(T->rchild);
		printf("%d ",T->data.key);
		RightOrderTraverse(T->lchild);
	}
	return OK;
}

int main(void) {
	BSTree T;
	printf("请输入二叉排序树的数据:");
	CreateBST(T);
	printf("二叉排序树的大到小遍历(右-左)为:");
	RightOrderTraverse(T);
	return 0;
}

/*
构建二叉排序树,并对该二叉排序树按“右-根-左”顺序进行遍历,并输出该序列。
测试输入:10 44 8 22 77 6 99 10 -1 (-1作为输入结束标志)
预期输出:99 77 44 22 10 8 6
*/
  • 5
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小王桐学

谢谢,只求点赞哟

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值