c 實現堆排序(由小到大)

2021-09-19 08:38:39 字數 3150 閱讀 4922

這裡實現了兩種堆排序演算法

第一種是:將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 把小於基準值元素的子數列和...