java實現折半插入排序演算法__演算法

來源:互聯網
上載者:User
前言

折半插入排序演算法是一種排序的演算法,它通過“折半尋找”在比較區尋找插入點的位置,這樣可以減少比較的次數,移動的次數不變,時間複雜度仍為
O(n^2); 演算法描述 將第一個元素當做一個尋找區的元素,剛開始這個尋找區僅含ary[0](第一個元素) 取出下一個元素(這裡迴圈擷取,從第二個元素開始),和尋找區的中間元素(半查法)比較。註:尋找區裡面的元素都排好序了 如果新的元素小於中間元素,將尋找區的右邊界(right變數表示)向左移動一位,如果大於等於中間元素,將左邊界(left變數表示)左移一位 重複步驟3,直到左邊界大於右邊界 判斷左邊界是否在尋找區裡面,如果是就從找到的索引位置開始,到該比較元素索引位置結束,向後移動一位。如果在右邊界外面,則忽略這一步 將找到的位置元素用比較的元素(第二步取出的資料)覆蓋 重複第二步

提示:上面從第二步開始到第7步結束,每一次迴圈比較區裡面的右邊界都在遞增,直到遞增結束 演算法描述圖

以上是在開始寫這篇文章的基礎知識,如果還是看不懂沒關係,我找到一個講解比較好的連結,請看下面的參考資料 為什麼寫這篇文章

這篇文章與其說是來記錄折半排序演算法,還不如說是一次總結,從後面我貼出的代碼可以看出我特意在封裝類中應用了泛型、內部類、以及提供2個Comparable與Comparator的實作類別調用的重載的排序方法,算是對自己前面階段鞏固java基礎一次檢驗,我也希望能對看到這篇文章的人有所協助,由於自身水平的關係,如有錯誤的地方,希望能指出。 本文

在前言中我描述了折半排序演算法的步驟以及原理,我下面從一個實現該演算法的代碼入手來分析一下

public void  binarySort(T[] obj , Comparator<T> comparator ) {            //定義折半插入演算法所需的一些變數                 int left, right, mid;           T curValue = null;            for( int start = 1; start < obj. length; start++) {                 curValue = obj[ start];                 left = 0;                 right = start - 1;                 //下面代碼在比較區使用半查法找出可以插入的位置                 while( left <= right) {                      //使用位元運算找出比較區中間位置                      mid = ( left + right) >> 1;                      if( comparator.compare( curValue, obj[ mid]) < 0) {                            //當curValue小於obj[mid],右邊界左移                            right -= 1;                     } else {                               //這裡需要注意一下,如果兩個值相等也讓左邊界向左移動一位                            left += 1;                     }                }                 //結束迴圈以後left = right + 1; 且 left <= start                 //left就是需要插入元素的位置,moveStep表示將left - start之間的元素後移一位                 int moveStep = start - left;                System. arraycopy(obj, left, obj, left+1, moveStep);                 obj[ left] = curValue;           }     }

從上面我們可以看到代碼有兩個迴圈,第一個for迴圈是對應2-7步驟,第二個while迴圈對應2-4步驟,我們需要注意一下,start是從數組第二個元素開始的,第一個元素我設定成尋找區間元素,右邊界right和這個start有關,這樣才能讓尋找區間不斷的擴充。等while迴圈結束以後,表示我已經找到插入的位置了,接下去通過arraycopy函數,將合格數組向右移動以後,然後用待比較資料去覆蓋找到的索引上的值
我覺得有必要提醒一下就是半查法是針對已經排好序的數組,所以尋找區間按照設定,不斷擴張的以後,裡面的資料也是排序好的

測試代碼

package org.study.arithmetic;import java.util.Arrays;import java.util.Comparator;import java.util.Random;public class BinarySortAc<T> {     /**      * 折半插入演算法排序      * @param 外面傳遞一個需要排序的數組引用      */     public void binarySort(T[] obj, Comparator<T> comparator) {            //定義折半插入演算法所需的一些變數                 int left, right, mid;           T curValue = null;            for( int start = 1; start < obj. length; start++) {                 curValue = obj[ start];                 left = 0;                 right = start - 1;                 //下面代碼在比較區使用半查法找出可以插入的位置                 while( left <= right) {                      //使用位元運算找出比較區中間位置                      mid = ( left + right) >> 1;                      if( comparator.compare( curValue, obj[ mid]) < 0) {                            //當curValue小於ojb[mid],右邊界左移                            right -= 1;                     } else {                               //這裡需要注意一下,如果兩個值相等也讓左邊界向左移動一位                            left += 1;                     }                }                 //結束迴圈以後left = right + 1; 且 left <= start                 //left就是需要插入元素的位置,moveStep表示將left - start之間的元素後移一位                 int moveStep = start - left;                System. arraycopy(obj, left, obj, left+1, moveStep);                 obj[ left] = curValue;           }     }     @SuppressWarnings({ "unchecked", "rawtypes" })     /**      * 排序重載的方法,這裡我無法在使用泛型了,因為泛型由於無法調用compareTo方法      * @param obj 需要比較的資料集合      */     public void binarySort(Object[] obj) {            //定義折半插入演算法所需的一些變數                 int left, right, mid;           Comparable curValue = null;            for( int start = 1; start < obj. length; start++) {                 curValue = (Comparable) obj[ start];                 left = 0;                 right = start - 1;                 while( left <= right) {                      mid = ( left + right) >> 1;                      if( curValue.compareTo( obj[ mid]) < 0) {                            right -= 1;                     } else {                            left += 1;                     }                }                 //結束迴圈以後left = right + 1; 且 left <= start                 //left就是需要插入元素的位置,moveStep表示將left - start之間的元素後移一位                 int moveStep = start - left;                System. arraycopy(obj, left, obj, left+1, moveStep);                 obj[ left] = curValue;           }     }     @SuppressWarnings("unchecked")     /**      * @return 返回一個具體的集合      */     public User<String>[] getList() {           User<String>[] users = new User[10];            for( int index = 0; index < 10; index++) {                User<String> user = new User<String>();                 user.setName( "Abigail"+ index);                 user.setAge( new Random().nextInt(100));                 users[ index] =  user;           }            return users;     }     /**      *      *      * @param <T> User使用外圍類的泛型參數      */     private static class User<V> {            private V name;            private int age;            public V getName() {                 return name;           }            public void setName(V name) {                 this. name = name;           }            public int getAge() {                 return age;           }            public void setAge( int age) {                 this. age = age;           }            public String toString() {                StringBuilder sbu = new StringBuilder();                 return sbu.append( "[name:")                        .append( name)                        .append( ",age:")                        .append( age)                        .append( "]").toString();           }     }     /**      * @return 返回一個具體的比較子      */     public Comparator<User<String>> getComparator() {            return new MyComparator();     }     /**      * 內部類實現一個User的比較子      * @param args      */     private class MyComparator implements Comparator<User<String>>{            @Override            /**            * 用年齡來比較兩個對象的大小            */            public int compare(User<String> o1, User<String> o2) {                 return o1.getAge() - o2.getAge();           }     }     public static void main(String[] args) {           BinarySortAc<Integer> ite  = new BinarySortAc<Integer>();           Integer[] ites = new Integer[] {5,2,10,6,4,3,1,5,10};           System. out.format( "排序前%s\n", Arrays.toString(ites));            ite.binarySort( ites);           System. out.format( "排序後%s\n", Arrays.toString(ites));           BinarySortAc<User<String>> ite1  = new BinarySortAc<User<String>>();           User<String>[] users = ite1.getList();           System. out.format( "排序前%s\n", Arrays.toString(users));            ite1.binarySort( users, ite.getComparator());           System. out.format( "排序後%s\n", Arrays.toString(users));     }}
參考資料

折半插入排序演算法描述(左小右大)
http://wenku.baidu.com/link?url=16JgfPzd4KYlB8rMYULIINnnWSvTcAy916vgxlQpCE47H3D8x96k2wJx0CNaJ8urQyAQ70pKnHYVHeAxoeyK34tsKaasUgKkf5zSVgIZUJe

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.