1. 程式人生 > >插入排序法(Java實現)

插入排序法(Java實現)

插入法排序

※ 插入法排序原理
利用插入法對無序陣列排序時,我們其實是將陣列R劃分成兩個子區間R[1..i-1](已排好序的有序區)和R[i..n](當前未排序的部分,可稱無序區)。插入排序的基本操作是將當前無序區的第1個記錄R[i]插人到有序區R[1..i-1]中適當的位置上,使R[1..i]變為新的有序區。因為這種方法每次使有序區增加1個記錄,通常稱增量法。
插入排序與打撲克時整理手上的牌非常類似。摸來的第1張牌無須整理,此後每次從桌上的牌(無序區)中摸最上面的1張並插入左手的牌(有序區)中正確的位置上。為了找到這個正確的位置,須自左向右(或自右向左)將摸來的牌與左手中已有的牌逐一比較。
插入排序法動態圖


圖解:根據其原理,我們把該無序數列看成兩個部分,我們不難看出圖中,首先我們把第一位3看成是有序數列,剩下的作為無序數列,因為要把後面的無序數列中的數插入到前面有序數列,所以依次把後面的數抽出,在前面找到合適位置插入。如圖,先抽出44,與前面比較,比3大放在3後面,再抽出38,與前面比較,比44小,比3大,所以插入到3後面。依次類推,直到最後的一個數也插入到前面的有序數列中。

※ 插入例項演算法分析
{3 -1 0 -8 2 1} 這是要進行插入排序的陣列

{3 -1 0 -8 2 1} -1 先把-1(陣列的第二個位置)拿出來當做要進行往左邊插入的值,
但是把-1插入到左的什麼位置需要通過程式找出來
(左邊的值依次和這個值-1作比較得出)

{3 3 0 -8 2 1} -1 拿第一個位置的值3和-1比較,發現比-1大,那麼就把第一個位置
的值3賦給第二個位置,結果如左邊所示

{-1 3 0 -8 2 1} -1 這個時候第一個位置
就有可能是我們要找的插入的位置,進一步發現第一種位置前面
沒有值了,那麼就果斷把-1插入到第一個位置,結果如左邊所示,
好了本次迴圈結束

{-1 3 0 -8 2 1} 0 這次把0(陣列的第三個位置)拿出來當做要進行往左邊插入的值,
但是把0插入到左的什麼位置需要通過程式找出來
(左邊的值依次和這個值0作比較得出)

{-1 3 3 -8 2 1} 0 拿第二個位置的值3和0比較,發現比0大,那麼就把第二個位置
的值3賦給第三個位置,結果如左邊所示

{-1 0 3 -8 2 1} 0 這個時候第二個位置
就有可能是我們要找的插入的位置,進一步發現第一個位置的值-1
比0小,那麼就果斷確定第二個位置就是我們要找的插入位置,
然後把0插入到第二個位置,結果如左邊所示,
好了本次迴圈結束

{-1 0 3 -8 2 1} -8 這次把-8(陣列的第四個位置)拿出來當做要進行往左邊插入的值,
但是把-8插入到左的什麼位置需要通過程式找出來
(左邊的值依次和這個值-8作比較得出)

{-1 0 3 3 2 1} -8 拿第三個位置的值3和-8比較,發現比-8大,那麼就把第三個位置
的值3賦給第四個位置,結果如左邊所示

{-1 0 0 3 2 1} -8 拿第二個位置的值0和-8比較,發現比-8大,那麼就把第二個位置
的值0賦給第三個位置,結果如左邊所示

{-1 -1 0 3 2 1} -8 拿第一個位置的值-1和-8比較,發現比-8大,那麼就把第一個位置
的值-1賦給第二個位置,結果如左邊所示

{-8 -1 0 3 2 1} -8 這個時候第一個位置
就有可能是我們要找的插入的位置,進一步發現第一種位置前面
沒有值了,那麼就果斷把-8插入到第一個位置,結果如左邊所示,
好了本次迴圈結束

{-8 -1 0 3 2 1} 2 這次把2(陣列的第五個位置)拿出來當做要進行往左邊插入的值,
但是把2插入到左的什麼位置需要通過程式找出來
(左邊的值依次和這個值2作比較得出)

{-8 -1 0 3 3 1} 2 拿第四個位置的值3和2比較,發現比2大,那麼就把第四個位置
的值3賦給第五個位置,結果如左邊所示

{-8 -1 0 2 3 1} 2 這個時候第四個位置就有可能是我們要找的插入的位置,
拿第三個位置的值0和2比較,發現比2小,
那麼就果斷把2插入到第四個位置(再往前就不用比較了,因為順序已經是排好的),
結果如左邊所示

{-8 -1 0 2 3 1} 1 這次把1(陣列的第六個位置)拿出來當做要進行往左邊插入的值,
但是把1插入到左的什麼位置需要通過程式找出來
(左邊的值依次和這個值1作比較得出)

{-8 -1 0 2 3 3} 1 拿第五個位置的值3和1比較,發現比1大,那麼就把第五個位置
的值3賦給第六個位置,結果如左邊所示

{-8 -1 0 2 2 3} 1 拿第四個位置的值2和1比較,發現比1大,那麼就把第四個位置
的值2賦給第五個位置,結果如左邊所示

{-8 -1 0 1 2 3} 1 這個時候第四個位置就有可能是我們要找的插入的位置,
拿第三個位置的值0和1比較,發現比1小,
那麼就果斷把1插入到第四個位置(再往前就不用比較了,因為順序已經是排好的),
結果如左邊所示

最後插入排序已完成。。。。
在這裡插入圖片描述

※ 實現程式碼如下:

package com.test.insertsort;
/*
 * 插入排序演算法:
 * 1、以陣列的某一位作為分隔位,比如index=1,假設左面的都是有序的.
 * 
 * 2、將index位的資料拿出來,放到臨時變數裡,這時index位置就空出來了.
 * 
 * 3、從leftindex=index-1開始將左面的資料與當前index位的資料(即temp)進行比較,如果array[leftindex]>temp,
 * 則將array[leftindex]後移一位,即array[leftindex+1]=array[leftindex],此時leftindex就空出來了.
 * 
 * 4、再用index-2(即leftindex=leftindex-1)位的資料和temp比,重複步驟3,
 * 直到找到<=temp的資料或者比到了最左面(說明temp最小),停止比較,將temp放在當前空的位置上.
 * 
 * 5、index向後挪1,即index=index+1,temp=array[index],重複步驟2-4,直到index=array.length,排序結束,
 * 此時陣列中的資料即為從小到大的順序.
 * 
 * @author bjh
 *
 */
public class InsertSort {
    private int[] array;
    private int length;
    
    public InsertSort(int[] array){
        this.array = array;
        this.length = array.length;
    }
    
    public void display(){        
        for(int a: array){
            System.out.print(a+" ");
        }
        System.out.println();
    }
    
    /*
     * 插入排序方法
     */
    public void doInsertSort(){
        for(int index = 1; index<length; index++){//外層向右的index,即作為比較物件的資料的index
            int temp = array[index];//用作比較的資料
            int leftindex = index-1;
            while(leftindex>=0 && array[leftindex]>temp){//當比到最左邊或者遇到比temp小的資料時,結束迴圈
                array[leftindex+1] = array[leftindex];
                leftindex--;
            }
            array[leftindex+1] = temp;//把temp放到空位上
        }
    }
    
    public static void main(String[] args){
        int[] array = {38,65,97,76,13,27,49};
        InsertSort is = new InsertSort(array);
        System.out.println("排序前的資料為:");
        is.display();
        is.doInsertSort();
        System.out.println("排序後的資料為:");
        is.display();
    }
}
自己思考所寫:

package com.briup.Abstract;

import java.util.Arrays;

public class Test {
public static void main(String[] args) {
	int[] array={12,73,45,69,35};
	int i,j,temp;
	for(i=1;i<array.length;i++) {
		/*
		 * 第一個for迴圈
		 * 把陣列分成兩部分,右邊為未排序,左邊為已排序
		 * 記錄排序與未排序分割點temp(temp為下一個排序物件)
		 */
		temp=array[i];
		for(j=i-1;j>=0;j--) {
		/*
		 * 第二個for迴圈
		 * 將排序物件temp與已排序陣列比較
		 * 當temp比最近左邊的數大時(按從小到大循序排列時)
		 * 直接結束本次迴圈,進行下一個數排序
		 * 否則比左邊這個數小時將這個數後移,騰出這個數的位置
		 */
		   if (temp > array[j]) {
				break;
		   }else{
	    	   array[j+1] = array[j];
	       }
		}
		array[j+1]=temp;
	}
	System.out.println(Arrays.toString(array));
}
}

三種排序彙總:

package com.briup.Abstract;

import java.util.Arrays;

public class A {
  public int[] array;
  public A(int[] array){
	  this.array=array;
  }
  //氣泡排序
public void test1() {
	for(int i=1;i<array.length;i++) {
		for(int j=0;j<array.length-i;j++) {
			if(array[j]>array[j+1]) {
				int temp=array[j];
				array[j]=array[j+1];
				array[j+1]=temp;
			}
		}
	}
	System.out.println(Arrays.toString(array));
}
//選擇排序
public void test2() {
	int i,j,index;
	for(i=0;i<array.length;i++) {
		index=i;
		for(j=i+1;j<array.length;j++) {
			if(array[j]<array[index]) {
				index=j;
			}
		}
		int temp=array[i];
		array[i]=array[index];
		array[index]=temp;
	}
	System.out.println(Arrays.toString(array));
}
//插入排序
public void test3() {
	int i,j,temp;
	for(i=1;i<array.length;i++) {
		temp=array[i];
		for(j=i-1;j>=0;j--) {
			if(temp>array[j]) {
				break;
			}else {
				array[j+1]=array[j];
			}
		}
		array[j+1]=temp;
	}
	System.out.println(Arrays.toString(array));
}
public static void main(String[] args) {
     int[] array={23,34,25,66,21};
     A a=new A(array);
     a.test3();
}
}