栈:
后进先出
数组实现
从索引1开始存储数据, 当S.top存储指向最新插入的元素(下标),当栈为空时S.top指向0(下标)
STACK-EMPTY(S) if S.top == 0 return TRUE else return FALSE PUSH(S, x) S.top = S.top + 1 S[S.top] = x POP(S) if STACK-EMPTY(S) error "underflow" else S.top = S.top - 1 return S[S.top + 1]
队列:
先进先出
Q.tail 指向队列的下一个新元素将要插入的位置(下标)
Q.head 指向对头元素位置(下标)
环绕: 到达数组末端后,下一个位置就是1
Q.head == Q.tail 时,队列为空, 此时出队会发生下溢
Q.head == (Q.tail + 1) % n 时,队列为满, 此时入队会发生上溢
Q[1..n] 最多容纳 n - 1个元素
// 这里省略了上溢和下溢的检查 ENQUEUE(Q, x) Q[Q.tail] = x if[Q.tail] == Q.length Q.tail = 1 else Q.tail = Q.tail + 1 DEQUEUE(Q) x = Q[Q.head] if Q.head == Q.length Q.head = 1 else Q.head = Q.head + 1 return x
链表:
各对象按线性顺序排列,链表的顺序是由各个对象的指针决定的
可有多种形式,单链接的或双链接的,已排序的或未排序的,循环的或非循环的。
L.head 指向链表的第一个元素,如果L.head == Nil, 则链表为空
psudo code
LIST-SEARCH(L, k) x = L.head while x != Nil && x.key != k x = x.next return x LIST-INSERT(L, x) x.next = L.head if L.head != Nil L.head.prev = x L.head = x x.prev = Nil LIST-DELETE(L, x) if x.prev != Nil x.prev.next = x.next else L.head = x.next if x.next != Nil x.next.prev = x.prev
reverse doubly linked list
def list_reverse(l): h = l l = l.next h.next = None while l != None: x = l l = l.next x.next = h h.prev = x h = x h.prev = None return h class Node: def __init__(self, val) self.val, self.pre, self.next = val, None, None
有根数的表示:
1. 二叉树:T.root根节点, p, left 和right 存放指向父节点, 左孩子和右孩子的指针。
2. k分支的有根数,类似于二叉树,仅将left, right换为 child1 c h i l d 1 , child2 c h i l d 2 ….
3. 分支无限制的有根数:T.root, p, left-child(指向最左边孩子的结点), right-sibling(指向右侧相邻兄弟的结点)
4. 完全二叉树: 可使用堆来表示, 堆用一个数组加上堆最末结点的下标来表示。
5. 只需向根节点方向遍历的数: 只需指向父节点的指针,而没有子节点的指针
…
结点的深度和高度:Refer to What is the difference between tree depth and height?
I learned that depth and height are properties of a node:
The depth of a node is the number of edges from the node to the tree’s root node.
A root node will have a depth of 0.The height of a node is the number of edges on the longest path from the node to a leaf.
A leaf node will have a height of 0.Properties of a tree:
The height of a tree would be the height of its root node,
or equivalently, the depth of its deepest node.The diameter (or width) of a tree is the number of nodes on the longest path between any two leaf nodes. The tree below has a diameter of 6 nodes.
搜索树:
搜索树数据结构支持许多动态集合的操作,包括SEARCH, MINIMUM, MAXIMUM, PREDECESSOR, SUCCESSOR,INSERT和DELETE等。
- 二叉搜索树:以二叉树来组织,如果某个孩子结点或父节点(根节点)则相应的属性值为NIL。左子树的关键字 <=父节点关键字<=右子树关键字。在一棵高度为h的二叉搜索树上,动态集合上的操作SEARCH, MINIMUM, MAXIMUM, SUCCESSOR, PREDECESSOR, INSERT 和 DELETE可以在 O(h) O ( h ) 时间内完成。
INORDER-TREE-WALK(x) // 中序遍历 if x != NIL INORDER-TREE-WALK(x.left) print x.key INORDER-TREE-WALK(x.right) TREE-SEARCH(x, k) if x == NIL or k == x.key return x if k < x.key return TREE-SEARCH(x.left, k) else return TREE-SEARCH(x.right, k) ITERATIVE-TREE-SEARCH(x, k) while x != NIL and k != x.key if k < x.key x = x.left else x = x.right return x TREE-MINIMUM(x) while x.left != NIL x = x.left return x TREE-MAXIMUM(x) while x.right != NIL x = x.right return x TREE-SUCCESSOR(x) if x.right != NIL return TREE-MINIMUM(x.right) y = x.p while y != NIL and x == y.right x = y y = y.p return y TREE-PREDECESSOR(x) if x.left != NIL return TREE-MAXIMUM(x.left) y = x.p while y != NIL and x == y.left x = y y = y.p return y TREE-INSERT(T, z) y = NIL x = T.root while(x != NIL) y = x if z.key < x.key x = x.left else x = x.right z.p = y if y == NIL T.root = z // tree I was empty else if z.key < y.key y.left = z else y.right = z TRANSPLANT(T, u, v) if u.p == NIL T.root = v elseif u == u.p.left u.p.left = v else u.p.right = v if v != NIL v.p = u.p TREE-DELETE(T, z) if z.left == NIL TRANSPLANT(T, z ,z.right) elseif z.right == NIL TRANSPLANT(T, z, z.left) else y = TREE-MINIMUM(z.right) if y.p != z TRANSPLANT(T, y, y.right) y.right = z.right y.right.p = y TRANSPLANT(T, z, y) y.left = z.left y.left.p = y
LEFT-ROTATE(T, x) y = x.right // set y x.right = y.left // turn y's left subtree into x's right subtree if y.left != T.nil y.left.p = x y.p = x.p // link x's parent to y if x.p == T.nil T.root = y elseif x == x.p.left x.p.left = y else x.p.right = y y.left = x // put x on y's left x.p = y
从左到右 RIGHT-ROTATE(T, y), 从右到左 LEFT-ROTATE(T, x) RIGHT-ROTATE(T, y) 以y为pivot, 左孩子向右旋转, 使左孩子成为该子树的根节点 LEFT-ROTATE(T, x) 以x为pivot,右孩子向左旋转,使右孩子成为该子树的根节点 | | y x / \ / \ x r a y / \ / \ a b b r
RIGHT-ROTATE(T, y) x = y.left y.left = x.right if x.right != T.nil r.right.p = x x.p = y.p if y.p == T.nil T.root = x else if y == y.p.right y.p.right = x else y.p.left = x x.right = y y.p = x