在插入排序(概念)中簡單的提到了表插入排序。我簡單的總結了一下,寫下這篇文章,有需要的可以參考一下。
表插入排序,顧名思義,藉助一個索引表對原表進行插入排序,這樣做的好處就是省去了對原來表中元素的移動過程。當然單一的整數數組(僅作為實驗用)移動元素也是挺方便的,但是對於結構有些複雜的表來說,要想移動表中的元素那可真真不是一件容易的事情了。舉個例子(以下PHP中的二維數組)
$arr = array (
1=> array ("uname"=>'張三','age'=>20,'occu'=>'PHP程式員'),
2=> array ("uname"=>'李四','age'=>27,'occu'=>'PHP程式員'),
3=> array ("uname"=>'趙五','age'=>19,'occu'=>'PHP程式員'),
4=> array ("uname"=>'王六','age'=>33,'occu'=>'PHP程式員'),
5=> array ("uname"=>'劉大','age'=>35,'occu'=>'PHP程式員'),
6=> array ("uname"=>'公子糾','age'=>29,'occu'=>'PHP程式員'),
7=> array ("uname"=>'公子小白','age'=>26,'occu'=>'PHP程式員'),
8=> array ("uname"=>'管仲','age'=>80,'occu'=>'PHP程式員'),
9=> array ("uname"=>'孔丘','age'=>76,'occu'=>'PHP程式員'),
10=> array ("uname"=>'曾子','age'=>66,'occu'=>'PHP程式員'),
11=> array ("uname"=>'子思','age'=>55,'occu'=>'PHP程式員'),
12=> array ("uname"=>'左丘明','age'=>32,'occu'=>'PHP程式員'),
13=> array ("uname"=>'孟子','age'=>75,'occu'=>'PHP程式員'),
14=> array ("uname"=>'宋襄公','age'=>81,'occu'=>'PHP程式員'),
15=> array ("uname"=>'秦穆公','age'=>22,'occu'=>'PHP程式員'),
16=> array ("uname"=>'楚莊王','age'=>45,'occu'=>'PHP程式員'),
17=> array ("uname"=>'趙盾','age'=>58,'occu'=>'PHP程式員'),
18=> array ("uname"=>'廉頗','age'=>18,'occu'=>'PHP程式員'),
19=> array ("uname"=>'藺相如','age'=>39,'occu'=>'PHP程式員'),
20=> array ("uname"=>'老子','age'=>100,'occu'=>'PHP程式員'),
);
對於此數組,假如我們只是對age進行排序,但是又不想改變每個元素的位置,這是我們就可以使用表插入排序。藉助一個索引表對當前表進行排序。
好了,下面我們開始對錶插入排序來分析分析。首先我們需要一張索引表,表結構如下(依然是以php為例)
array (
index=> array ('next'=>值)
)
index 為元素在原來表中的索引next 指向其下一個索引
舉個例子 有以下元素需要排序
我們暫且認為其下標是從1開始的,0位作為開頭索引。那麼經過排序以後其索引表(稱其為B表)如下
接下來我們根據這個例子一步步構造此索引表
第一步:初始化索引表 置其兩個元素
第二步:遍曆A表,當前是A表中的第2個元素值為5 。然後從索引表(以後我們都稱其為B表)0位的next值開始,依次比較A[$next] 和 5 的大小 終止遍曆B表的條件有兩個,一是$next為0 二是A[$next] 要大於或者等於5
A[1]大於5 所以對B表做更改 B[0]的next值為2 B[2]的next值為1 如下
$next = B[0][next] 開始為1
while($next 不等於0){
if(A[$next]<5)
$next = B[$next][next] 此時$next值為0
If(A[$next]>=5)
跳出迴圈
}
If($next等於0 ) //說明直到B表中的最後一個元素仍然沒有比5大的元素 則將B[2]的next 值置為0,B[1]的next值置為2 其它的不變
If($next 不等於0) //說明A[$next]值大於等於 5 則將 B[0][next] 置為2 ,B[2][next]置為1
第三步遍曆A表,當前是A表中的第3個元素值為9 。步驟同第二步,這裡不再贅述。經過第三步,A、B表如下
B[3][next] = B[2][next]
B[2][next] = 3
第四步:同第二步 A、B表如下
B[4][next] = B[2][next]
B[2][next] = 4
至此索引表的構建方式就已經介紹完了。不知道有沒有給大家介紹清楚,如果有不清楚的地方可以在下面留言,看到後我會第一時間回複。
下面我們用PHP實現表插入排序 測試資料就用文章開頭的二維數組
$link = array (); //鏈表
$link [0]= array ('next'=>1);//初始化鏈表 $link第一個元素僅僅作為頭部
$link [1]= array ('next'=>0); //將第一個元素放入$link
/*
* 開始遍曆數組 從第二個元素開始
*/
for ( $i =2; $i <= count ( $arr ); $i ++){
$p = $arr [ $i ]; //儲存當前待排序的元素
$index =0;
$next = 1; //從開始位置尋找鏈表
while ( $next !=0){
if ( $arr [ $next ]['age']< $p ['age']){
$index = $next ;
$next = $link [ $next ]['next'];
}
else break ;
}
if ( $next == 0){
$link [ $i ]['next'] = 0;
$link [ $index ]['next'] = $i ;
} else {
$link [ $i ]['next']= $next ;
$link [ $index ]['next']= $i ;
}
}
至此索引表已經構建完成,只要遍曆此索引表就可以看到我們想要的效果了。下面是輸出結果的代碼
$next = $link [0]['next'];
while ( $next !=0){
print_r ( $arr [ $next ]);
$next = $link [ $next ]['next'];
}
從以上代碼中我們不難看出表插入排序的時間複雜度依然是O(n²)
好了,以上就是所有表插入排序的內容,歡迎大家在下面留言共同討論,共同提高。