前面介紹了插入排序和shell排序,今天我們來看看堆排序和歸併排序。
說起堆排序,先來說一下堆。堆分為大根堆和小根堆,大根堆就是一顆雙親節點元素大於孩子節點元素的二叉樹,小根堆正好相反,是一顆雙親節點的元素小於孩子節點元素的二叉樹。
**堆排序的思想是先利用資料建立大根堆,然後再將根元素放置最後儲存起來,然後不斷調整大根堆,將新的跟插入到舊根的前面,直至將最後乙個元素儲存,這樣儲存的元素將會是有序的。****如下:
static void heapadjust(int *arr, int start, int end)//o(logn)
//i儲存左右孩子較大值的下標
if (arr[i] > tmp)
else
}arr[parent] = tmp;
}void heapsort(int *arr, int len)//o(nlogn) o(1) 不穩定
int tmp;
for (i = 0; i < len - 1; i++)
}
比起堆排序,歸併排序的演算法更加好理解。**歸併排序演算法的思想是將所有元素兩兩分組,使其組內有序,再將分組寬度變為原來的2倍,在使之組內有序,以此類推,最後使所有元素排列有序的過程。****如下:
//歸併排序
static void merge(int *arr, int len, int gap)//o(n) o(n)
else
}//乙個歸併段沒有資料,另乙個還有
while (low1 <= high1)
while (low2 <= high2)
low1 = high2 + 1;
high1 = low1 + gap - 1;
low2 = high1 + 1;
high2 = low2 + gap - 1 < len - 1 ? low2 + gap - 1 : len - 1;
} //不足兩個歸併段
while (low1 < len)
for (int i = 0; i < len; i++)
free(brr);
}void mergesort(int *arr, int len)//o(nlogn)
}
歸併排序和堆排序
歸併排序的演算法我們通常用遞迴實現,先把待排序區間 s,t 以中點二分,接著把左邊子區間排序,再把右邊子區間排序,最後把左區間和右區間用一次歸併操作合併成有序的區間 s,t 桶排序法,非常耗空間。規定陣列中元素的最大值不超過陣列的長度,否則要先求出陣列元素的最大值後,才能指定空桶的個數,要求待排序陣...
堆排序和歸併排序
極少涉及,在此就不再研究 了!堆排序 原理 把待排序的元素按照大小在二叉樹位置上排列,排序好的元素要滿足 父節點的元素要大於等於子節點 這個過程叫做堆化過程,如果根節點存放的是最大的數,則叫做大根堆,如果是最小的數,則叫做小根堆,可以把根節點拿出來,然後再堆化,迴圈到最後乙個節點。時間複雜度 平均 ...
堆排序 快速排序 歸併排序總結
二分查詢及其擴充套件應用場景 大端和小端的問題 2012 09 21 11 33 41 分類 演算法 資料結構 標籤 演算法資料結構 歸併排序 內部排序面試 舉報 字型大小大中小 訂閱這三個排序以前都寫過,快速排序還寫了遞迴版和迭代版。現在在這裡做一下總結。堆排序 heap sort 堆排序是一種樹...