八大排序演算法之直接插入排序(教你用生活的想象,讀懂插入演算法)
八大排序演算法之直接插入排序(教你用生活的想象,讀懂直接插入演算法)
1,生活小遊戲:"演算法來源於生活",哈哈哈,還記得玩過的抽牌小遊戲嗎,你從放在地上的那一堆未知的牌【無序】抽一張牌後,
小腦袋機靈的將抽到的牌放到手中牌【早已被你打理得僅僅有序啦】的某個合適位置後【手中牌保持井井有序】。
手中牌【有序】<-------------------------------- 地上牌【無序】
直接插入排序 == “將牌一張張從地上抽起,然後在手中打理得井井有序”。
2,圖解:
從圖解可以知道咱需要“插入”,而本題咱用的儲存空間是陣列~則涉及到了陣列的空間移動問題了
~陣列移動是從最後一個元素開始,前一個元素的值賦值給後一個元素。
3,簡單分析一下過程:一開始,在整體牌中,有序區的牌只有一張,放在第一個位置,無序區的牌就是從第二張到最後一張結束。
然後,咱不斷的從無序區【從第二張牌開始直到最後一張牌~一個遍歷過程】拿牌插入到有序區的合適位置
【需要通過取出來的牌與已經在有序區的牌比較大小才知道是否合適~也是一個遍歷過程,從有序區的第一個位置開始直到
取出的牌 的前一個位置結束】。
4,所以:外迴圈(取出無序區的牌):從第二張牌開始到最後一張牌 【無序區的範圍】
內迴圈(在有序區找合適位置將取出的牌插入):從第一張牌開始直到 取出的牌 的前一張牌 【有序區的範圍】
5,假設,有序區是從小到大排序,則咱因為陣列移動空間問題,【有序區的範圍】
於是乎,也從最後該元素比較起,一旦找到在有序第一個數小於取出的數,則有序區的該數後邊便是合適插入位置。
6,比較過程,形象生動用一個想象說明吧,看圖解(咱有一個從小到大的賽道跟一個球),當球停止,便也找到合適位置了:
7,直接上程式碼,分析如上:
for(int i = 2; i <= N; i++){ //外迴圈,從無序區取出牌 arr[0] = arr[i]; //arr[0]是哨兵元素,後邊再補充哨兵元素的好處 for(j = i - 1; arr[0] < arr[j]; j--){ //內迴圈,從有序區最後一個元素開始比較,知道“球”卡住了,便找到合適位置arr[j + 1] = arr[j]; } arr[j + 1] = arr[0]; }
8,哨兵元素好處:參考《資料結構c語言版嚴蔚敏PPT.pdf ~
https://wenku.baidu.com/view/9e73cb8b69dc5022aaea00c1.html》
(1)不用額外增加輔助空間;
(2)省去對下標越界的判斷;