排序演算法(一)氣泡排序,簡單選擇排序,直接插入排序,希爾排序
阿新 • • 發佈:2019-01-02
氣泡排序,簡單選擇排序,直接插入排序是三種複雜度為O(n2)的演算法,希爾排序在特殊增量序列的時候可以獲得複雜度為O(n3/2)
氣泡排序
1、最簡單的排序實現
這裡把每個數和這個數之後的每個數比較,大於就交換位置。
缺點:多出了很多次沒有用的交換
public class mysort {
public void sort(int[] array)
{
if(array.length<=1) return;
for(int i=0;i<array.length-1;i++)
{
for (int j=i+1;j<array.length;j++)
{
if(array[i]>array[j])
{
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
}
}
2、氣泡排序
從後向前交換相鄰的,這樣在交換的過程中附帶會把略小的交換到前面去
即每次把最小的數交換到前面去,像冒泡一樣
public class mysort {
public void sort(int[] array)
{
for(int i=0;i<array.length;i++)
{
for(int j=array.length-1;j>i;j--)
{
if(array[j]<array[j-1])
{
int temp = array[j];
array [j] = array[j-1];
array[j-1] = temp;
}
}
}
}
}
3、氣泡排序改進演算法
設定一個flag用於後面的數是否已經排序,如果已經排好(沒有交換)則後面的迴圈不需要再繼續
public class mysort {
public void sort(int[] array)
{
boolean hasSorted = false;
for(int i=0;(i<array.length) && (!hasSorted);i++)
{
hasSorted = true;
for(int j=array.length-1;j>i;j--)
{
if(array[j]<array[j-1])
{
int temp = array[j];
array[j] = array[j-1];
array[j-1] = temp;
hasSorted = false;
}
}
}
}
}
簡單選擇排序
和冒泡相比卻只交換當前數和後面數中最小的數,減少了交換的次數
public class mysort {
public void sort(int[] array)
{
if(array.length<2) return;
for(int i=0;i<array.length-1;i++)
{
int min = i;
for(int j=i+1;j<array.length;j++)
{
if(array[j]<array[min])
min = j;
}
if(min!=i)
{
int temp = array[min];
array[min] = array[i];
array[i] = temp;
}
}
}
}
直接插入排序
基本思想:將新的數不斷插入已經排序好的序列中
public class mysort {
public void sort(int[] array)
{
if(array.length<2) return;
for(int i=1;i<array.length;i++)
{
//[0,i-1]是已經從小到大排好序的陣列,如果新的數比原本最大的數小,則需插入原陣列
if(array[i]<array[i-1])
{
//num為需要插入的新值
int num = array[i];
//如果當前陣列中的某個數比需要插入的num大,則後移一位
int j;
for(j=i-1;(j>=0)&&(array[j]>num);j--)
{
array[j+1] = array[j];
}
//插入num
array[j+1] = num;
}
}
}
}
希爾排序
遍歷陣列,相隔某個增量比較兩個數,前者大於後者則交換,增量不斷變小。增量變小的規律目前還是個難題,因為是跳躍式的,演算法也不夠穩定
public void xier(int[] arr)
{
if(arr==null || arr.length==0) return;
int increment = arr.length;
int j = 0;
do{
increment = increment/3+1;
for(int i=increment;i<arr.length;i++)
{
//將i-incre,i-2incre,...所有的i-n*incre的比arr[i]大的數都像後挪動incre
int temp = arr[i];
for(j=i-increment;j>=0 && arr[j]>temp;j-=increment)
{
arr[j+increment] = arr[j];
}
arr[j+increment] = temp;
}
}
//必須保證最後一個incrment=1
while(increment>1);
}