Original video:

https://www.youtube.com/playlist?list=PL2_aWCzGMAwI3W_JlcBbtYTwiQSsOTa6P

Table of Contents

image-20240216163409415

image-20230525151427427

List

list在insert, remove 的时候所有的元素位置都会移动, 那么这些操作的时间复杂度就会比较高

并且数组满了, 我们都会创建一个新的更大的数组(double size), copy 原来的元素到新的数组

image-20230525151447550

image-20230525151122948

Linked list

先看看list

image-20230525152302333

首地址 : base address

现在定义一个长度为4的 int 数组, 要注意, list 的内存是contiguous的, 现在这种情况就没法extend

image-20230525152812600

那我就重新开辟一个空间, 也就是一个新的array

太小我存不下, 如果我继续存, 那就又存不下了, 怎么办呢? 用linked list

disjoint non-continuous blocks of memory, link them, so store some extra information with each block, so we have two part for each block

image-20230525152950157

linked list : 不是一个连续的list, 而是把每个元素都开辟一个空间, 然后再在后面开辟一个空间, 存下一个元素的地址

image-20230525153800746

一个node由 : int variable 和 pointer variable 组成

image-20230525153904166

image-20230525154055955

时间复杂度 time complexity O(n) big O of n

好处: no extra use of memory

Array vs linked list

cost of accessing an element

image-20230525160936243

so if you want to access elements in the list all the time, array is a better choice

memory requirements

array -fixed size

linked list

image-20230525161320112

这里算linked list占用空间的时候那个 5还没加上去, 现在加上去的话就应该是32 bytes

image-20230525161528683

cost of inserting an element

image-20230525163515341

Implement of linked list in C

这里主要讲的是singly linked list

image-20230525163939621

insert a node at the end of linked list

  1. declare a variable that will store the address of the head node
  2. 在数组里存入数据

image-20230525170537798

在c++中, 可以这么写

image-20230525170658327

再添加节点

image-20230525171616132

现在我们创建了一个新的node, 有数据, 有link( 为null), 那么如何把上一个 node 的link 指向这个新的node呢?

  • 我们需要遍历linked list, 然后找到reach the end of the list, 也就是那个link ,红色大括号就是遍历

inserting a node at beginning in linked list

主方法( 这里insert已经定义好了)

image-20230525174700918

  1. 定义insert 方法, 添加第一个元素

image-20230525173544799

​ 再添加一个元素

image-20230525174624603

  1. 接下来, 定义print方法

    image-20230525175309822

累了, 暂时不听了, 要补的后续再来补, 先听关键部分

Doubly Linked List

image-20230525180012215

假如是int, 每个node 占 12个bytes

doubly linked list implement in C

Stack

stack as abstract data type(ADT), 把stack当作抽象数据类型

logic view of stack, also called last-in-first-out(LIFO)

定义:

image-20230607110514401

operations

push(x) : 插入

pop(): remove the most recent item from the stack

top(): return the element at the top of the stack

isEmpty(): 返回boolean

​ constant time or O(1)

applications

image-20230607111116070

第三个是检查括号的匹配性, 有一个{ 有要有一个 } 来和前面那个括号匹配

infix, postfix, prefix

infix: human readable

postfix, prefix: 才是对machine最友好的, 可以节省infix的括号, 节省内存

  • infix

    image-20230607111502029

image-20230607111833306

因为it's not easy parse and evaluate an infix expression without ambigiouty

所以提出了不需要括号可以无歧义进行分析, 也无需关心操作符的优先级的方法: postfix 和 prefix

  • prefix

    image-20230607112515922

    image-20230607112732553

  • postfix

    image-20230607112633439

image-20230607112758903

Queues

把Queues当作抽象数据类型来看(ADT)

image-20230607120000116

first in first out(FIFO)

image-20230607120023598

Queue的地位, 这很重要

Java 中的 LinkedList 类实现了 Queue 接口,因此可以直接用作队列

image-20240207101558239

operations

enqueue(x) , push(x) : 插入

dequeue(), pop() : remove an element form the front head of the queue, 可以让它返回删除的元素

front(), peek() : return the element of the front

isEmpty(): 返回boolean

ifFull()

size(): 获取队列中元素的数量

image-20240207100738594

image-20230607120405198

插入和移除要从不同的sides进行

image-20230607120528136

application

有shared recourses, 先来的先得

image-20230607120727929

Trees

之前将的list, linked list, stack, queue都是linear data structure, 数据是以顺序储存起来的

怎么决定用哪种数据结构?

image-20230607121008538

nodes linked together to simulate hierarchy, non linear structure, 它是一种recursive data structure, 每一个箭头都叫做link

image-20230607121413188

image-20230607151400865

只能从1 ->2 , 不能往回走, 不能从2 -> 1

6和7是Cousins, 不是siblings

在tree中, 如果有n个节点, 那么就有n-1条边

image-20230607153043741

depth and height

image-20230607153249230

depth强调的是到这个node有多少个link(edge), 比如3的深度是1, 7的depth是2, 11的depth是3

A binary tree's maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.

height强调的是从这个node出发, 到leaf节点, 最长的路线, 所以leaf节点的height为0, 3的height是2

一个是到这个节点, 一个是从这个节点出发

Binary tree

一个node不超过两个children

一个node有三个空, 两个pointer, 一个data

image-20230607154349832

image-20230607154420576image-20230607154429384

application

image-20230607154607193

strict\proper binary tree

只能有两个或者0个children

image-20230607154935592

image-20240201151631270

complete binary tree

image-20230607154957712

image-20230607155355709

最后一个层级可以不被填满, 也可以只有单个node, 比如下图

image-20240201152008839

perfect binary tree

所有层级都被填满

image-20230607155942800

image-20230607160220130

n是 number of nodes

为什么将这个: 因为很多binary tree的操作 time consume 取决于 height

balanced binary tree

image-20230607160631204

image-20230607162707203

2这个node的左子树的高度为1(不算所说节点自身), 2这个node右子树的高度为-1(不算所说节点自身), 空的

是左子树 高度=1, 右子树为空 =-1. 所以diff才等于2

image-20240201152822070

index

image-20240201153612548

很神奇, 2* 0+1 = 1, 2 * 0+2 = 2, 所以索引为0的数字, 指向index为1和2的地方, 也就是2指向了4和1, 这正好是2的左树和右树

Binary search tree (BST)

问题: image-20240201160330945

需要search, insert, remove....

-> 我会使用array和linked list

Binary search tree就是 Binary tree的一种, 但是这个search tree 的左substree的数字比右边小

image-20230607170023271

这就是一个Binary search tree(左边tree的数字也不能大于root数字, 比如我把12换成16, 16 > 15 这就不是Binary search tree)

image-20240201165807268

为什么要用binary search tree

image-20230607165838247

为什么是logn? 因为是二分搜索, 找到中间数字, 然后只去搜索一变, 因此每次都除以2, 去一边进行搜索, k就是搜索的次数

image-20230607170833008

实现binary search three

记住: 每一个node最多有两个children

image-20240201170655921

这里的return newNode会返回data数值所对应的节点树的地址

很妙, 使用递归

下面这个方法是插入方法, 提示: 永远在root节点插入, 所以才能递归

image-20240201220222255

每次插入如果发现左(右)节点为0, 那就是null, 因此会创建一个新的地址返回来给到 左(右)节点

null is only the map macro for address 0

image-20240201221436822

image-20240201220920934

Graphs

none-linear

image-20230607174147526

image-20230607172834682

directed and undirected

image-20230607173102509

image-20230607173203508

image-20230607174007136

self-loop\multi edge

self-loop起点即终点

不含self-loop\multi edge的graph被称为simple graph

image-20230607182544383

image-20230607182528629

image-20230607182814891

image-20230607182908042

image-20230607183049406

image-20230607183141679