對資料進行一定的操作時,資料有序會使其處理起來方便很多,對資料的排序方法有很多種,而因為我們經常需要對資料多次排序或者對很大的資料量進行排序,不同排序演算法花費時間不同。簡單介紹幾種排序演算法;
一、簡單排序演算法:氣泡排序、插入排序,選擇排序;
二、快速排序演算法:基本快速排序、三數取中快速排序、三劃分快速排序;
三、合併排序
四、線性時間排序演算法:計數排序、桶排序
實現的氣泡排序、插入排序、基本快速排序、合併排序,對快速排序以及合併排序寫下個人的理解。
快速排序(平均時間nlogn):
選定乙個基準值a[i](即partition過程,使得i左側都比a[i]小,i右側都比a[i]大,也確定了a[i]的位置),然後通過遞迴過程,對a[l:i-1]和a[i+1,r]進行排序,同時對這兩個子串行排序又是同一類問題,最後就在經過多次的選基準值並確定其位置,就對數列排好序了。**:
合併排序(平均時間nlogn):
分治的思想,將數列分為兩個大小相等的子數列分別排序,子串行排序又是將子串行分為兩個子串行分別排序,最後最基礎的就是兩個元素進行分,一大一小,然後通過乙個輔助陣列b,將兩邊已經分好的序列從前往後挑小的放到b裡面,最後一定有一半被挑完,另一半還剩下一些元素(還是排好序的,但比b中的所有元素都大),然後再將這些元素加到b中,最後將b再複製回原來分成兩個子數列的a數列中。乙個遞迴的思想;
**:略說三數取中快排:大致思想就是在用遞迴處理時,如果陣列的規模比較小,比如5~25之間,就可以通過非遞迴演算法實現,比如插入排序,可以有效提高效能,就在quicksort()函式的前面加乙個判斷此時陣列規模if(r-l>10)insertion();
略說三劃分快排:基本思想是在陣列a[l:r]中存在大量鍵值相同的元素時,可以提高效率;v=a[r]為基準值,將陣列分為a[l:i],a[i+1,j-1],a[j,r]三段,左段鍵值小於v,中段等於v,右段大於v,演算法對左右兩段陣列進行遞迴排序;
#include#include#includeint b[100005];
void swap(int *a,int *b)
//氣泡排序(選擇排序,我分不太清二者的區別) ,複雜度無論如何都是o(n2)量級;
//最壞(任何)情況下需要執行n(n-1)/2次元素比較;
void bubble(int a,int l,int r)
} }}//插入排序,在如果是一串有序的數字輸入時,插入排序的複雜度可以減小甚至變成o(n)量級;
//最壞情況下 ,需要執行n(n-1)/2次比較和交換;
void insert(int a,int l,int i)
}void heapsort(int* a,int size) //將堆一次一次提取出當前的最大值,也就可以解決第k小的數的問題;
}int main()
;// bubble(a,0,9);
// insertion(a,0,9);
// quicksort(a,0,9);
// mergesort(a,0,9);
heapsort(a,11); //堆排序一般是從陣列編號為1開始儲存,所以在對a陣列改動了(a陣列前加了乙個0)以便堆排序輸出;
for(i=0;i<11;i++)
printf("%d%c",a[i],i==10?'\n':' ');
return 0;
}
第五次作業:
1、(將一串1~n的無序數列排序過程中,每個數能到的最右端與最左端差值的最大值,即計算每個數左邊比之大的數的個數和右邊比它小的數的個數)容易知道雖然題目說的是氣泡排序,但是計算每個數其前後有多少個比之大和小的數的個數,在合併排序的過程中就可以計算,每次合併過程都對數的大小進行了比較,記錄其個數即可。題目部落格鏈結
**:
#include#includeconst int n = 100007;
int a[n], wz[n], you[n], tmp[n];
int min(int &a, int &b)
int main()
guibing(1, n);
for (i = 1; i <= n; i++) puts("");
}
2、(將乙個丟失序列(丟失資料為0),和已知可能是丟失資料的數列合併,看是否能夠合併成功使之單調遞增)可以借助乙個陣列儲存0的位置,然後對要插入的數列先排序,再插入之後進行比較就可以得到結果;題目部落格鏈結
欠缺:還乙個第k小元素問題沒有深入學習,之後補上之後予以更新;
補充:已經對第k小(大)元素的問題學習,即通過堆排序的方式實現;**已更新;堆排序**:
參考部落格:
選擇排序 直接選擇排序與堆排序
選擇排序即每次從待排序的數列中選擇乙個最小的元素,然後把它放在已排好序列的最前面 假定這裡從小到大排序 直至序列完全有序。選擇排序分為線性結構的直接選擇排序與非線性的堆排序,後者是用相當於把樹的元素存在陣列中,通過元素下標來區分孩子結點與父親結點等等 1.直接選擇排序 直接上 void select...
選擇排序與氣泡排序
今早心血來潮,又想看看氣泡排序.於是乎度娘一番,找到了度娘給我的這篇文章,前面的文字描述還是簡單易懂的,可惜給出的 示範有些文不對題.於是乎又wiki一番.發現上文給出的 形似選擇排序,於是總結如下 我們假設有乙個陣列 624159 對應的索引也就是 0 5,如果我想描述第二個位置,也就是數字2的位...
選擇排序與氣泡排序
選擇排序 static void sort1 int arr var temp arr i arr i arr min arr min temp 氣泡排序 static void sort2 int arr static void main string args sort1 arr foreach...