排序模板

      简单地复习一下排序,虽然说常用的只有几种但还是把所有的排序都复习一下,所有算法的存在都有它的理由,也都承载着许多人的智慧,再理解一遍对OI的学习或许有一些启发作用。

pascal模板

冒泡排序

      最早学习的就是冒泡学习,原理最简单,当然速度也是最慢的,不过在一些特殊的题型中会有一些独有的作用,首先,是它的交换原理的应用,比如一些只能左右交换的数据就只可以用冒泡排序,题目就像熟知的车厢重组求步数,是非冒泡排序不可的。在冒泡的过程中,一定要注意记录当前循环是否发生交换,如果无则结束,也算一个剪枝吧:

i:=1

 repeat

   bo:=true;

   for  j:=1 to n-i do

   if a[j]<a[j+1] then

   begin

     t:=a[i];  a[i]:=a[j];  a[j]:=t;

     bo:=false;

   end;  

   inc(i);

 until bo; 

快速排序

      快排是最常用的一种算法,要掌握多关键字的快排和有主次之分的快排,用random来防止排序退化,然后注意一些小技巧即可。注意主程序里的randomize不要忘记:

procedure qsort(l,r:longint);

var

  i,j,k,mid:longint;

begin

  i:=l; j:=r;

  mid:=a[l+random(r-l+1)];

  repeat

    while a[i]<mid do inc(i);

    while a[j]>mid do dec(j);

    if i<=j then

    begin

      k:=a[i];

      a[i]:=a[j];

      a[j]:=k;

      inc(i); dec(j);

    end;

  until i>j;

  if i<r then qsort(i,r);

  if l<j then qsort(l,j);

end;

桶排序

      从原理上来说,桶排序是最快的一种排序,但是由于其内存开销太大了,所以从实用性上比较起来是比较弱的,但是这种思想还是很重要的,当然,数据规模不大时,桶排序还是很实用的。 

For i:=1 to m do b[i]:=0;   //m是数据范围

  For i:=1 to n do

  Begin

      Read(k);

      B[k]:=b[k]+1;

  End;

For i:=1 to m do

While b[i]>0 do begin

    Write(I,’ ‘);

    Dec(b[i]);

End;

插入排序

      这是一种比较慢的方法,主要思想是设置一个负无穷大的数,不断插入新的数,将后面的数后移一位,开始学习的时候受书上的误导,在原数组上操作,导致每插入一个数整个数组后移,奇慢,唉,尽信书不如无书啊,不过这个算法代码没多少复习必要,思想温习一下即可。还有熟练这种思想在有序链表上的运用,在hash表上还是比较常用的。

归并排序

      将多路有序数列合并,主要是比较麻烦,如果要可排序的话,可并堆会更优秀一些,但是这毕竟也可以和快排相媲美了

Procedure mergerort(s,t:longint);

Var

  M,I,j,k:longint;

Begin

  If s=t then exit;

  M:=(s+t)>>1;

  Mergesort(s,m);

  Mergesort(m+1,t);

  I:=s;

  J:=m+1;

  K:=s;

  While (i<=m)and(j<=t) do

  Begin

    If a[i]<a[j] then

       Begin

          R[k]:=a[i];

          Inc(i); inc(k);

       End

       Else begin

         R[k]:=a[j];

         Inc(j);

          Inc(k);

      End;

      While i<m do

      begin

         r[k]:=a[i]; inc(i); inc(k); 

      end;

      while j<=t do

      begin

        r[k]:=a[j]; inc(j); inc(k);

      end;

  for i:=s to t do

  remove(r[i],a[i],sizeof(r[i]));

end; 

基数排序

      基数排序比桶排略慢,但是内存消耗却比桶排序要节省许多,就是字符串处理比较麻烦,不过,也不失为一种比较好的算法:

var

  max,i,j,k,m,n:longint;

  x:array['0'..'9',1..100000] of ansistring;

  a:array[1..100000] of ansistring;

  l:array['0'..'9'] of longint;

  c:char;



begin

  readln(n);

  for i:=1 to n do

  begin

    readln(a[i]);

    if length(a[i])>max then max:=length(a[i]);

  end;

  for i:=1 to n do

  while length(a[i])<max do a[i]:='0'+a[i];

  for j:=max downto 1 do

  begin

    for c:='0' to '9' do l[c]:=0;

    for i:=1 to n do

    begin

      inc(l[a[i][j]]);

      x[a[i][j],l[a[i][j]]]:=a[i];

    end;

    m:=0;

    for c:='0' to '9' do

    for i:=1 to l[c] do

    begin

      inc(m);

      a[m]:=x[c,i];

    end;

  end;

  for i:=1 to n do

  begin

    for j:=1 to length(a[i]) do

    if a[i][j]<>'0' then

    begin

      for k:=j to length(a[i]) do

      write(a[i][k]);

      writeln;

      break;

    end;

  end;

end.

      单纯排序的似乎没有什么特别难的题目,但是经过组合,许多时候,巧妙地运用排序,比如优化二分或是优化搜索,可以提高程序效率,蒽,就这样吧,好好理解一下。

你可能感兴趣的:(排序)