1、在歸併排序中對小數組採用插入排序(放在上一篇裏了);算法
2、冒泡排序編程
冒泡排序效率幾乎是全部排序裏最低的,但卻很流行,就是由於它的編程複雜度也是最低的。大多數時候,效率還不及插入排序,其實冒泡排序、插入排序、選擇排序基本上效果是差很少的(這個效果不是功能。。功能上講確定差很少啊都是排序),只是過程略有區別。既然寫到這裏,就本身總結一下三者吧。數組
1.插入排序——摸撲克牌的過程函數
假定前一個是有序的,把第二個插進它應當在的位置,那麼前兩個就是有序的了,把第三個插進它應當在的位置,那麼前三個就是有序的了……直到前n個有序。這與打撲克摸牌的時候咱們作的事差很少。優化
時間主要耗費在插入和挪動上了。複雜度n^2。spa
2.冒泡排序——高矮個自行排隊code
首先對最後一我的說:「若是你前面的人比你高,你就和他換一下。」(如今倒數第二我的就是後兩我的裏最矮的了)orm
而後對倒數第二我的說:「若是你前面的人比你高,你就和他換一下。」(如今倒數第三我的就是後三我的裏最矮的了)blog
而後對倒數第三我的說一樣的話……一輪下來,第一我的就是最矮的那個(其實和選擇排序有點像,不過選擇的方式不太同樣,並且排的過程當中就有讓隊列趨向有序的傾向)排序
對後n-1我的執行一樣的過程……直到對最後2我的執行一樣的過程。
時間主要耗費在交換上。複雜度n^2。
3.選擇排序——老師給排隊
首先,老師從全部人裏選一個最矮的,跟第一我的交換位置。而後從後n-1我的裏選一個最矮的,跟第二我的交換位置……直到從後一我的裏選一個最矮的,放在最後。
時間主要耗費在選擇最值上了。複雜度n^2。(後面會有一個堆排序,就是優化了選擇過程,從而實現了nlgn的複雜度)
能夠看出,這三種都是正確的排序算法。下面是冒泡排序的代碼:
#include<stdio.h> void bubblesort(int *a,int l,int r) { int i,j; for (i=l+1;i<=r;i++) { for (j=r;j>=i;j--) { if (a[j]<a[j-1]) { int temp=a[j]; a[j]=a[j-1]; a[j-1]=temp; } } } } int main() { int n; scanf("%d",&n); int a[11]={}; int i; for (i=1;i<=n;i++) { scanf("%d",&a[i]); } bubblesort(a,1,n); for (i=1;i<=n;i++) { printf("%d |",a[i]); } return 0; }
3、霍納規則的正確性
這是一個求多項式函數的值的方法,看完代碼簡直跪了,居然如此簡潔的完成了這個功能!
霍納規則是採用最少的乘法運算策略,求多項式A(x) = anxn+ an-1xn-1+...+ a1x + a0在x0處的值,該規則是A(x0)=(...((anx0+ an-1)x0+...+ a1)x0+ a0)
下面是實現的代碼:
#include<stdio.h> double horner(double *a,int n,double x) { double y=0; int i; for (i=n;i>=0;i--) { y=a[i]+x*y; } return y; } int main() { int n; int i; double x; scanf("%d",&n); double a[11]={}; for (i=0;i<=n;i++) { scanf("%lf",&a[i]); } printf("A(x)="); printf("%.2lf",a[0]); for (i=1;i<=n;i++) { printf("+%.2lfx^%d",a[i],i); } printf("\n"); while (1) { scanf("%lf",&x); printf("A(%.2lf)=%.2lf\n",x,horner(a,n,x)); } return 0; }
4、逆序對問題
先是逆序對的定義:一個n個互異元素的數組a,求知足i<j時a[i]>a[j]條件的數對個數。
輸入:n(元素個數),a數組 輸出:逆序對個數
很容易想到就是逐個比較的n^2的算法,可是算法導論上引導出了nlgn的算法。(修改歸併排序)
首先,若是一個數組的已經知道了,前半部份內部的逆序對的個數k1,後半部分的逆序對的個數k2,而且兩部分都已經由小到大排好序了。那麼在merge的過程當中就能夠順便把兩部分之間的逆序對個數k求出來(由於前半部分比後半部分大的數必定是個逆序對)。那麼總的逆序對的個數就是k1+k2+k。
那麼,怎麼求出前半部分逆序對的個數呢?一樣的方法,求出前半部分,後半部分,兩部分之間。return和。因此就是一個遞歸的問題,只須要修改一下歸併排序便可。
下面是代碼:
#include<stdio.h> int mergenixu(int *a,int *b,int l,int mid,int r) { int k=0; int i=l,j=mid+1; int cou=l; while (i<=mid && j<=r) { if (a[i]<=a[j]) { b[cou]=a[i]; i++; cou++; } else { b[cou]=a[j]; k+=mid-i+1; j++; cou++; } } while (i<=mid) { b[cou]=a[i]; i++; cou++; } while (j<=r) { b[cou]=a[j]; j++; cou++; } for (i=l;i<=r;i++) { a[i]=b[i]; } return k; } int mergesortnixu(int *a,int *b,int l,int r) { if (r-l<1) return 0; int mid=(l+r)/2; int k1=mergesortnixu(a,b,l,mid); int k2=mergesortnixu(a,b,mid+1,r); int k=mergenixu(a,b,l,mid,r); return (k1+k2+k); } int main() { int n; int a[11]={},b[11]={}; scanf("%d",&n); int i; for (i=1;i<=n;i++) { scanf("%d",&a[i]); } int k=mergesortnixu(a,b,1,n); for (i=1;i<=n;i++) { printf("%d |",a[i]); } printf("\n%d",k); return 0; }