7-5 簡化的插入排序 (15 分)
本題要求編寫程序,將一個給定的整數插到原本有序的整數序列中,使結果序列仍然有序。
輸入格式:
輸入在第一行先給出非負整數N(<10);第二行給出N個從小到大排好順序的整數;第三行給出一個整數X。
輸出格式:
在一行內輸出將X插入後仍然從小到大有序的整數序列,每個數字後面有一個空格。
輸入樣例:
5
1 2 4 5 7
3
輸出樣例:
1 2 3 4 5 7
代碼在最後,此處是分析(寫的很基礎) (更新後爲兩種方法)
(更新後爲兩種方法).
方法一思路:定義數組=> 找到插入值的位置=> 將其後面的值轉換位置=> 將其插入,輸出數組即可。
- 首先,我們分析這道題,不難發現其在增加一個數後數組的大小發生了變化,所以我們在定義時直接int a【n+1】即可解決.
- 之後,我們遍歷數組,將第二行輸入的數字賦值到數組a【n+1】中即可。
接着我們就開始進行數據的調換,但把大象裝進冰箱的第一步是打開冰箱門,即我們首先要找到x即插入值的位置應該在哪裏。所以我們不難想到遍歷數組,當其大於a[i]且小於a[i+1],(在此題中,保證了不重複,不會出現相等的情況)則記錄下這個i,此爲其位置! - 再找到其位置後,我們可以開始轉換吧,採用的思想是將其錯位放置,即例如原本爲第五個位置的數放置在第六個位置,將第四個位置的數放在第五個位置(順序可不能反了啊2333)。
那麼又會出現一個最大的問題!如何合理安排其轉換?理解了思路後,其實實踐中,我們就會發現許多問題,比如錯位放置的時候,在哪裏停止?從哪裏開始?
在數組中,其第一個數從a[0]開始的,所以其開始的順序是與正常的邏輯有所差異(即差一位)。所以我們先熟悉正常的,常見的,for循環而瞭解其循環的次數與特性。
1.當我們輸入:(以題目中給出的參考輸入值爲準)for(i=0;i<n;i++)或者for(i=1;i<=n;i++) `` 那麼我們會循環n(即n-0)次.由於我們使用的數組爲保持一致性,我們還是使用第一種.
2.在此題中,我們需要交換多少次呢?我們原來一共有n個數,後來變爲n+1個數,我們從一般情況來看:當滿足以下條件時我們可以得到其位置(即i)
if(x>a[i]&&x<a[i+1])
但我們也應注意到(載體給定的數據中)是第3個而且其i=2;此時我們輸入的數據中,最後一個是i=n-1;在這裏我們使用新的變量j來計數,並實現交換數組。(保持i的不變)在此循環中我們循環了(n-1)-i+1次即在i後面我們有這麼多次交換。注意:a[i]不變,a[i+1]最終會進行x的賦值實現插入(被替換)。(此處類比上述1的特性)
for(j=n-1;j>i;j- -);
3.最後,我們考慮到將x插入,則一般情況解決,但是其中的特殊情況:比如x最小或最大在最前面或最後一個,則需要單獨處理。(評論有指出給定的數字與有序數列中的相同時的bug,已經修復,而且我覺得題意最後要求排列後爲有序數列,就不會給出這樣的情況(也許是我錯了,但最好加上等於號排除這中可能)。感謝提出問題並交流)
真的代碼!
#include<stdio.h>
int main(){
int n,j,i,t,x;
scanf("%d",&n);
int a[n+1];
for(i=0;i<n;i++){//input
scanf("%d",&a[i]);
}
scanf("%d",&x);
if(x<a[0]){//special min
for(j=n-1;j>=0;j--){//有多少個n移多少次!
a[j+1]=a[j];
}a[0]=x;
}
else if(x>a[n-1])a[n]=x;//special max
else for(i=0;i<n;i++){//do
if(x>a[i]&&x<=a[i+1]){
for(j=n-1;j>i;j--){
a[j+1]=a[j];
}a[i+1]=x;
break;
}
}
for(i=0;i<n+1;i++){//output
printf("%d ",a[i]);
}
return 0;
}
方法二的思路:從後向前比較,如果x>最後一個數字a[n-1]那麼將a[n]賦值爲x即可停止程序;如果x<a[n-1],那麼我們將a[n-1]向後移一位,再繼續循環比較。
- 這樣的好處是我們不必再去考慮一些特殊情況的處理
- 更加符合我們的邏輯習慣
- 代碼也更爲簡單
代碼如下:
#include<stdio.h>
int main(){
int n,j,i,t,x;
scanf("%d",&n);
if(n==0){
scanf("%d",&x);
printf("%d ",x);
return 0;
}
int a[n+1];
for(i=0;i<n;i++){//input
scanf("%d",&a[i]);
}
scanf("%d",&x);
// if(x<a[0]){//special min
// for(j=n-1;j>=0;j--){//有多少個n移多少次!
// a[j+1]=a[j];
// }a[0]=x;
// }
// else if(x>a[n-1])a[n]=x;//special max
//
// else
for(i=n-1;i>=0;i--){//do
if(x>a[i]){
a[i+1]=x;
break;}//找到x的位置並插入了
else a[i+1]=a[i];//沒找到,將大的數字向右移一位,繼續比較。
}
for(i=0;i<n+1;i++){//output
printf("%d ",a[i]);
}
return 0;
}