• 6.5 k个已排好序链表合并为一个排序链表


    1 建立链表(带哨兵位的)
    2 建立最小堆方法
    3 合并已排好序的k个链表

      1 typedef int DataType;
      2 //建立链表
      3 class Link
      4 {
      5 private:
      6     struct Node
      7     {
      8         DataType data;
      9         Node *next;
     10     };
     11     Node *head; //哨兵位
     12 public:
     13     Link()
     14     {
     15         Init();
     16     }
     17     ~Link()
     18     {
     19         Delete();
     20     }
     21     void Init()
     22     {
     23         head = new Node;
     24         head->next = NULL;
     25     }
     26     void Delete()
     27     {
     28         for (Node *p = head; p != NULL;)
     29         {
     30             Node *pTemp = p->next;
     31             delete p;
     32             p = pTemp;
     33         }
     34         head = NULL;
     35     }
     36     bool Empty()
     37     {
     38         return head->next == NULL;
     39     }
     40     void Print()
     41     {
     42         for (Node *p = head->next; p != NULL; p = p->next)
     43         {
     44             cout << p->data << endl;
     45         }
     46     }
     47     //顺序插入 考虑两种情况 1.空表 2.当插入值是最大值的时候
     48     void SortInsert(DataType data)
     49     {
     50         Node *p = head;
     51         do 
     52         {
     53             if (p->next == NULL || p->next->data > data)
     54             {
     55                 Node *pNew = new Node;
     56                 pNew->data = data;
     57                 pNew->next = p->next;
     58                 p->next = pNew;
     59 
     60                 return;
     61             }
     62             p = p->next;
     63         } while (true);
     64     }
     65     //使用数组初始化列表
     66     void ArrayInsert(DataType array[], int size)
     67     {
     68         for (int i=0; i<size; ++i)
     69         {
     70             SortInsert(array[i]);
     71         }
     72     }
     73     //尾插法直接插入
     74     void Insert(DataType data)
     75     {
     76         Node *p = head;
     77         while(p->next != NULL)
     78         {
     79             p = p->next;
     80         }
     81 
     82         Node *pNew = new Node;
     83         pNew->data = data;
     84         pNew->next = NULL;
     85         p->next = pNew;
     86     }
     87     //去掉首结点并返回首结点的值
     88     int ExtractDate()
     89     {
     90         if (! Empty())
     91         {
     92             DataType data = head->next->data;
     93             Node *p = head->next;
     94             Node *pFirst = p->next;
     95 
     96             delete p;
     97             p = NULL;
     98 
     99             head->next = pFirst; 
    100             return data;
    101         }
    102         return -1;
    103     }
    104     int GetData()
    105     {
    106         if (!Empty())
    107         {
    108             return head->next->data;
    109         }
    110     }
    111     bool Find(const DataType data)
    112     {
    113         for (Node *p = head->next; p != NULL; p = p->next)
    114         {
    115             if (p->data == data)
    116             {
    117                 return true;
    118             }
    119         }
    120         return false;
    121     }
    122     void Swap(Link &p)   //交换两个链表主要是交换 head
    123     {
    124         if (head != p.head)
    125         {
    126             Node *tmp = head->next;
    127             head->next = p.head->next;
    128             p.head->next = tmp;
    129         }
    130     }
    131 };
    132 //保持最小堆性质 参数inode为内部结点 注意结点从1开始,数组从0开始
    133 void MinHeapify(int array[], int size, int inode)
    134 {
    135     int least= inode;                //父结点
    136     int left = inode*2;                //左子结点
    137     int right = inode*2+1;            //右子结点
    138 
    139     if (left <= size && array[left-1] < array[least-1])
    140     {
    141         least = left;
    142     }
    143     if (right <= size && array[right-1] < array[least-1])
    144     {
    145         least = right;
    146     }
    147 
    148     if (least != inode)                    //父结点小于 左子结点 或者 右子结点
    149     {
    150         int temp = array[inode-1];            //子结点值与父结点值交换
    151         array[inode-1] = array[least-1];
    152         array[least-1] = temp;
    153 
    154         MinHeapify(array, size, least);      //再次验证被交换的值的子结点是否满足 最小堆性质
    155     }
    156 }
    157 //建立最小堆 使每一个父结点小于子结点
    158 void BuildMinHeap(int array[],int size)
    159 {
    160     for(int i=size/2; i>0; --i)     //最多有 size/2 个内部结点
    161     {
    162         MinHeapify(array, size, i);
    163     }
    164 }
    165 //k个已排好序的链表合并为一个链表
    166 //pLink 链表数组的地址, linkSize链表数组的大小, array 数组的地址, count数组的大小
    167 void SortLink(Link *pLink, int linkSize, Link *link)
    168 {
    169     int *pArray = new int[linkSize]; //动态分配k个大小的数组
    170     for (int i=0; i<linkSize; ++i)    //从k个链表中取首结点的值
    171     {
    172         pArray[i] = pLink[i].GetData();
    173     }
    174 
    175     int j=0;
    176     do 
    177     {
    178         BuildMinHeap(pArray,linkSize); //构造最小堆,即每个父结点小于或等于子结点,根结点为最小值
    179         for (j=0; j<linkSize; ++j)
    180         {
    181             if(pLink[j].Find(pArray[0]))   //寻找最小值来自于哪一个链表
    182             {
    183                 link->Insert(pLink[j].ExtractDate());  //去掉并返回链表的的值(更新链表)
    184                 break;
    185             }
    186         }
    187         if (!pLink[j].Empty())  //确保取出值的链表不为空
    188         {
    189             pArray[0] = pLink[j].GetData();   //更新数组
    190         }
    191         else 
    192         {
    193             pArray[0] = pArray[linkSize-1];  
    194             pLink[j].Swap(pLink[linkSize-1]);  //交换两个链表
    195             --linkSize;
    196         }
    197     } while (linkSize != 0);
    198 
    199     delete [] pArray;
    200 }
    201 void main()
    202 {
    203     //检测是否有内存泄露 需要加头文件#include <crtdbg.h>
    204     _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
    205 
    206     Link k[5];
    207 
    208     int Array[5][5] = { {21, 12, 11, 10, 1}, 
    209                         {22, 17, 16, 7, 2},
    210                         {23, 18, 13, 8, 3},
    211                         {24, 19, 14, 9, 4},
    212                         {25, 20, 15, 6, 5}};
    213 
    214     for (int i=0; i<5; ++i)
    215     {
    216         k[i].ArrayInsert(Array[i],sizeof(Array[i])/sizeof(Array[i][0]));
    217     }
    218     //for (int i=0; i<5; ++i)
    219     //{
    220     //    k[i].Print();
    221     //}
    222 
    223     Link link;
    224 
    225     SortLink(k, sizeof(k)/sizeof(k[0]), &link);
    226 
    227     link.Print();
    228 
    229     system("pause");
    230 }

     (转载请注明作者和出处^_*  Seven++ http://www.cnblogs.com/sevenPP/  )

  • 相关阅读:
    错误日志记录
    解决连接Oracle 11g报ORA-01034和ORA-27101的错误
    windows和linux 下将tomcat注册为服务
    ORA-12170: TNS:Connect timeout occurred
    ubuntu修改时区和时间的方法
    SecureCRT中文显示乱码的解决方法
    修復 “Failed to bring up eth0″ in Ubuntu virtualbox
    HDU 1358 Period
    rcp(插件开发)点击按钮出现 The chosen operation is not enabled 解决办法
    CRM上线之路 走上了CRM实施顾问-第12天上班 -第三周
  • 原文地址:https://www.cnblogs.com/sevenPP/p/3627368.html
Copyright © 2020-2023  润新知