数据结构基础

逻辑结构

  • 线性结构:元素关系是一对一
  • 树结构:一对多
  • 图结构:多对多 

物理结构

  • 顺序存储:连续的内存
    • 数组(c++)
      • 数组元素类型要一样
      • 数据长度固定
    • 列表(Python)
      • 列表元素可以不一样,但存储元素地址(32位机器:一个地址4个字节)
      • 查询列表元素时,实际上是通过地址查找具体元素
      • 插入和删除都是O(n)操作
      • 是一个数据集合,只能在一端进行插入或删除的列表
      • 特点:LIFO(last-in, first-out)
      • 操作:进栈li.append(),出栈 li.pop(),取栈顶 li[-1]
      • 栈的应用:括号匹配
      • class Stack:
            def __init__(self):
                self.stack = []
        
            def push(self, n):
                self.stack.append(n)
        
            def pop(self):
                return self.stack.pop()
        
            def gettop(self):
                if self.stack:
                    return self.stack[-1]
                else:
                    return None
    • 队列

      • 数据集合,仅允许一端插入,另一端删除

      • 插入端为队尾(rear),插入称为进队或入队

      • 删除端为队头(front),删除称为出队

      • 队列特点:先进先出(First-in,First-out)

      • 队列的实现方式:环形队列

        • 当指针front (或rear) == Maxsize + 1时,再进一位,自动指向0

        • 队首指针前进1:front = (front + 1) % MaxSize

        • 队尾指针前进1:rear = (rear + 1) % MaxSize

        • 队空条件:rear == front

        • 队满条件:(rear + 1) % MaxSize == front

      • Python的内置队列模块

        • import queue 单向队列

        • from collections import deque  双向队列

          • q = deque(li, size)   ## li 初始化队列元素,size最大长度

          • 正向进队:append()      出队:popleft()

          • 反向进队:appendleft()       出队:pop()

    • 哈希表

      • 由一个直接寻址表和一个哈希函数组成。

      • 哈希函数h(k)将元素关键字作为自变量,返回元素的存储下标。

      • 哈希冲突:哈希表大小有限,存储的数量无限,因此总有两个元素映射到同一个位置上。

      • 开放寻址法:

      • 拉链法:

      • 哈希表应用:字典和集合、MD5算法/SHA2算法(密码)

  • 链式存储

    • 链表

      • 一系列节点组成的元素集合。

      • 两部分:数据域和指针next

    • 创建链表

      • 头插法:head = Node(1); node.next = head; head = node

      • 尾插法:head = Node(1); tail = head; tail.next = node; tail = node

      • 插入

      • 删除

    • 双链表

      • 三部分:前节点指针prior,item,后节点指针next

    • 链表总结

      • 优点:插入和删除操作O(1);内存分配灵活;链式存储对数和图结构有很大启发

      • n个节点的集合

      • 二叉树:每个节点的度为2(2个分叉)

      • class BiTreeNode:
            def __init__(self, data):
                self.data = data
                self.lchild = None
                self.rchild = None

      • 二叉树遍历方式

        • 前序遍历:“根左右”

        • def preorder(root):
              if root:
                  print(root.data, end=',')
                  preorder(root.lchild)
                  preorder(root.rchild)

        • 中序遍历:“左根右”

        • 后序遍历:“左右根”

        • 层次遍历:一层一层

        • from collections import deque
          
          def level_order(root):
              q = deque()
              q.append(root)
              while len(q) > 0:
                  node = q.popleft()
                  print(node.data, end=',')
                  if node.lchild:
                      q.append(q.lchild)
                  if node.rchild:
                      q.append(q.rchild)
      • 二叉搜索树bst

        • 性质:lchild.key <= root.key,  rchild.key >= root.key

        • 查询、删除、插入

        • class BitreeNode:
              def __init__(self, data):
                  self.data = data
                  self.lchild = None
                  self.rchild = None
                  self.parent = None
          
          class BST:
              def __init__(self, li=None):
                  self.root = None
                  if li:
                      for val in li:
                          self.insert_no_rec(val)
          
              def insert(self, node, val):
                  if not node:
                      node = BiTreeNode(val)
                  if val < node.data:
                      node.lchild = self.insert(node.lchild, val)
                      node.lchild.parent = node
                  elif val > node.data:
                      node.rchild = self.insert(node.rchild, val)
                      node.rchild.parent = node
                  return node
          
              def insert_no_rec(self, val):
                  p = self.root
                  if not p:
                      self.root = BiTreeNode(val)
                      return
                  while True:
                      if val < p.data:
                          if p.lchild:
                              p = p.lchild
                          else:
                              p.lchild = BiTreeNode(val)
                              p.lchild.parent = p
                              return
                      elif val > p.data:
                          if p.rchild:
                              p = p.rchild
                          else:
                              p.rchild= BiTreeNode(val)
                              p.rchild.parent = p
                              return
                      else:
                          return
                  
              def pre_order(self, root):
                  if root:
                      print(root.data, end=',')
                      self.pre_order(root.lchild)
                      self.pre_order(root.rlchild)
          
              def in_order(self, root):
                  if root:
                      self.pre_order(root.lchild)
                      print(root.data, end=',')
                      self.pre_order(root.rlchild)
          
              def post_order(self, root):
                  if root:
                      self.pre_order(root.lchild)
                      self.pre_order(root.rlchild)
                      print(root.data, end=',')
          
          if __name__ == "__main__":
              bst = BST([4,6,2,3,1,8,7,9,5])
              bst.pre_order(bst.root)
              print()
              bst.in_order(bst.root)
              print()
              bst.post_order(bst.root)
      • AVL树

        • 自平衡的二叉搜索树

        • 性质:

          • 根的左右子树高度差绝对值不能超过1(平衡要求苛刻);

          • 左右子树都是平衡二叉树

        • 插入O(logn):可能导致不平衡,四种情况

          • 右孩子的右子树插入:左旋

          • 左孩子的左子树插入:右旋

          • 左孩子的右子树插入:左旋 + 右旋

          • 右孩子的左子树插入:右旋 + 左旋

      • 红黑树

        • 一种特殊的自平衡二叉搜索树

        • 查找和插入O(logn)

        • 四条性质:(平衡要求宽松(相对AVL树而言))

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值