插入排序法(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();
}
}