代碼量比較少的排序算法:冒泡、插入、選擇排序(用java實現)

常見的的排序算法有直接插入排序、希爾排序、簡單選擇排序、堆排序、冒泡排序、快速排序、歸併排序、基數排序這八種。其中代碼量很少的有冒泡、插入、選擇這三種,寫出來也比較簡單,理解起來也不復雜,不需要考慮太多的細節。這裏會列出這三種排序算法。
算法用文字描述有些困難,可以看一下視頻教程:
鏈接:https://pan.baidu.com/s/1NwMqpD5Yk5_Q-uddJRrAnQ
提取碼:kr1n

1、冒泡排序

冒泡是最簡單的一種。思想就是將兩個相鄰的數進行比較,如果前一個數比後一個數大,就進行交換。假設有如下數組:

{21,4,54,5,51,20};

那麼拿21和4(索分別是0和1)比較,發現21比4大,於是進行交換,得到如下結果:

{4,21,54,5,51,20};

。同樣的接下來,拿索引爲1和2的比較、拿索引爲2和3的比較、拿索引爲3和4的比較、拿索引爲4和5的比較。前一個數比後一個數大,就交換。

經歷了第一趟,事情沒玩,只是找到了最大的一個數,放置在了數組的最後面。
第二趟的目標是找出第二大的數放在數組的倒數第二位,第三趟的目標是找出第三大的數放在數組的倒數第三位……
對於上面的數組,它有6個元素,經歷5趟,整個數組就是有序的了。
代碼:

int [] arr= {21,4,54,5,51,20};
for (int i = 0; i < arr.length-1; i++) //因爲要經歷arr.length-1趟排序
{
	for (int j = 0; j < arr.length-i-1; j++)//這裏不減i也行,但是會增加無意義的比較,增加排序的時間。因爲最大的數已經放在最後,你還去比較就是浪費時間,前面的數肯定不比後面的數大。
	{
		if (arr[j]>arr[j+1]) //如果前一個數比後一個數大,就交換
		{
			int temp=arr[j];//先把前面的數保存在一個臨時變量中
			arr[j]=arr[j+1];//後面的數賦值給前面的數。此時前面的數已經被覆蓋掉了,但是別慌,數據沒有丟失,因爲上一步已經用一個臨時變量把前面數保存起來了
			arr[j+1]=temp;//把前面的數賦值給後面的數
		}
	}
}
2、插入排序

插入排序的切入點就是,一開始將數組分成兩部分,第一部分是有序的,第二部分是無序的。

{21,4,54,5,51,20};

對於上面的數組,把21當成是有序的,把剩餘的當成是無序的。接下來就是從無序的部分拿出一個數,插入到前面的有序的部分中去。比如說第一趟,我們拿出4插入到前面中去:

{21,21,54,5,51,20};//找到插入的位置之後,那個元素往後移
{4,21,54,5,51,20};//插入到指定位置

我們發現找到了插入的位置之後,那個數據會往後移,但是數據4並沒有丟失,因爲我們用一個臨時變量保存起來了。

說起來簡單,但是用代碼實現的話,是怎麼找到插入的位置的?
拿上面的步驟來說,它是拿4和21進行比較,如果拿出來的數比有序的那部分中的元素小的話,就一直循環,直到拿出來的數據比有序的部分中的元素大爲止。這個有點難說明,詳情見代碼中的註釋。
代碼:

int [] arr= {21,4,54,5,51,20};
for (int i = 1; i < arr.length; i++)//從第二個數開始拿
{
	int temp=arr[i];//用一個臨時變量保存拿出來的數
	int index=i-1;//用於記錄插入的位置,並且用於倒序遍歷有序的那部分數據。
	while (index>=0&&temp<arr[index])//這是在倒序遍歷有序的部分,如果拿出來的數比有序的部分中的數小的話,就一直循環。 
	{
		arr[index+1]=arr[index];//元素往後移
		index--;
	}
	//while循環遍歷完之後就進行插入
	arr[index+1]=temp;//這裏爲啥是index+1?舉個例子,上面的索引可能會變成-1,那麼就是將數據插入到索引爲0的位置。
}

3、選擇排序

選擇排序是從剩餘的部分選擇最小的數,來和前面的有序的部分的最後一個數進行交換。前面的插入排序是直接選取無序的部分的第一個數,插入到有序的部分當中去。這是選擇排序和插入排序最明顯區別的地方。選擇排序相對來說更好理解一些。

{21,4,54,5,51,20};

對於上面的數組,第一趟選擇排序是這樣的:
從索引 0~5中選中最小的一個數,來和21交換。顯然最小的數時21,那麼交換後如下:

{4,21,54,5,51,20};

第二趟是從索引 1~5中,選擇一個最小的數,來和21交換。
……
經歷了arr.lengh-1次選擇、交換之後,整個數組就是有序的了。
代碼:

int [] arr= {21,4,54,5,51,20};
for (int i = 0; i < arr.length; i++) 
{
	int min=arr[i];//最小的那個數要保存在一個變量中,因爲涉及到元素的交換
	int minIndex=i;//最小的元素的索引也要記錄下來,不然交換不了,因爲元素會被覆蓋
	for (int j = i+1; j < arr.length; j++) //在後面無序的部分中找出一個最小的數
	{
		if (arr[j]<min)//如果遍歷到的數比min還小
		{
			min=arr[j];
			minIndex=j;//記錄最小的那個數的索引
		}
	}
	arr[minIndex]=arr[i];//把前面的數扔到後面
	arr[i]=min;//把後面那個最小的數扔到前面,完成了交換		
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章