cs61b数据结构与算法笔记 10,11 二叉搜索树

ADT(Abstract Data Type)

抽象数据结构只定义操作,不定义具体实现。抽象数据类型的定义仅仅取决于它的一组逻辑特性,而与它在计算机中的表示和实现无关。例如,大一C语言里实现过的学生管理系统里,我们就定义了一个抽象数据类型student,它封装了姓名,学号,成绩三个不同类型的变量。

Stack

栈也可以看成是一种抽象数据结构,经典的五个操作init push pop top destroy,可能还有isEmpty之类的。

stack的具体实现:采用链表或可变长数组

GrabBag

四个操作:insert(int x); remove; sample; size(int i)

在remove实现中,明显用数组更快。只需要把要remove的元素和最后一个元素交换,然后把数组的长度减少1即可。如果用链表就要一个一个遍历,浪费时间。

java中的接口并不是绝对抽象的。因为可能包含一些实现的细节,如初始方法。

Map

图在图论中已经进行过深入研究。

Java Libraries

java已经提供了很多内置包。如utils.

Binary Search Trees(二叉搜索树)

链表中搜索一个项目需要很长时间。在二进制搜索中,由于列表是排序的,因此我们只需要二分法搜素就能很快找到元素。但如何对链表进行二进制搜索呢?我们必须一直遍历到中间位置,才能检查那里的元素,而这本身就需要线性时间!

我们可以实现的一种优化方法是对中间节点进行引用,这样二分的时候速度就升高了一些,平均搜索时间减少了一半。

如图,sentinel节点指向中点,指针往两端指。

我们可以递归地重复这一步,直到把一个链表变成一个二叉树。

形式上成为了二叉树,遍历任何一个节点的步数不会大于树的高度

定义

树:两个节点之间只能有一条路。

二叉搜索树里,我们让每个节点的左子节点小于该节点,右节点大于该节点。

不能有大小完全相同的节点。

操作

查找

  • 从根节点开始,如果目标等于当前节点,则return;
  • 小于当前节点,则左移;
  • 大于当前节点,则右移。

本质上等同于二分法,而且操作简单。用时减少到logN。

插入

总是向最下面插入叶子。首先,我们在树中搜索节点。如果找到了,就什么也不用做。如果没有找到,我们就已经在叶子节点上了。此时,我们可以将新元素添加到叶子节点的左侧或右侧,同时保留 BST 属性。

static BST insert(BST T, Key ik) {
  if (T == null)
    return new BST(ik);
  if (ik ≺ T.key)
    T.left = insert(T.left, ik);
  else if (ik ≻ T.key)
    T.right = insert(T.right, ik);
  return T;
}

删除

删除操作面临三种不同的情况:没有子节点、有一个子节点、两个子节点。

没有子节点很简单。

一个子结点:让要删除的节点的父节点指向要删除节点的子节点。

二个子节点:这种情况是比较复杂的,为了不破坏二叉查找书的结构,我们可以按照以下操作进行:

  • 找出左子树中最大或者右子树中最小的值val
  • 将当前节点的值替换为val
  • 在左子树或者右子树中找到val删除

11.1 平衡搜索树(Balanced Search Trees)

BST Tree Height

最好的情况(完全树)Θ(log N)

最坏的情况(一条线) Θ(N)

大O代表小于等于,所以大O可能是不精确的。大Θ是精确的。

Height and Depth

节点深度指它离根节点多远。

树的高度指它最深的叶子节点的高度。

平均高度指树的节点的平均深度。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值