CPT102数据结构部分

本文只梳理Lecture的大概提纲

注意

由于CPT102的内容大部分基于java实现数据结构的应用(Lec和Lab),这个帖子主要用来罗列知识点名字以及展示相关概念,java代码实现和具体内容还是需要与学校的PPT和老师给的JAVA代码配合观看。(其实就是我码不动字了)

每个ADT主要包含——ADT特征,ADT的部分方法,相关知识点
以下列出每个ADT的部分代表性方法,部分被继承的方法将不再重复列举

进度:完

正文:

数据结构大致分为线性(Linear)结构和层次(Hierarchical )结构
数据结构类型:Array, Stack, Queue, List, Set, Bag | Tree, Graph, Map, Network…
相关操作:增删查改排序…

  1. 为什么使用数据结构
  2. 什么是算法
  3. 什么是数据结构
  4. 数据结构是数据存储概念而非编程语言
  5. 静态数据结构和动态数据结构,是什么,各自的优缺点
  6. 评估各个ADT增删查改操作在空间,时间上的Cost
  7. 递归算法
  8. recursion和iteration的比较和相互转换

Java和算法

  1. Java里的抽象概念Abstraction,接口以及抽象类,Abstract Data Type抽象数据类型分别是什么,有什么不同,能否实例化instantiated
  2. 接口特征,抽象类特征
  3. 封装Encapsulation
  4. 方法头
  5. import Libraries,什么是Librariy,课程需要使用那些库util/io/swing/awt
  6. Collection类
  7. 如何创建抽象类型的实例对象
  8. 指明集合类型< E > → Collection type
  9. 迭代器 Iterator 的使用,为什么使用迭代器,
  10. List 和 array的比较,ArrayList是什么
  11. 异常Exception是什么,为什么要抛出异常,捕获异常
  12. 异常何时抛出,如何抛出异常
  13. 如何处理异常(RuntimeException和Other Exception不同的处理策略),getMessage()方法是什么
  14. 指针,地址空间及垃圾回收
  15. 黑箱测试,白箱测试(Lec12)
  16. 二分法搜索(Lec16)分治思想
  17. 给定T(n) 算O(n)
  18. 基本排序算法 (Lec17)按照效率,空间,数据要求评估不同排序算法
  19. 快速排序,选择排序,归并排序
  20. 递归实现排序算法

Iterator

迭代器,所有Collection类都可以使用迭代器

· hasNext(): 返回boolean,指针之后是否有元素
· next(): 返回指针之后的下一个元素,移动指针往后移动1个元素
· remove(): 删除上次迭代的元素(这个方法不怎么使用,但是必须要声明)

  1. 区分Iterable接口 和 Iterator接口(Lec05)

Comparable

比较器,所有Collection类都可以使用比较器

· compareTo(T ob): Comparable的接口的方法,所有继承自Comparable的对象都要实现该方法,方法代表了natural order,根据传入对象与自己的比较返回整数,自己大返回1,对面大返回-1,平手返回0

· compare(Object,Object): Comparator接口的方法,比较两个对象,<返回-1, =返回0, >返回1

  1. natural ordering是什么
  2. 区分Comparable 和 comparator
  3. Collections.sort(…, Comparator) 的使用

Collection

这里讨论java中的接口,所有其他ADT都继承于Collection
· isEmpty(): 返回是否为空
· size(): 返回已包含元素的数量
· contains(E elem): 返回是否包含某个元素
· add(E elem): 在尾部添加一个对象作为元素,返回操作状态
· remove(E elem): 移除一个元素,返回操作状态
· iterator():返回一个迭代器
· clear(): 利用迭代器清空集合
· addall(Collection): 合并两Collection
· removeAll(Collection): 移除所有位于两Collection交集里的所有元素
· containsAll(Collection): 返回是否包含这个Collection的所有元素

List

继承自Collection
List特性:没有访问限制(随机访问),允许重复
· add(index, item): 在下标处添加元素,该位置以及之后的元素后移一位,返回操作状态
· remove(index):移除下标处元素,该位置之后的元素前移一位,返回操作状态
· get(index): 返回某个元素值下标
· set(index, item): 将下标处元素替换,返回操作状态
· indexOf(item): 返回某个元素下标
· subList(int from, int to): 返回子List

AbstractList

继承自List
声明了size();get(index);等方法
定义了isEmpty();add();contains();clear()等方法

Array

特点:数组内元素有顺序,随机访问,数组长度不可变,允许重复

Bag

继承自List
Bag特性: 其内元素没有顺序,没有访问限制(随机访问),允许重复
· add(value): 添加元素,返回操作状态
· remove(value): 移除元素,返回操作状态
· contains(value): 返回是否包含该元素
· findElement(value): 返回匹配的元素

  1. 什么时候使用Bag

Set

继承自List
Set特性:其内元素没有顺序,没有访问限制(随机访问),排除重复项
· add(value): 添加元素,返回操作状态,元素重复则False
· remove(value): 移除元素,返回操作状态
· contains(value): 返回是否包含该元素
· findElement(value): 返回匹配的元素
· clear(): 清空

Stack

继承于List
Stack特性:其内元素有顺序,先进后出,后进先出,顺序访问,不排除重复项
· push(value): 将对象元素入栈,放置栈顶
· pop(): 出栈一个元素,从栈顶移除
· peel(): 不弹出栈顶元素,返回该栈顶元素

  1. Stack在HTML中的使用
  2. Stack作为栈存储程序各方法的状态
  3. Stack在递归中的使用
  4. 利用Stack判断代数表达式是否括号对称
  5. 利用Stack处理前缀Polish,中缀Infix,后缀表达式Postfix之间的转换(lec 04
  6. 利用Stack对字符逆序操作

Map

继承自List
Map特性:其内元素无顺序,无访问限制(随机访问),key不能重复,每个元素存储为(key, value)的形式。

· get(key): 返回该key对应的val
· put(key, value): 重新设定key对应的val
· remove(key): 移除key为指定key的元素
· containsKey(key)返回是否包含key为指定key的元素
· keySet(): 返回keys的Set对象
· values(): 返回vals的Collection对象
· entrySet(): 返回所有元素的Set对象

  1. 使用Map计算文档中单词使用频率(Lec05)
  2. 通过key,val,pair分别迭代Map类所有元素
  3. 使用Map表示cast表

Queue

继承自List
Queue特性:其内元素有顺序,删除操作只能在一端进行,不排除重复项
· offer(value): 添加元素进队列入端,返回操作状态,也叫做enqueue
· poll(): 移除并返回出端的一个元素,也叫做dequeue
· peek(): 不移除地返回出端元素
· remove(): 移除并返回出端的元素,当队列为空时抛出异常
· element(): 非移除地返回出端元素,当队列为空时抛出异常

  1. 哈夫曼编码Huffman coding的优先级队列应用
  2. Priority Queue是什么,如何用数组实现
  3. 使用count的queue
  4. 使用front和back指针的循环状queue
  5. 上面两者的差别

ArrayList

继承自List的类
特征:相比于数组,ArrayList可以自动扩容。
· size()
· get(index)
· set(index,value)
· remove(index):之后的元素需要前移
· add(index,value):之后的元素需要后移
· iterator()

  1. count这个变量的作用
  2. 哪些方法会涉及到扩容
  3. 如何扩容
  4. remove()方法移除元素后,之后的元素如何变动(删除原ArrayList最后一位)(Lec08)
  5. add()方法添加元素后,之后的元素如何变动 (是否扩容)(Lec08)
  6. 实现迭代器
  7. 实现迭代器的remove方法
  8. remove和next方法中canRemove变量的作用
  9. 多迭代器冲突
    10.扩容带来的时间复杂度不同

ArraySet

特征:其内元素无顺序,可以实现自动扩容,随机访问,排除重复
· contains(item):返回是否包含某元素
· add(item) :通常在尾部加入,应避免重复
· remove(item) :定位并移除指定元素,与arraylist不同的是无需将之后的元素都前移而是只把最后一位元素挪进空位

  1. contains的复杂度为n

SortedArraySet

特征:与ArraySet类似,只是元素在存储时按照排序存储,因此定位元素时可以二分查找,加快查找速度。

  1. contains的复杂度为logn
  2. Set,ArraySet,SortedArraySet之间的比较
  3. 为何ArraySet,SortedArraySet在频繁add和remove时效率差不多

Linked Node(val, nextnode):

节点类,串起来可表示链表
value记录值,next记录指针
· setNext(): 设立指针指向下一个节点

使用串联起来的LinkedNode已经可以实现链表的操作了,但是把各种操作封装起来更好一些,如下面的LinkedList

Linked List

继承于AbstractList的链表类,其内有Node私有类表示节点

特性:其内元素有顺序,每个节点会记录下一个节点的地址,形成链表,访问时必须顺序访问,元素可重复
· get(index): 返回节点值
· set(index, item): 设立节点值
· add(index, item): 添加新元素
· remove(item):删除某一元素
· remove(index): 删除下标处元素

  1. 头指针
  2. 修改或添加元素时的双指针遍历或.next.next提前遍历的原因
  3. 使用图像表示链表
  4. 使用循环创建链表
  5. 使用循环输出链表
  6. 插入删除操作(lec 13-14)

Linked Stack

特性:由链表存储的栈结构,头节点方向代表栈顶
· push(item): 元素入栈,头节点指向新元素,新元素指向原第一位元素
· pop(): 元素出栈,头节点指向原第二位元素
· peek(): 非弹出返回栈顶元素
· size(): 返回链表长度

  1. 头节点
  2. 为什么头节点方向代表栈顶,与链表尾部代表栈顶有何差别

Linked Queue

特性:由链表存储的队列结构
链表头节点可以作为队列入端,也可以作为出端,相应地,链表尾节点可以作为出端或者入端。更高效的做法是改变下链表头节点,使头节点有两指针分别指向队列入端元素和队列出端元素(学校PPT做法是头指针指向队列出端,尾指针指向队列入端)

· offer(value): 添加元素进队列入端,返回操作状态,也叫做enqueue
· poll(): 移除并返回出端的一个元素,也叫做dequeue
· peek(): 不移除地返回出端元素
·

Tables(Maps)

类似于Maps,只是一个key后面跟着许多values
· insert(key, item): 在某个key中插入val
· lookup(key): 返回key及其values
· remove(key): 移除key及其values

  1. 由链表实现Tables
  2. 由二叉树实现Tables
  3. 还可以由哈希表实现

Hash Tables

增删查时间复杂度为O(1),存在一个长为N的数组,定义一个哈希函数(Hash function), 输入任意元素值,函数将该值映射为hash值,代表表中某一位置。对于同一输入得出的哈希值是一样的。

  1. 哈希table的大小如何影响空间和时间效率
  2. 哈希值为什么需要定长
  3. 地址范围为0到容量-1
  4. 好的哈希函数应该:避免冲突;均匀分散元素;计算复杂度不能太高
  5. 字母哈希时需要注意ASCII表是从0101到0172
  6. 数字哈希Mid-square method(Lec23)
  7. 字符串哈希(4-byte看成int型,累加)Lec23
  8. 处理哈希值冲突
  9. 处理满哈希表

Tree

树由节点构成,二叉树的一个节点下可划分为左子树和右子树,节点内有key值,左指针和右指针。

  1. 哈夫曼编码Huffman coding的二叉树应用
  2. 树与线性存储结构的差别,树的优点,树的应用
  3. 平衡二叉树AVL是什么
  4. 递归树型结构Recursion tree表示递归
  5. 二叉树的前序遍历pre,中序遍历in,后序遍历post以及转换前中后缀表达式
  6. 使用队列queue实现树的层序遍历
  7. In general, 节点的子节点之间无先后之分(Binary tree has no ordering upon its sibling nodes)。但是各种应用中,也有规定子节点先后顺序的树。

BinaryTree

java实现二叉树,特点:一个节点可以有多个子节点,使用两个BinaryTree记录左右子节点
· getValue()
· getLeft(): 返回左孩子节点
· getRight(): 返回右孩子节点
· setValue()
· setLeft(tree): 设置左子树
· setRight(tree): 设置右子树
· isLeaf()
· find(val): 返回值为val的节点

  1. 使用java构造二叉树
  2. java递归前序遍历二叉树

General Tree

java实现普通树,特点:一个节点可以有多个子节点,节点记录的子节点含有顺序,使用List记录所有children
· getChildren():返回所有孩子节点
· getChild(i): 返回第i个孩子节点
· addChild(child): 往List里添加一个节点
· addChild(i,child): 在List第i个位置添加一个节点

  1. 使用java构造普通树
  2. java递归前序遍历普通树

Binary Search Trees

二叉搜索树特征:每个节点的左孩子节点值<该节点值<该节点右孩子节点值

增:从根节点开始,大于当前向左下移动,小于当前向右移动,直到底部
删:删除某一节点,将右子树的最大值填补进空缺。

  1. 增删查的平均时间复杂度为O(log N),最坏O(N)
  2. BST什么情况时间复杂度最差→退化成链表degenerative cases

Balanced Search Trees

平衡搜索树特点:每个节点的左孩子节点值<该节点值<该节点右孩子节点值且任意节点的左子树深度和右子树深度相差≤1

  1. 增删查的最坏时间复杂度为O(log N)
  2. 什么是AVL Trees(自平衡二叉搜索树)
  3. 为什么需要旋转操作
  4. 旋转rotation操作的实现(Lec21)
  5. 插入元素后的AVL自平衡操作

Graph

特点:由点V和边E组成,

  1. 点与点的邻接adjacent以及点与边的关联incident

  2. simple graph简单图点点间只连一线且没有loop

  3. 度序列非负非升序

  4. 加权图weighted graph

  5. 有向图digraph,出度入度

  6. subgraphs和点集相同的特殊子图:spanning subgraph

  7. 邻接矩阵adjacency和关联矩阵incidence

  8. walk点到点路径,trail点到点的路径且边不重复,path点到点的路径且边和点都不重复

  9. 连通与非连通

  10. Tree是没有回环的连通图

    1. 图的生成树,最小生成树
    2. 贪婪算法生成最小生成树(Lec26)
    3. 求两节点间最短路径(Lec27)(Dijkstra’s algorithm)

一些补充:

Lec04(前中后缀表达式转换,单栈single,双栈dual):

前缀profix:操作符在前,+ab
中缀infix:操作符在中,a+b
后缀postfix:操作符在后,ab+,主要是后缀

操作符优先级配对半括号^ > × / > + - >首次出现的半括号

中缀转后缀
从左到右扫描中缀表达式,维护操作符栈

  1. 遇到操作数, 直接输出

  2. 遇到操作符后, 如果操作符堆栈为空, 则直接压入操作符,
    如果操作符堆栈非空,判断当前操作符与栈顶操作符的优先关系, 假如栈顶操作符的优先级当前操作符的优先级, 那么弹出栈顶操作符直到栈顶操作符优先级当前操作符优先级. 最后将当前操作符入栈

  3. 如果遇到左括号,直接入栈

  4. 如果遇到右括号, 那么将栈顶操作符弹出, 持续弹出直到遇到匹配的左括号, 左括号弹出但不输出

  5. 表达式读入完毕, 若栈不为空, 则持续弹出栈顶操作符, 直到栈为空

中缀转前缀
从右到左扫描中缀表达式,维护操作符栈

  1. 遇到操作数, 直接输出

  2. 遇到操作符后, 如果操作符堆栈为空, 则直接压入操作符,
    如果操作符堆栈非空,判断当前操作符与栈顶操作符的优先关系, 假如栈顶操作符的优先级当前操作符的优先级, 那么弹出栈顶操作符直到栈顶操作符优先级当前操作符优先级. 最后将当前操作符入栈

  3. 如果遇到右括号,直接入栈

  4. 如果遇到左括号, 那么将栈顶操作符弹出, 持续弹出直到遇到匹配的左括号, 左括号弹出但不输出

  5. 表达式读入完毕, 若栈不为空, 则持续弹出栈顶操作符, 直到栈为空

  6. 反转输出字符串

计算evaluate后缀表达式postfix
从左到右扫描后缀表达式,维护操作数栈

  1. 扫描到数字,入栈
  2. 扫描到操作符,依次出栈两数字,先出栈的作为操作符后数字,后出栈的作为操作符前数字,计算结果并把数字入栈

计算evaluate前缀表达式profix
从右到左扫描后缀表达式,维护操作数栈

  1. 扫描到数字,入栈
  2. 扫描到操作符,依次出栈两数字,先出栈的作为操作符前数字,后出栈的作为操作符后数字,计算结果并把数字入栈

用双栈计算evaluate中缀表达式infix
维护操作符栈和操作数栈,从左到右扫描中缀表达式。

  1. 扫描到数字,入操作数栈
  2. 扫描到操作符,按照中缀转后缀表达式的规则压入操作符栈
  3. 如果上一步pop出来了操作符,那么对于被pop出来的操作符,依次pop操作数,数字从后向前交叉操作符,计算结果再入栈
  4. 如果中缀表达式扫描结束后,操作符栈非空,继续按照以上规则pop操作符计算

Lec06(迭代器,比较器):

继承自Iterator的类是个迭代器,其作用是迭代该迭代器属于的对象内元素,需要实现next()和hasNext(), remove()方法
Iterable是可迭代声明,继承自Iterable的类可以迭代,该类应该实现一个叫 iterator() 的公开方法,这个方法会返回一个迭代此类的迭代器,属于该类的迭代器的类代码位于该类的内部,并且是私有的。

继承自Comparator的类是个比较器,其内需要实现compare(E a, E b)方法,该方法作用是比较传入的a, b对象。
Comparable是可比较对象声明,继承自Comparable的类可以被比较以及排序,该类应该直接实现一个叫compareTo(Object)的方法,该方法将这个类对象与传入对象比较。compareTo()定义的比较方式代表了该类的自然顺序,如果默认调用Collection.sort()的话会按照自然顺序进行排序。当然也可以创建一个比较器,然后将比较器传入sort(),sort()就会按照比较器规定的比较方式进行排序。

Lec13,14(对链表的删除操作的实现步骤):

Leetcode-删除链表的节点
假设链表头节点指针为data,链表长度记录为count删除成功返回True,无需删除或出问题返回False
遍历链表删除节点

  1. 如果想要删除的元素为null或链表无链表头节点则返回False
  2. 如果头节点与预删除元素值相同,将头节点指针指向next,链表长度count-=1,返回True
  3. 否则,链表往后查找与预删除元素值相同的节点,(实际遍历的是与预删除元素值相同的节点的前一个节点):
    1. 创建一个临时的链表头节点指针node
      2.1. 如果node指向的当前节点有后续节点以及下个节点值不等于预删除值,循环node=node.next
    2. 退出循环时如果为尾节点,返回False
    3. 退出循环时如果是中间节点,代表后续节点既是目标节点,将node.next更新为node.next.next,删除目标节点,count-=1,返回True

Lec16 (给定T(n) 算O(n) ):

题干:
在这里插入图片描述
解题: 根据T(n)递推公式,
T(n)=2T(n/2)+n ········等号右边的式子根据Guess的式子(括号里变成n/2),放缩至
T(n)≤nlog(n/2)+n ········再把log括号里的除二提出来
T(n)≤n(logn-log2)+n ········因为log2=1
T(n)≤nlogn-n+n ········加n减n相消,得证

Lec 21(二叉树左旋LL右旋RR左右旋LR右左旋RL

旋转

  • 24
    点赞
  • 99
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值