代碼:ios
void quick_pow(int n,int a[]) { for(int i=0;i<n;i++) { int pos=i; for(int j=i+1;j<n;j++) { if(a[j]<a[pos]) pos=j; } int temp=a[i]; a[i]=a[pos]; a[pos]=temp; } }
這個算法的名字由來是由於越大的元素會經由交換慢慢「浮」到數列的頂端(升序或降序排列),就如同碳酸飲料中二氧化碳的氣泡最終會上浮到頂端同樣,故名「冒泡排序」。算法
void quick_pow(int n,int a[]) { for(int i=0;i<n-1;i++)//n個元素進行n-1次排序 { for(int j=0;j<n-i-1;j++)//每趟排序比較的次數 { if(a[j]>a[j+1]) { int temp=a[j]; a[j]=a[j+1]; a[j+1]=temp; } } } }
插入排序的基本操做就是將一個數據插入到已經排好序的有序數據中,從而獲得一個新的、個數加一的有序數據,算法適用於少許數據的排序數組
void quick_pow(int n,int a[]) { for(int i=1;i<n;i++)//從第二個元素開始插入,[0,i-1]都是有序數據 { int temp=a[i];//要插入的元素 int j; for(j=i-1;j>=0&&temp<a[j];j--) a[j+1]=a[j];//交換位置 a[j+1]=temp; } }
快速排序的本質就是把基準數大的都放在基準數的右邊,把比基準數小的放在基準數的左邊,這樣就找到了基準在數組中的正確位置.
之後採用遞歸的方式分別對前半部分和後半部分排序,當前半部分和後半部分均有序時該數組就天然有序了。優化
int find(int le,int ri,int a[])//找基準元素位置 { int base=a[le];//基準元素 while(le<ri) { while(le<ri&&a[ri]>=base)//從序列右端開始處理,大於基準的不變 ri--; a[le]=a[ri];//小於基準的交換到左邊 while(le<ri&&a[le]<=base)//處理左端,小於基準的不變 le++; a[ri]=a[le];//大於基準的交換到右邊 } //當左邊的元素都小於base,右邊的元素都大於base時,此時base就是基準元素,le或ri就是基準元素的位置 a[le]=base; return le; } void quick_pow(int le,int ri,int a[]) { if(le>=ri) return; int pos=find(le,ri,a); quick_pow(le,pos-1,a); quick_pow(pos+1,ri,a); }
①先從隊尾開始向前掃描且當low < high時,若是a[high] > tmp,則high–,但若是a[high] < tmp,則將high的值賦值給low,即arr[low] = a[high],同時要轉換數組掃描的方式,即須要從隊首開始向隊尾進行掃描了
②同理,當從隊首開始向隊尾進行掃描時,若是a[low] < tmp,則low++,但若是a[low] > tmp了,則就須要將low位置的值賦值給high位置,即arr[low] = arr[high],同時將數組掃描方式換爲由隊尾向隊首進行掃描.
③不斷重複①和②,知道low>=high時(實際上是low=high),low或high的位置就是該基準數據在數組中的正確索引位置.
ui
希爾排序是記錄按下標的必定增量分組,對每組使用直接插入排序算法排序;隨着增量逐漸減小,每組包含的關鍵詞愈來愈多,當增量減至1時,整個文件恰被分紅一組,算法便終止。spa
void quick_pow(int n,int a[]) { for(int k=n/2;k>0;k=k/2)//k是分組距離 { for(int i=k;i<n;i++)//能夠分紅n-k組,輪流對每一個分組進行插入排序 { int temp=a[i];// int j; for(j=i-k;j>=0&&a[j]>temp;j=j-k) a[j+k]=a[j];//前面的元素大於右邊,交換位置, a[j+k]=temp; } } }
歸併排序的核心思想是將兩個有序的數列合併成一個大的有序的序列。經過遞歸,層層合併,即爲歸併。3d
先把總體二分到一,在合併成有序總體code
void merge(int le,int mid,int ri,int a[],int temp[])//將數組a的左右兩部分合並 { int i=le,j=mid+1; int m=mid,n=ri; int k=0; while(i<=m&&j<=n)//a數組兩端更小的先加進temp數組 { if(a[i]<a[j]) temp[k++]=a[i++]; else temp[k++]=a[j++]; } //把a數組剩下的部分加入temp數組 while(i<=m) temp[k++]=a[i++]; while(j<=n) temp[k++]=a[j++]; for(int i=0;i<k;i++)//把有序的temp數組放回a數組 a[le+i]=temp[i]; } void quick_pow(int le,int ri,int a[],int temp[]) { if(le>=ri) return ; int mid=(le+ri)/2; quick_pow(le,mid,a,temp);//使左邊有序 quick_pow(mid+1,ri,a,temp);//右邊有序 merge(le,mid,ri,a,temp);//左右有序的部分合並 }
堆排序能夠說是一種利用堆的概念來排序的選擇排序。分爲兩種方法:blog
大頂堆:每一個節點的值都大於或等於其子節點的值,在堆排序算法中用於升序排列;排序
小頂堆:每一個節點的值都小於或等於其子節點的值,在堆排序算法中用於降序排列;
建立一個堆 H[0……n-1],按照大頂堆的性質從左往右建立;
建立完成以後,先把堆首元素(最大值)拿走,再把堆尾元素(同一層按從右往左順序)放到堆首位置;
堆尾元素放到堆首以後,判斷是否比左右節點元素大,交換使堆頂元素大於左右節點;
重複步驟 2,直到堆的尺寸爲 1。
#include<iostream> #include<algorithm> #include<math.h> #include<string.h> #define ll long long #define M 0x3f3f3f3f3f using namespace std; void quick_pow(int a[],int pos,int len) { int root=a[pos];//頂點 int le=pos*2+1;//由於pos使從0開始,因此是左孩子 while(le<len) { int ri=le+1; if(ri<len&&a[ri]>a[le])//使左孩子大於右孩子 le=ri; if(root<a[le])//使頂點大於左孩子 { a[pos]=a[le]; pos=le; le=pos*2+1; } else break; } a[pos]=root; } void init(int n,int a[]) { for(int i=n/2-1;i>=0;i--)//將數組a初始化爲大頂堆 quick_pow(a,i,n); for(int i=n-1;i>=0;i--)//將堆頂元素和堆尾元素互換,並維護大頂堆的性質 { int temp=a[0];//堆頂元素 a[0]=a[i]; a[i]=temp; quick_pow(a,0,i); } } int main() { int n; int a[105],temp[105]; cin>>n; for(int i=0;i<n;i++) cin>>a[i]; init(n,a); for(int i=0;i<n;i++) cout<<a[i]<<' '; cout<<endl; return 0; }