pta7-5 簡化的插入排序 (15 分)詳解(附帶一些基礎講解)

7-5 簡化的插入排序 (15 分)

本題要求編寫程序,將一個給定的整數插到原本有序的整數序列中,使結果序列仍然有序。

輸入格式:

輸入在第一行先給出非負整數N(<10);第二行給出N個從小到大排好順序的整數;第三行給出一個整數X。

輸出格式:

在一行內輸出將X插入後仍然從小到大有序的整數序列,每個數字後面有一個空格。

輸入樣例:

5
1 2 4 5 7
3

輸出樣例:

1 2 3 4 5 7

代碼在最後,此處是分析(寫的很基礎) (更新後爲兩種方法)

(更新後爲兩種方法).
方法一思路:定義數組=> 找到插入值的位置=> 將其後面的值轉換位置=> 將其插入,輸出數組即可。

  1. 首先,我們分析這道題,不難發現其在增加一個數後數組的大小發生了變化,所以我們在定義時直接int a【n+1】即可解決.
  2. 之後,我們遍歷數組,將第二行輸入的數字賦值到數組a【n+1】中即可。
    接着我們就開始進行數據的調換,但把大象裝進冰箱的第一步是打開冰箱門,即我們首先要找到x即插入值的位置應該在哪裏。所以我們不難想到遍歷數組,當其大於a[i]且小於a[i+1],(在此題中,保證了不重複,不會出現相等的情況)則記錄下這個i,此爲其位置!
  3. 再找到其位置後,我們可以開始轉換吧,採用的思想是將其錯位放置,即例如原本爲第五個位置的數放置在第六個位置,將第四個位置的數放在第五個位置(順序可不能反了啊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;
}



發佈了24 篇原創文章 · 獲贊 7 · 訪問量 6834
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章