剛在csdn論壇上看到乙個「關於1-n自然數排序的華為面試題」的帖子,勾起了我的回憶;我大二時有段時間閒得沒事幹,想做乙個int型的陣列排序,達到時間複雜度為o(n)的目的,同學都因為n*log2(n)說這不可能,但自己做完後感覺不錯,雖做不到o(n),但自認為時間複雜度為o(n+t),大家鑑別鑑別是不是這樣的.我設計的演算法是:
1、掃瞄要排序陣列a,找出最大值 t
2、構造二維陣列 b[t][2],將其中所有元素置零
3、再掃瞄陣列a,碰到乙個元素i:若b[i-1][0]為0, 就將b[i-1][0]置為i,否則將b[i-1][1]加一
4、從後往前掃瞄陣列b,碰到不為0的b[i][0]:若b【i】為0,就將c[j]置為這個數b[i][0]
(j初值為n-1),並將j減一,若b【i】不為0
也將c[j]置為這個數b[i][0] (j初值為n-1),並將j減一再減去b[i][1]的值(說明有幾個重複的數字)
5、再從後往前掃瞄陣列c,每碰到0就將其置為其後面緊跟的元素,c 即就是排好序的a陣列了。
其**是:(vs2008上)
#include
using namespace std;
void main()
int temp=0;
int k=0,n;
int t=0;
cout<<"陣列的大小:">n;
int *a = new int[n];int *c= new int[n]; //動態定義2個一維陣列
//int c[20];int a[20];
for(int i=0;icout<<"輸入數字:">a[i];
for(int i=1;iif(a[i-1]>a[i]) //迴圈使b陣列中所有的元素為0(陣列中有0可以換為-1)
for(int i=0;i //做完此迴圈,c陣列中有了a陣列中的所有元素(小到大排列好了),但每個數字只有乙個,有重複的地方是0
i=n-2;
while(i>=0){ //從後往前掃瞄c陣列,如果碰到0就將其換為其後面的那個元素
if(c[i]==0)
c[i]=c[i+1];
i--;
cout<<"小到大排序後的結果為:"delete b;
delete a;
delete c;
system("pause");
說明:以上**只寫了正整數(除0)的排序;如果a中有元素0,只用在初始化b和c的時候將0改為-1即可;如果a陣列中有負數,在初始化b和c的時候就要將0改為負無窮大了,並且在開始階段將a陣列分為2個陣列,乙個只有負數,乙個只有正數,然後分別考慮即可。
這樣對於數字個數很多,比較集中且不是很大的話,跑得蠻快的。
當然程式是2年前寫的,有些考慮不周,與不規範的地方,現在也沒有太多時間去修改,希望看到的朋友批評指正。
時間複雜度為O n 的排序
題目 某公司有幾萬名員工,請完成乙個時間複雜度為o n 的演算法對該公司員工的年齡作排序,可使用o 1 的輔助空間。分析 排序是面試時經常被提及的一類題目,我們也熟悉其中很多種演算法,諸如插入排序 歸併排序 氣泡排序,快速排序等等。這些排序的演算法,要麼是o n2 的,要麼是o nlogn 的。可是...
時間複雜度為O(n)的排序演算法
我們常用的幾種排序演算法,氣泡排序,選擇排序,它們已經是相對比較簡單,穩定的排序演算法了,但是它們時間複雜度為o n n 基本都要用到兩層迴圈,今天我就像大家介紹一種簡單,只用一層for迴圈,時間複雜度為o n 的排序演算法。樣例輸入 1 4 5 6 3 4 2 8 9 1 樣例輸出 1 1 2 3...
實現排序演算法,時間複雜度為O n
我們常用的排序氣泡排序 o n 2 快速排序o nlogn 堆排序o nlogn 選擇排序o n 2 我們常用的排序都不符合時間複雜度的要求 經常聽說乙個說法 用空間代替時間 現在要排序的陣列為陣列 a 例如a陣列裡面有 1,1,2,2,3,3,2,2,5,5.等等很多無序的數字 那麼我們申請乙個陣...