zoukankan      html  css  js  c++  java
  • 算法导论6.58习题解答(最小堆K路合并)

    CLRS 6.5-8 原题为:请给出一个时间为O(nlgk)、用来将k个已排序链表合并为一个排序链表的算法。此处n为所有输入链表中元素的总数。(提示:用一个最小堆来做k路合并)。

          算法思想:
    1. 从k个链表中取出每个链表的第一个元素,组成一个大小为k的数组arr,然后将数组arr转换为最小堆,那么arr[0]就为最小元素了
    2. 取出arr[0],将其放到新的链表中,然后将arr[0]元素在原链表中的下一个元素补到arr[0]处,即arr[0].next,如果 arr[0].next为空,即它所在的链表的元素已经取完了,那么将堆的最后一个元素补到arr[0]处,堆的大小自动减一,循环n-k次即可。

          为了方便粘贴,把.h和.cpp都弄在一起,首先是两个类List和Node,然后就是两个关于最小堆操作的函数,代码有点长,但是一点都不难,因为你肯定看过最大堆的操作,那么最小堆就大同小异了:

    #include <iostream>
    using namespace std;

    class Node
    {
    public:
      Node
    * next;
      int data;

      Node();
      Node(
    int d);

      operator Node() const;
      //只需用到"<"号
      bool operator < (const Node& temp);
    };

    class List
    {
    public:
      Node
    * first;

      List();
      void insert(int d);
    };

    //修正i的位置,在此处已经假设i的子节点都是堆
    void min_heapify(Node*&a, int i, int length);
    //建立数组的堆
    void build_min_heap(Node*&a, int length);

    int main()
    {
      int K =5;
      List
    * list_one =new List();
      List
    * list_two =new List();
      List
    * list_three =new List();
      List
    * list_four =new List();
      List
    * list_five =new List();

      for(int i =0; i <5; i++)
      {
        list_one
    ->insert(i);
        list_two
    ->insert(i -3);
        list_three
    ->insert(i +5);
        list_four
    ->insert(2*i);
        list_five
    ->insert(i -10);
      }

      Node
    * arr =new Node[K];
      arr[
    0] =*(list_one->first);
      arr[
    1] =*(list_two->first);
      arr[
    2] =*(list_three->first);
      arr[
    3] =*(list_four->first);
      arr[
    4] =*(list_five->first);

      //先对这K个排序
      build_min_heap(arr, K);

      List
    * list =new List();

      //每次取arr[0]的下一个Node,如果Node为空的话,
      //则把堆末尾的元素补到arr[0],由于有--K,所以堆的大小减一
      while(K >0)
      {
        list
    ->insert(arr[0].data);
        if(arr[0].next != NULL)
          arr[
    0] =*(arr[0].next);
        else
          arr[
    0] = arr[--K];
        min_heapify(arr,
    0, K);
      }
      Node
    * begin = list->first;

      while(begin != NULL)
      {
        cout
    <<begin->data<<endl;
        begin
    = begin->next;
      }
      return 0;
    }

    void min_heapify(Node*&a, int i, int length)
    {
      int smallest = i;

      while(smallest <= length -1)
      {
        int left =2*smallest +1;
        int right =2*smallest +2;
        int temp = smallest;
        if(left <= length -1&& a[left] < a[smallest])
        {
          smallest
    = left;
        }

        if(right <= length -1&& a[right] < a[smallest])
        {
          smallest
    = right;
        }

        if(smallest != temp)
        {
          Node exchange
    = a[smallest];
          a[smallest]
    = a[temp];
          a[temp]
    = exchange;
        }
        else
          break;
      }
    }

    void build_min_heap(Node*&a, int length)
    {
      int root = length/2-1;

      for(int i = root; i >=0; i--)
        min_heapify(a, i, length);
    }

    Node::Node()
    {
      next
    = NULL;
    }

    Node::Node(
    int d)
    {
      data
    = d;
      next
    = NULL;
    }

    Node::
    operator Node() const
    {
      return data;
    }

    bool Node::operator (const Node& temp)
    {
      if(data < temp.data)
        return true;
      return false;
    }

    List::List()
    {
      first
    = NULL;
    }

    void List::insert(int d)
    {
      Node
    * node new Node(d);

      if(first == NULL)
        first
    = node;
      else
      {
        Node
    * temp = first->next;
        Node
    * prev = first;
        while(temp != NULL)
        {
          prev
    = temp;
          temp
    = temp->next;
        }
        prev
    ->next = node;
      }
    }
    ---
    可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明
  • 相关阅读:
    SAP HANA中创建分析权限(Analytic Privilege)
    SAP HANA 中的决策表(Decision Table)
    SAP HANA procudure 创建用户
    数据挖掘与分析学习链接汇总
    Wpf 自定义窗体
    Winform里实现一个双击ListBox可以切换为TextBox编辑的效果
    一个从没见过的C# ?.语法
    VB.net怎么用Sub Main
    Office2010 帮助查看器遇到意外问题
    WcfService:单服务多契约接口以及用户名密码认证
  • 原文地址:https://www.cnblogs.com/null00/p/2065077.html
Copyright © 2011-2022 走看看