這裡實現了兩種堆排序演算法
第一種是:將n個元素逐個插入到乙個空堆中,演算法複雜度為o(nlogn)
第二種是:從第乙個不是葉子節點的元素開始調整堆 演算法複雜度為o(n)
這裡還將堆排序和三路快排,歸併排序做了乙個比較
結果如下:
//優化:從第乙個非葉子節點開始
templatevoid heapsort2(t arr,int n)
int main(int argc, char const *ar**)
heap.h
#ifndef maxheap_h
#define maxheap_h
#includeusing namespace std;
templateclass maxheap
} void shiftdown(int k) }
public:
maxheap(int capacity)
maxheap(item arr, int n)
~maxheap()
int size()
bool isempty()
void insert(item item)
item extractmax()
public:
//老師是用樹的方式列印出元素,我先用陣列列印一下
void testprint()
};// int main(int argc, char const *ar**)
// #endif
merge.h
#ifndef _merge_h
#define _merge_h
template void inserectsort(t arr,int l, int r)
return;
}template //最後大合併 將arr[l,mid] 和 arr[mid+1,r]兩部分進行歸併
void __merge(t arr,int l,int mid,int r)
else if( j > r)
else if(aux[i - l] < aux[j-l])
else
}}templatevoid __mergesort(t arr,int l,int r)
int mid = (r+l)/2; //當r和l很大時會溢位
__mergesort(arr,l,mid); //突然明白原來是這個意思,也就是分到最後,每一次歸併都需要乙個輔助陣列
//雖然空間開銷很明顯會更大,但是由於我們更關注時間開銷,所以這種演算法我們才優先採用
__mergesort(arr,mid+1,r);
//在歸併前線判斷一下是否已經有序了
if( arr[mid] > arr[mid+1] )
__merge(arr,l,mid,r);
}//嗷嗷嗷,原來是通過這種方法解決了介面不統一的問題啊
templatevoid mergesort(t arr,int n)
#endif
quicksort.h
#ifndef _quicksort_h
#define _quicksort_h
#includeusing namespace std;
//三路快速排序
#include "sorttesthelper.h"
template void insertionsort(t arr,int l,int r)
arr[j] = e;
} return;
}template void __quicksort3ways(t arr, int l, int r)
//partition
swap( arr[l], arr[rand()%(r-l+1)+l] );
t v = arr[l];
int lt = l; //arr[l+1...lt] < v
int gt = r + 1; //arr[gt...r] > v
int i = l+1;//arr[lt+1,...i] = v
while( i < gt )
else if( arr[i] > v)
else
}swap( arr[l] , arr[lt]);
__quicksort3ways(arr, l, lt-1);
__quicksort3ways(arr, gt, r);
}template void quicksort3ways(t arr,int n)
#endif
sorttesthelper.h
#ifndef sorttesthelper_h
#define sorttesthelper_h
#include#include#includeusing namespace std;
namespace sorttesthelper
int* generatenearlyorderedarray(int n,int swaptimes)
return arr;
} templatevoid printarray(t arr,int n)
template bool issorted(t arr,int n)
templatevoid testsort(string sortname,void(*sort)(t,int),t arr,int n)
//可以將其改為模版函式 但有深拷貝問題
int* copyintarray(int a,int n)
}#endif
堆排序分析(大根堆為例,由小到大排序)
時間複雜度為o nlogn 思路就是從最後乙個非葉結點開始,依次往回遍歷每個結點,將以該結點為根的子樹建立成大根堆,直到遍歷到整棵完全二叉樹的根結點時為止,此時整棵樹為大根堆。以當前結點為根的子樹建立大根堆 向下調整,將該結點的子樹變成大根堆 void adjustdown int a,int k,...
010 3個數由小到大排序
核心演算法 借助於中間變數,使3個變數中存放的資料兩兩比較,兩兩交換,先確定乙個最值,再比較另外兩個的大小,使最終a中存放的數值最小,c中存放的數值最大,則按a,b,c的順序輸出就是按3個數公升序排列。注意 因為c程式整體上是順序結構,而3個數總共有三次兩兩比較,往往是先確定三者中的乙個最值,再比較...
c 實現快速排序 從小到大
從數列中挑出乙個元素,稱為 基準 pivot 重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的後面 相同的數可以到任一邊 在這個分割槽退出之後,該基準就處於數列的中間位置。這個稱為分割槽 partition 操作 遞迴地 recursive 把小於基準值元素的子數列和...