二、氣泡排序
氣泡排序效率幾乎是所有排序裡最低的,但卻很流行,就是因為它的程式設計複雜度也是最低的。大多數時候,效率還不及插入排序,其實氣泡排序、插入排序、選擇排序基本上效果是差不多的(這個效果不是功能。。功能上講肯定差不多啊都是排序),只是過程略有區別。既然寫到這裡,就自己總結一下三者吧。
1.插入排序——摸撲克牌的過程
假定前乙個是有序的,把第二個插進它應當在的位置,那麼前兩個就是有序的了,把第三個插進它應當在的位置,那麼前三個就是有序的了……直到前n個有序。這與打撲克摸牌的時候我們做的事差不多。
時間主要耗費在插入和挪動上了。複雜度n^2。
2.氣泡排序——高矮個自行排隊
首先對最後乙個人說:「如果你前面的人比你高,你就和他換一下。」(現在倒數第二個人就是後兩個人裡最矮的了)
然後對倒數第二個人說:「如果你前面的人比你高,你就和他換一下。」(現在倒數第三個人就是後三個人裡最矮的了)
然後對倒數第三個人說同樣的話……一輪下來,第乙個人就是最矮的那個(其實和選擇排序有點像,不過選擇的方式不太一樣,而且排的過程中就有讓佇列趨向有序的傾向)
對後n-1個人執行同樣的過程……直到對最後2個人執行同樣的過程。
時間主要耗費在交換上。複雜度n^2。
3.選擇排序——老師給排隊
首先,老師從所有人裡選乙個最矮的,跟第乙個人交換位置。然後從後n-1個人裡選乙個最矮的,跟第二個人交換位置……直到從後乙個人裡選乙個最矮的,放在最後。
時間主要耗費在選擇最值上了。複雜度n^2。(後面會有乙個堆排序,就是優化了選擇過程,從而實現了nlgn的複雜度)
可以看出,這三種都是正確的排序演算法。下面是氣泡排序的**:
#includevoid bubblesort(int *a,int l,intr) }
}}int
main()
;
inti;
for (i=1;i<=n;i++)
bubblesort(a,
1,n);
for (i=1;i<=n;i++)
return0;
}
三、霍納規則的正確性
這是乙個求多項式函式的值的方法,看完**簡直跪了,竟然如此簡潔的完成了這個功能!
霍納規則是採用最少的乘法運算策略,求多項式a(x) = anxn+ an-1xn-1+...+ a1x + a0在x0處的值,該規則是a(x0)=(...((anx0+ an-1)x0+...+ a1)x0+ a0)
下面是實現的**:
#includedouble horner(double *a,int n,doublex)
returny;}
intmain()
;
for (i=0;i<=n;i++)
printf(
"a(x)=");
printf(
"%.2lf
",a[0
]);
for (i=1;i<=n;i++)
printf("\n
");while (1
)
return0;
}
四、逆序對問題
先是逆序對的定義:乙個n個互異元素的陣列a,求滿足ia[j]條件的數對個數。
輸入:n(元素個數),a陣列輸出:逆序對個數
很容易想到就是逐個比較的n^2的演算法,但是演算法導論上引導出了nlgn的演算法。(修改歸併排序)
首先,如果乙個陣列的已經知道了,前半部分內部的逆序對的個數k1,後半部分的逆序對的個數k2,並且兩部分都已經由小到大排好序了。那麼在merge的過程中就可以順便把兩部分之間的逆序對個數k求出來(因為前半部分比後半部分大的數一定是個逆序對)。那麼總的逆序對的個數就是k1+k2+k。
那麼,怎麼求出前半部分逆序對的個數呢?同樣的方法,求出前半部分,後半部分,兩部分之間。return和。所以就是乙個遞迴的問題,只需要修改一下歸併排序即可。
下面是**:
#includeint mergenixu(int *a,int *b,int l,int mid,intr)
else
}while (i<=mid)
while (j<=r)
for (i=l;i<=r;i++)
returnk;}
int mergesortnixu(int *a,int *b,int l,int
r)int
main()
,b[11]={};
scanf("%d
",&n);
inti;
for (i=1;i<=n;i++)
int k=mergesortnixu(a,b,1
,n);
for (i=1;i<=n;i++)
printf(
"\n%d
",k);
return0;
}
演算法導論上幾個簡單的習題
5.1 2 用random 0,1 來實現random a,b 並估計執行時間.這個cu上面有討論。我想了乙個超級白痴的 random a,b random 0,1 b a a 不曉得cu上搞得這麼複雜。怪也 5.1 3 假設你希望以各1 2的概率輸出0和1。你可以自由使用乙個輸出0和1的過程bia...
演算法導論 2 隨機演算法習題選
演算法導論裡的習題,有很多都是經典,不少題目都做不出來,到網路上找答案,再自己慢慢理解,這樣的過程使我受益。我精選了一部分習題,寫出思路作為存檔以供查閱。從這篇博文開始,我嘗試使用mathjax來顯示公式,而不是之前若干篇博文中使用,如果你的瀏覽有什麼問題,請告訴我。前兩題是演算法入門一節挑的,太少...
演算法導論 習題 5 4 1
題 乙個房間裡必須要有多少人,才能讓某人和你生日相同的概率至少為1 2?必須要有多少人,才能讓至少兩個人生日為7月4日的概率大於1 2?解 1.假設一年有n 365 天,房間裡面有x人 不算自己 為求某人與自己生日相同,可求其反面,即房間裡面沒人跟自己生日相同,他們每個人生日可以在n天中選擇除去我生...