算法复习——堆排

来源:互联网 发布:bi数据分析工具 编辑:程序博客网 时间:2024/06/09 23:51

Long long ago,我曾经想过要写堆排(话说已经是刚开始写二分那个博客的时候了),后来好久没写,现在总算想到要写了……

好了,进入正题。

我以前曾经自己打过一个课件,现在打算放在CSDN下载那里,就当是放基础知识了,现在写写一道题的题解……

PPT网址如下(下载者先交1积分……):http://download.csdn.net/detail/u014120397/9472391

题目:codevs1245

链接:http://codevs.cn/problem/1245/

K路归并,初始化的时候把a,b数组排个序,然后把a[1]+b[1],a[2]+b[1]……a[n]+b[1]放入小根堆里面,然后每出一次堆,比如说把a[i]+b[1]出堆了,那么就把a[i]+b[2]入堆,如此操作执行n次就可以了。时间复杂度O(n log n)

代码:

type arr=array[1..100000]of longint;     ijk=record     sum,b:longint;     end;var heap:array[0..1000000]of ijk;    buf:ijk;    a,b:arr;    n,i,length:longint;procedure qs(l,r:longint;var a:arr);var i,j:longint;    x,y:longint;begin  i:=l;  j:=r;  x:=a[(l+r) shr 1];  repeat    while a[i]<x do    inc(i);    while a[j]>x do    dec(j);    if i<=j then    begin      y:=a[i];      a[i]:=a[j];      a[j]:=y;      inc(i);      dec(j);    end;  until i>j;  if l<j then qs(l,j,a);  if i<r then qs(i,r,a);end;procedure minheapify(x:longint);var min,l,r:longint;begin  l:=x shl 1;  r:=l+1;  min:=x;  if (l<=length)and(heap[l].sum<heap[min].sum) then  min:=l;  if (r<=length)and(heap[r].sum<heap[min].sum) then  min:=r;  if min<>x then  begin    heap[0]:=heap[x];    heap[x]:=heap[min];    heap[min]:=heap[0];    minheapify(min);  end;end;procedure sinkup(i:longint);var parent,tmp:longint;begin  parent:=i shr 1;  if (parent<>0)and(heap[parent].sum>heap[i].sum) then  begin    heap[0]:=heap[i];    heap[i]:=heap[parent];    heap[parent]:=heap[0];    if parent>1 then sinkup(parent);  end;end;function popheap:ijk;var min:ijk;begin  if length=0 then exit;  min:=heap[1];  heap[1]:=heap[length];  dec(length);  minheapify(1);  exit(min);end;procedure pushheap(buf:ijk);begin  inc(length);  heap[length]:=buf;  if length>1 then  sinkup(length);end;begin  readln(n);  for i:=1 to n do  read(a[i]);  for i:=1 to n do  read(b[i]);  qs(1,n,a);  qs(1,n,b);  for i:=1 to n do  begin    buf.sum:=a[i]+b[1];    buf.b:=1;    pushheap(buf);  end;  for i:=1 to n do  begin    buf:=popheap;    if i<>n then write(buf.sum,' ')else writeln(buf.sum);    if buf.b<=n then    begin      buf.sum:=buf.sum-b[buf.b]+b[buf.b+1];      inc(buf.b);      pushheap(buf);    end;  end;end.


0 0