1.歸併排序數組
分析:安全
歸併排序使用分治思想,原理是ui
①將一個無序數列分紅兩個序列後,對序列進行排序後,再將兩個有序序列合併成一個有序序列;code
②分開的兩個序列又能夠進行再分排序而後合併從而造成問題的子問題。排序
#include <stdio.h> #include <stdlib.h> void merge(int *a, int *ans, int s, int m, int t){ int ak, bk, ansk; ak = s, bk = m+1, ansk = s; while(ak<=m&&bk<=t){ *(ans+ansk++) = (*(a+ak)<*(a+bk))?*(a+ak++):*(a+bk++); } for(; ak<=m; ak++){ *(ans+ansk++) = *(a+ak); } for(; bk<=t; bk++){ *(ans+ansk++) = *(a+bk); } } void mergesort(int *a, int n, int low, int high, int *ans){ int mid; int *temp; temp = (int*)malloc(sizeof(int)*n); //save the result of sort if(low==high){ *(ans+low) = *(a+low); return; } mid = (low+high)/2; //sort a[low...mid] mergesort(a, n, low, mid, temp); //sort a[mid+1, high] mergesort(a, n, mid+1, high, temp); //merge temp[low...mid] temp[mid+1, high] into ans[low...high] merge(temp, ans, low, mid, high); free(temp); } int main(void){ int data[] = {2,4,8,5,1,6,3,10,9}; int n = sizeof(data)/sizeof(int); int ansk; int *ans = (int*)malloc(sizeof(int)*n); int *temp = (int*)malloc(sizeof(int)*n); mergesort(data, n, 0, n-1, ans); for(ansk=0; ansk<n; ansk++){ printf("%d ", *(ans+ansk)); } printf("\n"); return 0; }
2.堆排序it
分析:io
①將無序數列視爲一棵徹底二叉樹的節點,並以層逐個加入樹中,樹的節點數/2的節點必有孩子;class
②堆排序(結果須要從小到大排序)旨在將最大值元素移至樹根處,並將其與樹最後節點交換便可;原理
③對於一個結點,須要知足一個條件a[i]>a[2*i]和a[i]>a[2*i+1];二叉樹
④當一個結點與其孩子交換後,須要對交換的孩子向下調整,保證知足條件③;
因此堆排序的步驟則爲:
1)由無序數組視爲一棵無安全二叉樹的節點,從擁有孩子的節點開始,先對該樹進行調整,使其知足條件③,此時造成大頂堆;
2)樹根結點與樹最後節點交換後,因爲已經造成大頂堆,因此第二大的元素必爲根結點的孩子,因此只須要進行向下調整便可將最大元素置於根結點位置;假設第二大元素不爲根結點孩子,那麼必然位於根結點孩子的左或右子樹,而因爲第三個條件,子樹的根結點必爲最大,因此一定不知足條件③。
#include <stdio.h> #include <stdlib.h> void swap(int *a, int *b){ int temp; temp = *a; *a = *b; *b = temp; } void heapadjust(int *data, int n, int i){ //downward adjustment int k; int max; for(k=i+1; k<=n/2; k++){ //compare root,lchild,rchild max = (*(data+k-1)>*(data+2*k-1))?k-1:2*k-1; if(2*k<n) max = (*(data+max)>*(data+2*k))?max:2*k; if(max==k-1) continue; else{ swap(data+k-1, data+max); heapadjust(data, n, max); } } } void heapsort(int n, int *data){ int k; for(k=0; k<n; k++){ swap(data, data+n-k-1); heapadjust(data, n-k-1, 0); } } int main(void){ int data[]={5,4,3,2,1}; int k; int n=sizeof(data)/sizeof(int); for(k=n/2; k>=0; k--) heapadjust(data, n, 0); //initialize heap heapsort(n, data); for(k=0; k<n; k++){ printf("%d ", *(data+k)); } printf("\n"); return 0; }
3.快速排序
分析:
①尋找位置s,將無序數列第一個元素放置於as,使得as>aj (t<j<s),as<ai (n>i>s);
②對無序數列at,...,as-1和as+1,...,an重複步驟①便可,知道t=s-1或s+1=n位置。
#include <stdio.h> #include <stdlib.h> void swap(int *a, int *b){ int temp; temp = *a; *a = *b; *b = temp; } int find_mid(int *d, int low, int high){ int k; while(low<high){ while(*(d+low)<*(d+high)&&low<high) high--; swap(d+low, d+high); while(*(d+low)<*(d+high)&&low<high) low++; swap(d+low, d+high); } return low; } void quicksort(int *d, int low, int high){ int mid; if(low<high){ mid = find_mid(d, low, high); quicksort(d, low, mid-1); quicksort(d, mid+1, high); } } int main(void){ int data[] = {5,9,7,8,2,4,6,3,1}; int n = sizeof(data)/sizeof(int); int k; quicksort(data, 0, n-1); for(k=0; k<n; k++) printf("%d ", *(data+k)); printf("\n"); return 0; }