【数据结构笔记】二叉树排序树2019-11-29

二叉排序树又称二叉搜索树。

什么是二叉排序树?

定义
二叉排序树要么是一颗空树,要么具有以下性质:

  • 若左子树不空,左子树上的节点的值小于或等于根节点的值;
  • 若右子树不空,左子树上的节点的值大于或等于根节点的值;
  • 左右子树也均为二叉排序树。

二叉排序树的结点类型如下

typedef struct node
{     keyType key;                       //关键字项
      infoType data;                     //其他数据域
      struct node *lchild, *rlchild;
} BSTNode;

1.二叉排序树上的查找

二叉排序树可看做是一个有序表,所以在二叉排序树上进行查找,和二分查找类似,也是一个逐步缩小查找范围的过程。在这里插入图片描述
每一层只和一个结点进行关键字比较!

递归查找算法SearchBST()如下

BSTNode *SearchBST(BSTNoden *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的20次方个元素中查找某一个元素
其 2的20次方约等于10的6次方
将这些元素放入二叉排序树中,树的高度为20
最多只需要查找20次
对于高度为n的平衡二叉排序树来说
平均查找次数为log2的n

2.二叉排序树的插入和生成

插入过程:

  • 1 若二排序叉树T为空,则创建一个key域为k的结点,将它作为根结点;
  • 2 否则将k和根结点的关键字比较,若两者相等,则说明树中已有此关键字k,无需插入,直接返回0;
  • 3 若k< t ->key, 则将k插入根节点的左子树中。
  • 4 否则将它插入右子树中。

对应的递归算法Insert BST()如下:

int InsertBST(BSTNode *&p, KeyType k)
{
   if(p == NULL)
   {   p=(BSTNode *)malloc(sizeof(BSTNode));
       p->key = k; p->lchild = p->rchild = NULL;
       return 1;
   }
   else if(k == p->key)
      return 0;
      else if(k<p->key)
      return InsertBST(p->lchilde, k);
      else
      return InsertBST(p->rchilde, k);
}

3.二叉排序树的建立

利用二叉排序树的插入和生成实现。

BSTNode *CreatBST(KeyType A[],int n)
{   BSTNode *bt = NULL; //初始是bt为空树
    int i = 0;
    while(i<n)
    {InsertBST(bt,A[i]); //将A[i]插入二叉排序树T中中
      i++;
    }
    return bt;
}

T = O(n logn)

4.二叉排序树的结点删除

  • 1 被删结点是叶子节点:直接删除,并将其双亲节点中相应的指针域的值改为空
  • 2 被删除的结点只有左子树或者右子树,用其左子树或者右子树替换它。
  • 3 被删结点有左子树也有右子树,用其中序前驱值替换,然后再删除该前趋结点。前趋是左子树中最大的结点。

5.如何判断两个二叉排序树是否相等?

在这里插入图片描述不能只用中序遍历来判断,不同二叉排序树可能会出现中序相等的情况,如上图。
需要中序遍历和前序遍历来共同判断。

【附加】数组去重

int a[n] = {…};
(1) sort
1, 2, 2, 3, 3, 4 利用双指针i, j

(2) 哈希 STL: map[a[i]]++
map[i]++; //多余的计入,不再放到二叉排序树里(二叉排序树中无重复元素)
map类->底层->红黑树->变形的二叉排序树

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一、查找 1. 算法设计题 :已知n元顺序表a0, a1, … , an-1按关键字递增有序存储。给定关键字值key,编写算法用对分查找求下标i,满足ai-1<key且aikey。 2. 编程题:输入n个两两互不相等的整数,以这些整数为关键字建立平衡的二叉排序树。判断该二叉树是否为平衡的,输出判断结果;输出该二叉树的中序遍历关键字访问次序。 3. 从空起连续插入以下20个关键字构建m=4的B-。 50, 15, 09, 18, 03, 85, 33, 72, 48, 22, 91, 88, 11, 99, 06, 56, 68, 77, 43, 36。 4. 16个关键字组成的5阶B-如下图所示,请按关键 字递减的次序删除所有结点至空,画出每删除1个关键字后得到B-,直至空。 5. 12个关键字如本电子教案例1所示,设H(K)=K mod 13,地址空间范围0~15,用二次探测再散列解决冲突。画出哈希表;若各元素等概率查找,求成功查找时的平均查找长度。 二、内部排序 1.算法设计与分析题:将直接插入排序的内循环改造为使用对分查找实现元素插入,请写出基于对分查找的插入排序算法并给出其时间复杂度分析。 2.算法设计:将教案给出的非递归直接插入排序和冒泡排序算法用递归算法实现。 3.算法设计:带附加头结点单链表将各数据结点按关键字升序连接。 4.编程题:键盘输入n个无符号整数,用链式基数排序实现由小到大排序,输出排序结果。 提示:对于C语言32bit宽的unsigned类型,可以采用16进制形式来实现基数排序,即32bit共有8个16进制位,每个16进制位进行一趟分配和收集,共8趟。
西南交大;西南交通大学;数据结构;赵宏宇;一、查找 1. 算法设计题 :已知n元顺序表a0, a1, … , an-1按关键字递增有序存储。给定关键字值key,编写算法用对分查找求下标i,满足ai-1<key且aikey。 2. 编程题:输入n个两两互不相等的整数,以这些整数为关键字建立平衡的二叉排序树。判断该二叉树是否为平衡的,输出判断结果;输出该二叉树的中序遍历关键字访问次序。 3. 从空起连续插入以下20个关键字构建m=4的B-。 50, 15, 09, 18, 03, 85, 33, 72, 48, 22, 91, 88, 11, 99, 06, 56, 68, 77, 43, 36。 4. 16个关键字组成的5阶B-如下图所示,请按关键 字递减的次序删除所有结点至空,画出每删除1个关键字后得到B-,直至空。 5. 12个关键字如本电子教案例1所示,设H(K)=K mod 13,地址空间范围0~15,用二次探测再散列解决冲突。画出哈希表;若各元素等概率查找,求成功查找时的平均查找长度。 二、 内部排序 1. 算法设计与分析题:将直接插入排序的内循环改造为使用对分查找实现元素插入,请写出基于对分查找的插入排序算法并给出其时间复杂度分析。 2. 算法设计:将教案给出的非递归直接插入排序和冒泡排序算法用递归算法实现。 3. 算法设计:带附加头结点单链表将各数据结点按关键字升序连接。 4. 编程题:键盘输入n个无符号整数,用链式基数排序实现由小到大排序,输出排序结果。 提示:对于C语言32bit宽的unsigned类型,可以采用16进制形式来实现基数排序,即32bit共有8个16进制位,每个16进制位进行一趟分配和收集,共8趟。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值