插入排序(直接插入、折半、Shell)
直接插入排序(順序插入排序)
基本思想:
排序過(guò)程,整個(gè)排序過(guò)程為n-1趟插入,即先將序列中的第1個(gè)元素看成是一個(gè)有序子序列,然后從第2個(gè)元素開(kāi)始,逐個(gè)進(jìn)行插入,直至整個(gè)序列有序。
在有序序列中插入一個(gè)元素,保持序列是有序的,不斷增長(zhǎng)這個(gè)有序序列完成排序
就類似將成績(jī)單上的第一個(gè)同學(xué)的名字和成績(jī)學(xué)到旁邊一張白紙中央,如果第二個(gè)同學(xué)比他成績(jī)高,就寫(xiě)到第一個(gè)同學(xué)的上方,如果比他低,就寫(xiě)到下方。等看到第三個(gè)同學(xué)的成績(jī)后,根據(jù)他的成績(jī)與前兩個(gè)同學(xué)成績(jī)比較,插入到相應(yīng)的位置。比如他的成績(jī)正好在兩個(gè)同學(xué)之間,就在傍邊那張紙上,把他的名字插入到前兩個(gè)人之間。當(dāng)然,那張排序的張要留夠足夠的空白,方便插入后來(lái)的同學(xué)名字。
public static void Insert_sort(int[] a)
{
for (int i = 1; i < a.Length; i++)
{
int temp = a[i]; //將待排序的數(shù)組存入臨時(shí)變量
int j;
for (j = i - 1; j >= 0 && temp<a[j]; j--)
{
a[j + 1] = a[j]; //將小的數(shù)值往后移
}
a[j + 1] = temp; //將未排序的數(shù)字插入到相應(yīng)的位置
}
}
折半插入排序(二分插入排序)
基本思想:
折半插入算法是對(duì)直接插入排序算法的改進(jìn),排序原理同直接插入算法:
把n個(gè)待排序的元素看成一個(gè)有序表和一個(gè)無(wú)序表,開(kāi)始時(shí)有序表中只有一個(gè)元素,無(wú)序表中有n-1個(gè)元素;排序過(guò)程即每次從無(wú)序表中取出第一個(gè)元素,將它插入到有序表中,使之成為新的有序表,重復(fù)n-1次完成整個(gè)排序過(guò)程。
public static void BinaryInsertSort(int[] arr)
{
for (int i = 1; i < arr.Length; i++) //依次從第1個(gè)元素到第n個(gè)元素插入到有序序列中
{
int temp = arr[i]; //將待排序的數(shù)值賦值給一個(gè)變量
int mid = 0; //有序序列數(shù)組的中間位置
int low = 0; //有序序列中的第一個(gè)元素
int high = i-1; //有序序列中的第最后個(gè)元素
//采用二分法在有序的的數(shù)組序列中不斷循環(huán)找到合適的插入位置
while (low <= high)
{
mid = (low + high);//計(jì)算出中間位置
//如果待排序的數(shù)值小于中間值則在左半部分查找插入位置
//否則在右半部分查找插入位置
if (temp < arr[mid])
{
high = mid - 1;
}
else
{
low = mid + 1;
}
}
//將需要移動(dòng)的數(shù)組向后移
for (int j = i - 1; j < high + 1; j--)
{
arr[j + 1] = arr[j];
}
//需要插入的下標(biāo)位置,i待排序的下標(biāo)位置
if (low != i)
{
arr[low] = temp;
}
}
}
希爾插入排序(縮小增量排序)
基本思想:
假設(shè)待排序元素序列有n個(gè)元素,首先取一個(gè)整數(shù)increment(小于n)作為間隔將全部元素分為increment個(gè)子序列,所有距離為increment的元素放在同一個(gè)子序列中,在每一個(gè)子序列中分別實(shí)行直接插入排序。然后縮小間隔increment,重復(fù)上述子序列劃分和排序工作。直到最后取increment=1,將所有元素放在同一個(gè)子序列中排序?yàn)橹埂?br />
由于開(kāi)始時(shí),increment的取值較大,每個(gè)子序列中的元素較少,排序速度較快,到排序后期increment取值逐漸變小,子序列中元素個(gè)數(shù)逐漸增多,但由于前面工作的基礎(chǔ),大多數(shù)元素已經(jīng)基本有序,所以排序速度仍然很快。
關(guān)于希爾排序increment(增量)的取法增量increment的取法有各種方案。最初shell提出取increment=n/2向下取整,increment=increment/2向下取整,直到increment=1。但由于直到最后一步,在奇數(shù)位置的元素才會(huì)與偶數(shù)位置的元素進(jìn)行比較,這樣使用這個(gè)序列的效率會(huì)很低。后來(lái)Knuth提出取increment=n/3向下取整+1.還有人提出都取奇數(shù)為好,也有人提出increment互質(zhì)為好。應(yīng)用不同的序列會(huì)使希爾排序算法的性能有很大的差異。
static void shell_sort(int[] arr)
{
int d=(arr.Length)/2;
while(d>=1)
{
for(int i=d;i<arr.Length;i++)
{
int temp=arr[i];
int j=i-d;
//直接插入排序,會(huì)向前找所適合的位置
while(j>=0&&arr[j] >temp)
{
//交換位置
arr[j+d]=arr[j];
j=j-d;
}
arr[j+d]=temp;
}
d/=2;
}
}
隨機(jī)向數(shù)組中存入10萬(wàn)個(gè)元素比較耗時(shí)。
有關(guān)測(cè)試結(jié)果
直接插入排序:
折半插入排序:
希爾排序:
總結(jié)
以上是生活随笔為你收集整理的插入排序(直接插入、折半、Shell)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 十进制小数与二进制小数相互转换
- 下一篇: 糯米糍荔枝几月份成熟上市