• 排序模板


          简单地复习一下排序,虽然说常用的只有几种但还是把所有的排序都复习一下,所有算法的存在都有它的理由,也都承载着许多人的智慧,再理解一遍对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.

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

    愿你出走半生,归来仍是少年

  • 相关阅读:
    Hadoop2.2.0 注意事项
    为一个表增加一列,这个列能够自增加1
    商品推荐系统问题
    Android Service服务-(转)
    android实现通知栏消息
    【Android】状态栏通知Notification、NotificationManager详解(转)
    android调用邮件应用发送email
    有关WebView开发问题(转)
    Android开发把项目打包成apk-(转)
    对话框(单选)
  • 原文地址:https://www.cnblogs.com/forever97/p/3427594.html
Copyright © 2020-2023  润新知