E81086713E446D36F62B2AA2A3502B5EB155

          Java雜家

          雜七雜八。。。一家之言

          BlogJava 首頁 新隨筆 聯(lián)系 聚合 管理
            40 Posts :: 1 Stories :: 174 Comments :: 0 Trackbacks
          為了便于管理,先引入個(gè)基礎(chǔ)類:
          package algorithms;

          /**
           * 
          @author yovn
           *
           
          */
          public abstract class Sorter<extends Comparable<E>> {
              
              
          public abstract void sort(E[] array,int from ,int len);
              
              
          public final void sort(E[] array)
              {
                  sort(array,
          0,array.length);
              }
              
          protected final void swap(E[] array,int from ,int to)
              {
                  E tmp
          =array[from];
                  array[from]
          =array[to];
                  array[to]
          =tmp;
              }

          }
          一 插入排序
          該算法在數(shù)據(jù)規(guī)模小的時(shí)候十分高效,該算法每次插入第K+1到前K個(gè)有序數(shù)組中一個(gè)合適位置,K從0開始到N-1,從而完成排序:
          package algorithms;
          /**
           * 
          @author yovn
           
          */
          public class InsertSorter<extends Comparable<E>> extends Sorter<E> {

              
          /* (non-Javadoc)
               * @see algorithms.Sorter#sort(E[], int, int)
               
          */
              
          public void sort(E[] array, int from, int len) {
                   E tmp
          =null;
                    
          for(int i=from+1;i<from+len;i++)
                    {
                        tmp
          =array[i];
                        
          int j=i;
                        
          for(;j>from;j--)
                        {
                            
          if(tmp.compareTo(array[j-1])<0)
                            {
                                array[j]
          =array[j-1];
                            }
                            
          else break;
                        }
                        array[j]
          =tmp;
                    }
              }
                  
              

          }

          二 冒泡排序
          這可能是最簡單的排序算法了,算法思想是每次從數(shù)組末端開始比較相鄰兩元素,把第i小的冒泡到數(shù)組的第i個(gè)位置。i從0一直到N-1從而完成排序。(當(dāng)然也可以從數(shù)組開始端開始比較相鄰兩元素,把第i大的冒泡到數(shù)組的第N-i個(gè)位置。i從0一直到N-1從而完成排序。)

          package algorithms;

          /**
           * 
          @author yovn
           *
           
          */
          public class BubbleSorter<extends Comparable<E>> extends Sorter<E> {

              
          private static  boolean DWON=true;
              
              
          public final void bubble_down(E[] array, int from, int len)
              {
                  
          for(int i=from;i<from+len;i++)
                  {
                      
          for(int j=from+len-1;j>i;j--)
                      {
                          
          if(array[j].compareTo(array[j-1])<0)
                          {
                              swap(array,j
          -1,j);
                          }
                      }
                  }
              }
              
              
          public final void bubble_up(E[] array, int from, int len)
              {
                  
          for(int i=from+len-1;i>=from;i--)
                  {
                      
          for(int j=from;j<i;j++)
                      {
                          
          if(array[j].compareTo(array[j+1])>0)
                          {
                              swap(array,j,j
          +1);
                          }
                      }
                  }
              }
              @Override
              
          public void sort(E[] array, int from, int len) {
                  
                  
          if(DWON)
                  {
                      bubble_down(array,from,len);
                  }
                  
          else
                  {
                      bubble_up(array,from,len);
                  }
              }
              
          }

          三,選擇排序
          選擇排序相對(duì)于冒泡來說,它不是每次發(fā)現(xiàn)逆序都交換,而是在找到全局第i小的時(shí)候記下該元素位置,最后跟第i個(gè)元素交換,從而保證數(shù)組最終的有序。
          相對(duì)與插入排序來說,選擇排序每次選出的都是全局第i小的,不會(huì)調(diào)整前i個(gè)元素了。
          package algorithms;
          /**
           * 
          @author yovn
           *
           
          */
          public class SelectSorter<extends Comparable<E>> extends Sorter<E> {

              
          /* (non-Javadoc)
               * @see algorithms.Sorter#sort(E[], int, int)
               
          */
              @Override
              
          public void sort(E[] array, int from, int len) {
                  
          for(int i=0;i<len;i++)
                  {
                      
          int smallest=i;
                      
          int j=i+from;
                      
          for(;j<from+len;j++)
                      {
                          
          if(array[j].compareTo(array[smallest])<0)
                          {
                              smallest
          =j;
                          }
                      }
                      swap(array,i,smallest);
                             
                  }

              }
           
          }
          四 Shell排序
          Shell排序可以理解為插入排序的變種,它充分利用了插入排序的兩個(gè)特點(diǎn):
          1)當(dāng)數(shù)據(jù)規(guī)模小的時(shí)候非常高效
          2)當(dāng)給定數(shù)據(jù)已經(jīng)有序時(shí)的時(shí)間代價(jià)為O(N)
          所以,Shell排序每次把數(shù)據(jù)分成若個(gè)小塊,來使用插入排序,而且之后在這若個(gè)小塊排好序的情況下把它們合成大一點(diǎn)的小塊,繼續(xù)使用插入排序,不停的合并小塊,知道最后成一個(gè)塊,并使用插入排序。

          這里每次分成若干小塊是通過“增量” 來控制的,開始時(shí)增量交大,接近N/2,從而使得分割出來接近N/2個(gè)小塊,逐漸的減小“增量“最終到減小到1。

          一直較好的增量序列是2^k-1,2^(k-1)-1,.....7,3,1,這樣可使Shell排序時(shí)間復(fù)雜度達(dá)到O(N^1.5)
          所以我在實(shí)現(xiàn)Shell排序的時(shí)候采用該增量序列
          package algorithms;

          /**
           * 
          @author yovn
           
          */
          public class ShellSorter<extends Comparable<E>> extends Sorter<E>  {

              
          /* (non-Javadoc)
               * Our delta value choose 2^k-1,2^(k-1)-1,.7,3,1.
               * complexity is O(n^1.5)
               * @see algorithms.Sorter#sort(E[], int, int)
               
          */
              @Override
              
          public void sort(E[] array, int from, int len) {
                  
                  
          //1.calculate  the first delta value;
                  int value=1;
                  
          while((value+1)*2<len)
                  {
                      value
          =(value+1)*2-1;
                  
                  }
              
                  
          for(int delta=value;delta>=1;delta=(delta+1)/2-1)
                  {
                      
          for(int i=0;i<delta;i++)
                      {
                          modify_insert_sort(array,from
          +i,len-i,delta);
                      }
                  }

              }
              
              
          private final  void modify_insert_sort(E[] array, int from, int len,int delta) {
                    
          if(len<=1)return;
                    E tmp
          =null;
                    
          for(int i=from+delta;i<from+len;i+=delta)
                    {
                        tmp
          =array[i];
                        
          int j=i;
                        
          for(;j>from;j-=delta)
                        {
                            
          if(tmp.compareTo(array[j-delta])<0)
                            {
                                array[j]
          =array[j-delta];
                            }
                            
          else break;
                        }
                        array[j]
          =tmp;
                    }

              }
          }

          五 快速排序
          快速排序是目前使用可能最廣泛的排序算法了。
          一般分如下步驟:
          1)選擇一個(gè)樞紐元素(有很對(duì)選法,我的實(shí)現(xiàn)里采用去中間元素的簡單方法)
          2)使用該樞紐元素分割數(shù)組,使得比該元素小的元素在它的左邊,比它大的在右邊。并把樞紐元素放在合適的位置。
          3)根據(jù)樞紐元素最后確定的位置,把數(shù)組分成三部分,左邊的,右邊的,樞紐元素自己,對(duì)左邊的,右邊的分別遞歸調(diào)用快速排序算法即可。
          快速排序的核心在于分割算法,也可以說是最有技巧的部分。
          package algorithms;

          /**
           * 
          @author yovn
           *
           
          */
          public class QuickSorter<extends Comparable<E>> extends Sorter<E> {

              
          /* (non-Javadoc)
               * @see algorithms.Sorter#sort(E[], int, int)
               
          */
              @Override
              
          public void sort(E[] array, int from, int len) {
                  q_sort(array,from,from
          +len-1);
              }

              
              
          private final void q_sort(E[] array, int from, int to) {
                  
          if(to-from<1)return;
                  
          int pivot=selectPivot(array,from,to);

                  
                  
                  pivot
          =partion(array,from,to,pivot);
                  
                  q_sort(array,from,pivot
          -1);
                  q_sort(array,pivot
          +1,to);
                  
              }


              
          private int partion(E[] array, int from, int to, int pivot) {
                  E tmp
          =array[pivot];
                  array[pivot]
          =array[to];//now to's position is available
                  
                  
          while(from!=to)
                  {
                      
          while(from<to&&array[from].compareTo(tmp)<=0)from++;
                      
          if(from<to)
                      {
                          array[to]
          =array[from];//now from's position is available
                          to--;
                      }
                      
          while(from<to&&array[to].compareTo(tmp)>=0)to--;
                      
          if(from<to)
                      {
                          array[from]
          =array[to];//now to's position is available now 
                          from++;
                      }
                  }
                  array[from]
          =tmp;
                  
          return from;
              }


              
          private int selectPivot(E[] array, int from, int to) {
              
                  
          return (from+to)/2;
              }

          }

          還有歸并排序,堆排序,桶式排序,基數(shù)排序,下次在歸納。

          posted on 2007-12-13 01:08 DoubleH 閱讀(36718) 評(píng)論(15)  編輯  收藏 所屬分類: Memorandum

          Feedback

          # re: 排序算法復(fù)習(xí)(Java實(shí)現(xiàn))(一): 插入,冒泡,選擇,Shell,快速排序 2007-12-17 17:23 CoderDream
          不錯(cuò),感謝分享,已收藏!  回復(fù)  更多評(píng)論
            

          # re: 排序算法復(fù)習(xí)(Java實(shí)現(xiàn))(一): 插入,冒泡,選擇,Shell,快速排序 2008-01-22 09:13 haix
          不錯(cuò),感謝分享,已收藏!
          http://www.handandaily.com  回復(fù)  更多評(píng)論
            

          # re: 排序算法復(fù)習(xí)(Java實(shí)現(xiàn))(一): 插入,冒泡,選擇,Shell,快速排序 2008-11-12 18:46 first
          很好,都能用  回復(fù)  更多評(píng)論
            

          # re: 排序算法復(fù)習(xí)(Java實(shí)現(xiàn))(一): 插入,冒泡,選擇,Shell,快速排序 2008-12-24 14:02 wicker
          學(xué)習(xí)  回復(fù)  更多評(píng)論
            

          # re: 排序算法復(fù)習(xí)(Java實(shí)現(xiàn))(一): 插入,冒泡,選擇,Shell,快速排序[未登錄] 2009-01-14 16:32 小菜鳥
          學(xué)到很多,謝謝!  回復(fù)  更多評(píng)論
            

          # re: 排序算法復(fù)習(xí)(Java實(shí)現(xiàn))(一): 插入,冒泡,選擇,Shell,快速排序 2009-03-07 19:14 wolfman
          好強(qiáng)大,對(duì)JAVA理解真透徹
          不知博主搞了幾年JAVA  回復(fù)  更多評(píng)論
            

          # re: 排序算法復(fù)習(xí)(Java實(shí)現(xiàn))(一): 插入,冒泡,選擇,Shell,快速排序 2009-03-11 10:46 costom
          我只看了快速排序,很好很好,但有美中不足,
          在兩個(gè)值相等時(shí)依然進(jìn)行交換了。  回復(fù)  更多評(píng)論
            

          # re: 排序算法復(fù)習(xí)(Java實(shí)現(xiàn))(一): 插入,冒泡,選擇,Shell,快速排序 2009-03-13 23:09 sss
          非常感謝  回復(fù)  更多評(píng)論
            

          # re: 排序算法復(fù)習(xí)(Java實(shí)現(xiàn))(一): 插入,冒泡,選擇,Shell,快速排序 2009-03-22 17:19 rtp
          不太明白.講的不夠詳細(xì)..  回復(fù)  更多評(píng)論
            

          # re: 排序算法復(fù)習(xí)(Java實(shí)現(xiàn))(一): 插入,冒泡,選擇,Shell,快速排序 2010-06-29 17:36 淘寶
          該算法在數(shù)據(jù)規(guī)模小的時(shí)候十分高效,該算法每次插入第K+1到前K個(gè)有序數(shù)組中一個(gè)合適位置,K從0開始到N-1,從而完成排序:  回復(fù)  更多評(píng)論
            

          # re: 排序算法復(fù)習(xí)(Java實(shí)現(xiàn))(一): 插入,冒泡,選擇,Shell,快速排序 2010-09-28 16:42 JavaNewFish
          博主你好:
          您寫的快速排序?yàn)槭裁次艺{(diào)用了順序沒有改變啊?我是這樣調(diào)用的:
          Integer[] intArray = {1,2,52,6,23,63,27,423,34,56,3,13,23,61};
          QuickSorter<Integer> qs = new QuickSorter<Integer>();
          qs.selectPivot(intArray,0,intArray.length);
          for(int i:intArray){
          System.out.println(i);
          }  回復(fù)  更多評(píng)論
            

          # re: 排序算法復(fù)習(xí)(Java實(shí)現(xiàn))(一): 插入,冒泡,選擇,Shell,快速排序[未登錄] 2011-10-31 00:45 ST
          選擇排序有誤,更正如下

          public void sort(E[] array, int from, int len) {
          for(int i=from ;i<len + from;i++)
          {
          int smallest=i;
          int j=i+1;
          for(;j<from+len;j++)
          {
          if(array[j].compareTo(array[smallest])<0)
          {
          smallest=j;
          }
          }
          swap(array,i,smallest);

          }
          }
            回復(fù)  更多評(píng)論
            

          # re: 排序算法復(fù)習(xí)(Java實(shí)現(xiàn))(一): 插入,冒泡,選擇,Shell,快速排序[未登錄] 2011-11-04 19:00 helloworld
          @JavaNewFish
          您調(diào)錯(cuò)方法了,應(yīng)該qs.sort或者q_sort。這也太Fish了吧。  回復(fù)  更多評(píng)論
            

          # re: 排序算法復(fù)習(xí)(Java實(shí)現(xiàn))(一): 插入,冒泡,選擇,Shell,快速排序 2012-04-23 19:44 sfsdf
          插入排序中
          for(int i=from+1;i<from+len;i++)
          應(yīng)該改為
          for(int i=from+1;i<len ;i++)
          有個(gè)特殊的需求:
          我若想對(duì)一個(gè)數(shù)組 從 中間from(from>1 from= 2 或 3 什么的 )到末尾來個(gè)排序插到從0到from-1個(gè)數(shù)中且從小到大排序,而從0到from-1個(gè)數(shù)的排序無所謂的話,樓主這個(gè)程序顯然出現(xiàn)下標(biāo)越界問題 ,這是程序健壯性的問題,當(dāng)然了,這樣的情況比較少,完全可以不考慮只是改下或許會(huì)比較好吧?  回復(fù)  更多評(píng)論
            

          # re: 排序算法復(fù)習(xí)(Java實(shí)現(xiàn))(一): 插入,冒泡,選擇,Shell,快速排序 2012-04-23 20:00 sfsdf
          插入排序中
          for(int i=from+1;i<from+len;i++)
          應(yīng)該改為
          for(int i=from+1;i<len ;i++)
          有個(gè)特殊的需求:
          我若想對(duì)一個(gè)數(shù)組 從 中間from(from>1 from= 2 或 3 什么的 )到末尾來個(gè)排序且從小到大排序,而從0到from-1個(gè)數(shù)的排序無所謂的話,樓主這個(gè)程序顯然出現(xiàn)下標(biāo)越界問題 ,這是程序健壯性的問題,當(dāng)然了,這樣的情況比較少,完全可以不考慮只是改下或許會(huì)比較好吧? 回復(fù) 更多評(píng)論   回復(fù)  更多評(píng)論
            

          主站蜘蛛池模板: 崇明县| 枣阳市| 东阳市| 杨浦区| 阳泉市| 鄂托克前旗| 仙桃市| 塔河县| 呼玛县| 工布江达县| 永寿县| 鹤庆县| 新津县| 利津县| 淳安县| 庆安县| 视频| 文山县| 巩义市| 霍林郭勒市| 哈巴河县| 石河子市| 自治县| 宁德市| 温泉县| 建宁县| 久治县| 铜陵市| 丽江市| 隆尧县| 神农架林区| 盘山县| 石首市| 南充市| 施秉县| 乐都县| 阿瓦提县| 句容市| 慈溪市| 德清县| 兴安盟|