nlogn的排序:堆排,快排,歸併
堆排序(英語:Heapsort)是指利用堆這種數據結構所設計的一種排序算法。堆是一個近似完全二叉樹的結構,並同時滿足堆積的性質:即子結點的鍵值或索引總是小於(或者大於)它的父節點。
void adjustHeap(int a[], int i, int size)
{
//int max;
int l = 2 * i + 1;
int r = 2 * i + 2;
int max = i;
//vs 2017 會檢測&&右邊的,故不能將l < size&& a[l] > a[max]書寫
if (l < size) {
if ( a[l] > a[max])
max = l;
}
if (r < size) {
if ( a[r] > a[max])
max = r;
}
if (max != i)
{
::std::swap(a[i], a[max]);
adjustHeap(a, max, size);
}
}
void heapSort(int a[],int size)
{
for (int i = size / 2 - 1; i >=0; i--)
{
adjustHeap(a, i, size);
}
for (int i = size-1;i >= 0; i--)
{
swap(a[0], a[i]);
adjustHeap(a, 0, i);
}
}
冒泡排序(Bubble Sort),是一種計算機科學領域的較簡單的排序算法。
它重複地走訪過要排序的元素列,依次比較兩個相鄰的元素,如果他們的順序(如從大到小、首字母從A到Z)錯誤就把他們交換過來。走訪元素的工作是重複地進行直到沒有相鄰元素需要交換,也就是說該元素列已經排序完成。
這個算法的名字由來是因爲越大的元素會經由交換慢慢“浮”到數列的頂端(升序或降序排列),就如同碳酸飲料中二氧化碳的氣泡最終會上浮到頂端一樣,故名“冒泡排序”。
void bubbleSort(int a[], int size)
{
for (int i = 0; i < size - 1; i++)
{
for (int j = 0; j < size - i - 1; j++)
{
if (a[j] > a[j + 1])
::std::swap(a[j + 1], a[j]);
}
}
}
快速排序(Quicksort):通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然後再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。
快速排序(Quicksort)是對冒泡排序的一種改進。
int quickSortPart(int a[],int left,int right)
{
int temp = a[right];
while (left<right)
{
while (left<right&&a[left]<temp )
{
left++;
}
a[right] = a[left];
while (left < right&&a[right] >=temp)
{
right--;
}
a[left] = a[right];
}
a[right] = temp;
return right;
}
void quickSort(int a[], int left, int right)
{
if (left<right)
{
int mid = quickSortPart(a, left, right);
quickSort(a, left, mid - 1);
quickSort(a, mid + 1, right);
}
}
歸併排序(MERGE-SORT)是建立在歸併操作上的一種有效的排序算法,該算法是採用分治法(Divide and Conquer)的一個非常典型的應用。將已有序的子序列合併,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。若將兩個有序表合併成一個有序表,稱爲二路歸併。
void MergeData(int* arr, int left, int mid, int right, int* tmp) {
int index = left;
int p = left, q = mid; // 雙指針遍歷
// 待排區間===[left , right)
// 左有序區間[left, mid) 右有序區間[mid, right)
while (p < mid && q < right) {
if (arr[p] <= arr[q]) {
tmp[index++] = arr[p++];
}
else {
tmp[index++] = arr[q++];
}
}
while (p < mid) {
tmp[index++] = arr[p++];
}
while (q < right) {
tmp[index++] = arr[q++];
}
for (int i = left; i < right; i++) {
// [left, right)內的數列已全部有序
arr[i] = tmp[i];
}
}
void _MergeSort(int* arr, int left, int right, int* tmp) {
if (right - left > 1) {
int mid = left + ((right - left) >> 1);
// 1.排左區間
_MergeSort(arr, left, mid, tmp);
// 2.排右區間
_MergeSort(arr, mid, right, tmp);
// 3.歸併
MergeData(arr, left, mid, right, tmp);
}
}
void MergeSort(int* arr, int size) {
int* tmp = (int*)malloc(sizeof(int) * size);
if (tmp == NULL) {
cout<<"error"<<endl;
return;
}
_MergeSort(arr, 0, size, tmp);
free(tmp);
}