zoukankan      html  css  js  c++  java
  • sicilyK路归并

      1 /*
    2 K路归并排序 ,
    3 主要思想 :
    4 建立K路链表 , 在K路的最小元素提取出来 。
    5 存储到 result数组中 , 利用result数组构造最小堆 ,
    6 每次取出堆顶的元素 , 在把取出的元素的那路的next填充到堆顶中, 重新维持堆特性
    7 通过每次取出堆顶 ,知道K路链表均被取完 ,完成归并排序
    8 */
    9 #include <stdio.h>
    10 #include <algorithm>
    11 #include <memory.h>
    12
    13 using namespace std;
    14 //定义链表节点
    15 struct node
    16 {
    17 int data ; //数据
    18 node *next;
    19 node()
    20 {
    21 next = NULL;
    22 }
    23 node( int x )
    24 {
    25 data = x ;
    26 next = NULL;
    27 }
    28 bool operator<(const node& temp)
    29 {
    30 if(data < temp.data)
    31 return true;
    32 return false;
    33 }
    34 };
    35 //定义链表,对于每路定义一个链表,用链表数组lists【101】表示
    36 struct list
    37 {
    38 node *root;
    39 node *pre ;
    40 list()
    41 {
    42 root = NULL;
    43 }
    44 //链表的插入操作
    45 void insert( int d )
    46 {
    47 node* node_temp = new node(d);
    48 if(root == NULL)
    49
    50 {
    51 root = node_temp;
    52 pre = root ;
    53 }
    54 else {
    55
    56 pre->next = node_temp;
    57 pre = node_temp;
    58 }
    59 }
    60 }lists[105];
    61
    62
    63
    64 int k , n , t ; // k表示归并的路数 , n表示每路所含的数字个数 , t为测试用例个数
    65 //定义构造堆的数组result
    66 node* result = new node[105];
    67 bool cmp( node a , node b)
    68 {
    69 return ( a.data > b.data );
    70 }
    71 //保持堆特性函数,非递归写法
    72 void min_heapify(node* &a, int i, int length)
    73 {
    74 int smallest = i;
    75 while(smallest <= length - 1)
    76 {
    77 int left = 2*smallest + 1;
    78 int right = 2*smallest + 2;
    79 int temp = smallest;
    80 if(left <= length - 1 && a[left] < a[smallest])
    81 {
    82 smallest = left;
    83 }
    84 if(right <= length - 1 && a[right] < a[smallest])
    85 {
    86 smallest = right;
    87 }
    88 //最小的元素位置错误 , 交换其位置 , 使其正确
    89 if(smallest != temp)
    90 {
    91 node exchange = a[smallest];
    92 a[smallest] = a[temp];
    93 a[temp] = exchange;
    94 }
    95 else
    96 break;
    97 }
    98 }
    99
    100 //归并主要函数
    101 void merge()
    102 {
    103 //首先建堆
    104 make_heap( result , result + k , cmp );
    105
    106 while ( k > 0 )
    107 {
    108 //输出堆顶元素
    109 printf("%d " , result[0].data );
    110 //判断当前堆顶元素是否存在后续
    111 if ( result[0].next != NULL )
    112 {
    113 //若存在 , 等于后续
    114 result[0] = *(result[0].next);
    115
    116 }
    117 else
    118 {
    119 //若不存在 , 说明该路已完成归并 ,K-- , 并且 将堆的最后一个值赋给堆顶 ,减小堆的节点个数
    120 result[0] = result[--k];
    121
    122 }
    123 //保持堆特性
    124 min_heapify(result, 0 , k) ;
    125 }
    126 printf("\n");
    127 }
    128 int main()
    129 {
    130 int tep;
    131 scanf( "%d" , &t );
    132 while ( t -- )
    133 {
    134 scanf("%d%d" , &k , &n ) ;
    135 memset( lists , 0 , sizeof( lists ));
    136 for ( int i = 0 ; i < k ; i ++)
    137
    138 for ( int j = 0 ; j < n ; j++)
    139 {
    140 scanf("%d" , &tep);
    141 lists[i].insert(tep);
    142 }
    143
    144 //构造数组result
    145 for ( int i = 0 ; i < k ; i ++)
    146 {
    147
    148 result[i] =* ( lists[i].root );
    149 }
    150 merge();
    151
    152 }
    153 return 0 ;
    154 }
  • 相关阅读:
    STL源码剖析之_allocate函数
    PAT 1018. Public Bike Management
    PAT 1016. Phone Bills
    PAT 1012. The Best Rank
    PAT 1014. Waiting in Line
    PAT 1026. Table Tennis
    PAT 1017. Queueing at Bank
    STL源码剖析之list的sort函数实现
    吃到鸡蛋好吃,看看是哪只母鸡下的蛋:好用的Sqlite3
    cJSON
  • 原文地址:https://www.cnblogs.com/lzhenf/p/2288539.html
Copyright © 2011-2022 走看看