經典算法(三)----插入排序----圖解法讓你快速入門

引言

     只要設計到數據,就會涉及到數據的排序問題,比如給你隨機給你五個整數  3,1,5,2,4 。讓你從小到大進行排序,那我們該怎樣纔是實現對這些整數的排序呢 ?

    答案是多種多樣的,比如用插入排序、選擇排序、堆排序、歸併排序、快速排序等等,這些排序方法都可以實現對整數排序,而這篇文章要講的就是插入排序

本文將從以下幾個問題對插入排序進行分析和講解:

  1. 什麼是插入排序?
  2. 插入排序的大概過程是什麼?
  3. 怎樣用代碼實現插入排序?
  4. 插入排序的代碼詳解。

什麼是插入排序?


下面看百度百科對插入排序的定義:

插入排序,一般也被稱爲直接插入排序。對於少量元素的排序,它是一個有效的算法  。插入排序是一種最簡單的排序方法,它的基本思想是將一個記錄插入到已經排好序的有序表中,從而一個新的、記錄數增1的有序表。在其實現過程使用雙層循環,外層循環對除了第一個元素之外的所有元素,內層循環對當前元素前面有序表進行待插入位置查找,並進行移動   。

簡單來說:就是在想有序的數組中插入一個值,並且插入之後的數組仍然是有效的,進行一次次的插入,知道最後排好序。

下面看一個動圖:
 

 

插入排序的大概過程是什麼?

下面拿一個例子說明選擇排序的大概過程。

插入排序的基本思想就是:往有序的序列中一次次插入值,直到排序完成

下面來說用插入排序對3,1,5,2,4進行排序(從小到大排序)

  1. 首先選定第一個數3爲有序序列,拿着第二個數1往前面那個有序序列中插入值,插入的方法是用要插入的1依次和有序序列的值比較(從有序序列的後面依次往前比較),知道發現一個數比這個要插入的1小或者要插入的數走到了有序序列的頭部爲止。
  2. 經比較發現發現1<3,那就把有序序列的3後移一個位置(注意不是1和3這倆數)。這時候走到了頭,那就把數字1放到頭部。這時候數組元素爲1,3,5,2,4
  3. 繼續拿着5去有序序列中比較,發現5>3,那就不用繼續比較了,因爲3前面的數肯定比3小。                                         這時候數組元素爲1,3,5,2,4
  4. 繼續拿着2去和有序序列比較,首先發現2<5,那就把5後移一個位置(注意是後移)。再用2和3比較,發現2<3,那就把3後移一個位置,繼續用2和1比較,發現1<2。那就找到了放2的位置,把2在1後面就可以了。                                只是後數組元素爲1,2,3,5,4
  5. 按照上面的方法,用4去一一比較即可,最後得到的結果就是1,2,3,4,5

總結:假設有n個數需要排序,我們可以默認第一數是有序的,那就只需n-1輪就可以排序完成。每輪就是拿着元素去有序序列從後往前比較,這可以寫一個while循環實現,循環結束的條件就是比較到頭了或者找了比這個數要小的數,

擴展:這個擴展對後面理解希爾排序特別有用, 如果暫時不理解這個擴展的也沒事。

  1. 就上我們上面第3步結束後,數組元素爲1,3,5,2,4,前三個元素爲有序序列,後兩個還未比較,這時候我們需要拿着2去比較,等比較結束,發現3和5都後移了一個位置,所以一共後移了兩個位置。
  2. 再看我們上面的的第4步結束後,數組 元素爲1,2,3,5,4。這時候還剩一個元素4沒有排序,排序後,發現5後移了一個位置,所以一共後移了一次。
  3. 一個是後移了兩次,一個是後移了一次,那麼時間複雜度肯定是不同的,後移一次的肯定更省時一些,而且後移的次數時候數組元素的 “ 相對有序 ” 有關。
  4. 相對有序的意思就是相對來說小元素在前面,大元素在後面,只要有這個意識就可以了,其他的就不再多贅述了。至於怎樣利用這個相對有序來減少排序的時間,就是後面希爾排序的事情了。

 怎樣用代碼實現插入排序?

通過上面對3,1,5,2,4的排序過程講解,我們需要明確已知的三個條件

  1. 我們要排序的數組有哪些數?數組長度爲多少?
  2. 我們要進行幾輪插入操作?
  3. 每輪插入,哪些元素需要後移?

搞清楚了上面三個條件,我們下面我們動圖數據排序的實現代碼:

#include<iostream>
using namespace std;
//插入排序函數    穩定 
void InsertionSort(int arr[],int len)
{
	int temp;
	for(int i=1;i<len;i++)
	{
		int index=i-1;//前i-1個數已經排序好了
		int current=arr[i];
		while(index>=0&&arr[index]>current)
		{
			arr[index+1]=arr[index]; 
			index--; 
		}
		arr[index+1]=current;
	}
}
//輸出數組的值
void printf(int arr[],int len)
{
	for(int i=0;i<len;i++)
		cout<<arr[i]<<" ";
	cout<<endl;
}
int main()
{
	//要排序的數組 
	int arr[]={3, 44,38, 5,47,15,36,26,27,2 ,46,4 ,19,50,48};
	int len=15;//要排序的數組長度 
	
	//排序 
	InsertionSort(arr,len);
	
	//輸出 
	printf(arr,len);
	return 0;
}

運行結果: 

插入排序的代碼詳解

 

  1. 上面代碼寫了兩個函數,一個是printf函數,這個是輸出排序後的數組。
  2. 另一個函數就InsertionSort函數,在這個函數裏面有一個二重循環,外層循環的的次數就是要查找的次數,內層循環的次數的就是要比較的次數,剛好對應上面說的(這裏數組下標是從0開始的)。如果對上面代碼有疑問,自己可以按照前面的過程,模擬一邊對3,1,4,5,2的排序過程,就知道代碼是怎樣執行的了 。

本文參考以及引用:

百度百科

圖片動畫

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章