zoukankan      html  css  js  c++  java
  • 排序模板

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

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

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

  • 相关阅读:
    【故障处理】ORA-12162: TNS:net service name is incorrectly specified (转)
    android studio 编程中用到的快捷键
    java时间格式串
    android Error occurred during initialization of VM Could not reserve enough space for object heap Could not create the Java virtual machine.
    linux安装vmware
    x1c 2017 安装mint18的坑——grub2
    x1c2017 8G版 win linux的取舍纠结记录
    python的try finally (还真不简单)
    kafka+docker+python
    json文件不能有注释
  • 原文地址:https://www.cnblogs.com/forever97/p/3427594.html
Copyright © 2011-2022 走看看