数据结构复习

数据结构

  • 优先队列:是支持插入元素和寻找最大值元素的数据结构。

    普通队列(寻找最大值时需要搜索整个队列)

    排序数组(插入运算需要移动太多元素)

    优先队列的有效实现使用了一种称为堆的简单数据结构

  • 堆运算

    • sift-up

      用于修复H [i]的键值大于其父节点键值的情况

    //输入:数组H[1...n]和和位于1和n之间的索引i
    //输出:上移H[i],以使它不大于父节点
    
    done = flase
    if i=1 then exit {节点i为根节点}
    repeat
      if key(H[i])>key(H[i/2]) 
        互换H[i]和H[i/2]
      else  done = true
      i=i/2
    until i=1 or done
    
    • sift-down

    用于修复H[i]键值小于H[2i]和H[2i+1]中的最大键值的情况

    //输入:数组H[1...n]和位于1和n之间的索引i
    //输出:下移H[i],以使它不小于子节点
    
    done = false
    if 2i>n then exit {节点i是叶节点}
    repeat
      i = 2i
      if i+1<=n and key(H[i+1])>key(H[i])
        i = i+1  {确保key(H[i])为子节点中的最大键值}
      if key(H[i])>key(H[i/2])
        互换key(H[i]) and key(H[i/2])
      else done = true
      end if
    until done or 2i>n
    
    • INSERT
      1. 先将堆的大小+1
      2. 将x添加至H的末尾
      3. 根据需要把x给sift-up,直到满足堆的特性
    //输入:堆H[1...n]和元素x
    //输出:新的堆H[1,...n+1]
    
    n = n+1 { 增加H的大小 }
    H[n]=x
    SIFT-UP(H,n)
    
    • DELETE
      1. 用H[n]替换H[i]
      2. 将堆的大小-1
      3. 根据键值大小关系进行sift-up or sift-down运算
    //输入:非空堆H[1...n]和索引i
    //输出:删除H[i]之后的新堆H[1,...n-1]
    
    x=H[i]; y=H[n]
    n=n-1  {减少H的大小}
    if i=n+1 then exit{完成}
    H[i]=y
    if key(y)>=key(x) then SIFT-UP(H,i)
    else SIFT_DOWN(H,i)
    end if
    
    • MAKEHEAP1

      从对应T中最后一个非叶子节点的数开始调整数组,即A[ n/2 ], A[ n/2 - 1 ],…A[1].

      T 的叶子节点存储在H[ n/2 +1],H[n/2 + 2]…H[n]中

    //输入:n个元素的数组A[1,...n]
    //输出:A转换成的堆
    
    for i: n/2 downto 1
      SIFT-DOWN(A,i)
    end for
    
    • HEAPSORT2
      1. 先将A变成堆
      2. 将最大值也就是A[1]和A[n]交换,使得A[n]是数组的最大元素
      3. 此时A[1]的元素可能小于子节点,于是用SIFT-DOWN将A[1,…n-1]转换成堆
      4. 将A[1]与A[n-1]交换,调整数组A[1,…,n-2]为堆
      5. 交换和调整的过程不断重复,直至堆的大小变成1,此时A[1]是最小的
    //输入:n个元素的数组A[1,...,n]
    //输出:以非降序排列的数组A
    
    MAKEHEAP(A)
    for j: n downto 2
      互换A[1] and A[n]
      SIFT-DOWN(A[1,j-1],1)
    end for
    

  1. 需要Θ( n )的时间和Θ( 1 )空间构造一个n元素的堆 ↩︎

  2. 对n个元素排序需要0(n log_n)时间和Θ( 1 )空间 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值