堆排序、快速排序
時間復雜度一樣的都是O(nlog2 n),但貌似堆排序用到的空間比快速排序少(只要一個),那么為什么好像快速排序的應用比堆排序多?
?
?
堆排序
#include <iostream>
using namespace std;
void Swap(int & left_data, int & right_data)
{
? ? int auxiliary = left_data;
? ? left_data = right_data;
? ? right_data = auxiliary;
}
//----------------------------------------------------------------------------------
// 小頂堆
// 從i開始,到其父節點,父節點的父節點...,依次檢查、調整以符合“小頂堆”的性質
void MinHeapAdjustUp(int data[], int i)
{
? ? if (i <= 0)
? ? ? ? return;
? ? int j, auxiliary;
? ? auxiliary = data[i];
? ? j = (i - 1) / 2; // 父結點
? ? while (j >= 0 && i != 0)
? ? {
? ? ? ? if (data[j] <= auxiliary)
? ? ? ? ? ? break;
? ? ? ? data[i] = data[j]; // 較大結點下移,替換它的子結點 ?
? ? ? ? i = j;
? ? ? ? j = (i - 1) / 2;
? ? } ?
? ? data[i] = auxiliary;
}
// 向“小頂堆”中添加新的數據
// 每次插入都是將新數據放在數組最后,然后從新插入數據開始,
// 到其父節點,父節點的父節點...,依次檢查、調整以符合“小頂堆”的性質
void MinHeapAddData(int data[], int count, int new_data)
{ ?
? ? data[count] = new_data;
? ? MinHeapAdjustUp(data, count);
}
// 從i節點開始,進行一次從上向下的“小頂堆”調整
// count為節點總數,i節點的左右孩子節點依次為 2*i+1, 2*i+2
void MinHeapAdjustDown(int data[], int i, int count)
{
? ? int j, auxiliary;
? ? auxiliary = data[i];
? ? j = 2 * i + 1; // 左孩子結點
? ? while (j < count)
? ? {
? ? ? ? if (j + 1 < count && data[j + 1] < data[j]) // 在左右孩子中找最小的
? ? ? ? ? ? j++;
? ? ? ? if (data[j] >= auxiliary)
? ? ? ? ? ? break;
? ? ? ? data[i] = data[j]; // 把較小的子結點往上移動,替換它的父結點
? ? ? ? i = j;
? ? ? ? j = 2 * i + 1;
? ? }
? ? data[i] = auxiliary;
}
// 從“小頂堆”中刪除數據
// 堆中每次都只能刪除第0個數據。為便于重建堆,將最后一個數據的值賦給根結點
// 然后再從根結點開始進行一次從上向下的調整
void MinHeapDeleteData(int data[], int count)
{
? ? Swap(data[0], data[count - 1]);
? ? MinHeapAdjustDown(data, 0, count - 1);
}
// 建立“小頂堆”
// 因為對葉子結點來說,它已經是一個合法的“小頂堆”
// 所以這里只需要,從下往上,從右到左,將每個“非葉結點”當作根結點,將其與其子樹調整成“小頂堆”
void MakeMinHeap(int data[], int count)
{
? ? for (int i = count / 2 - 1; i >= 0; i--)
? ? ? ? MinHeapAdjustDown(data, i, count);
}
// 堆排序(利用小頂堆,進行降序排序)
void MinHeapSortDesc(int data[], int count)
{
? ? for (int i = count - 1; i >= 1; i--)
? ? {
? ? ? ? Swap(data[i], data[0]);
? ? ? ? MinHeapAdjustDown(data, 0, i);
? ? }
}
//----------------------------------------------------------------------------------
// 大頂堆
// 從i開始,到其父節點,父節點的父節點...,依次檢查、調整以符合“大頂堆”的性質
void MaxHeapAdjustUp(int data[], int i)
{
? ? if (i <= 0)
? ? ? ? return;
? ? int j, auxiliary;
? ? auxiliary = data[i];
? ? j = (i - 1) / 2; // 父結點
? ? while (j >= 0 && i != 0)
? ? {
? ? ? ? if (data[j] >= auxiliary)
? ? ? ? ? ? break;
? ? ? ? data[i] = data[j]; // 較小結點下移,替換它的子結點 ?
? ? ? ? i = j;
? ? ? ? j = (i - 1) / 2;
? ? } ?
? ? data[i] = auxiliary;
}
// 向“大頂堆”中添加新的數據
// 每次插入都是將新數據放在數組最后,然后從新插入數據開始,
// 到其父節點,父節點的父節點...,依次檢查、調整以符合“大頂堆”的性質
void MaxHeapAddData(int data[], int count, int new_data)
{ ?
? ? data[count] = new_data;
? ? MaxHeapAdjustUp(data, count);
}
// 從i節點開始,進行一次從上向下的“大頂堆”調整
// count為節點總數,i節點的左右孩子節點依次為 2*i+1, 2*i+2
void MaxHeapAdjustDown(int data[], int i, int count)
{
? ? int j, auxiliary;
? ? auxiliary = data[i];
? ? j = 2 * i + 1; // 左孩子結點
? ? while (j < count)
? ? {
? ? ? ? if (j + 1 < count && data[j + 1] > data[j]) // 在左右孩子中找最大的
? ? ? ? ? ? j++;
? ? ? ? if (data[j] <= auxiliary)
? ? ? ? ? ? break;
? ? ? ? data[i] = data[j]; // 把較大的子結點往上移動,替換它的父結點
? ? ? ? i = j;
? ? ? ? j = 2 * i + 1;
? ? }
? ? data[i] = auxiliary;
}
// 從“大頂堆”中刪除數據
// 堆中每次都只能刪除第0個數據。為便于重建堆,將最后一個數據的值賦給根結點
// 然后再從根結點開始進行一次從上向下的調整
void MaxHeapDeleteData(int data[], int count)
{
? ? Swap(data[0], data[count - 1]);
? ? MaxHeapAdjustDown(data, 0, count - 1);
}
// 建立“大頂堆”
// 因為對葉子結點來說,它已經是一個合法的“大頂堆”
// 所以這里只需要,從下往上,從右到左,將每個“非葉結點”當作根結點,將其與其子樹調整成“大頂堆”
void MakeMaxHeap(int data[], int count)
{
? ? for (int i = count / 2 - 1; i >= 0; i--)
? ? ? ? MaxHeapAdjustDown(data, i, count);
}
// 堆排序(利用小頂堆,進行降序排序)
void MaxHeapSortAsc(int data[], int count)
{
? ? for (int i = count - 1; i >= 1; i--)
? ? {
? ? ? ? Swap(data[i], data[0]);
? ? ? ? MaxHeapAdjustDown(data, 0, i);
? ? }
}
int main()
{
? ? int array[] = {9, 6, 3, 8, 7, 1, 5, 2, 4};
? ? MakeMinHeap(array, 9);
? ? MinHeapSortDesc(array, 9);
? ? for(int i = 0; i < 9; ++i)
? ? ? ? cout << array[i] << " ";
? ? cout << endl;
? ? MakeMaxHeap(array, 9);
? ? MaxHeapSortAsc(array, 9);
? ? for(int i = 0; i < 9; ++i)
? ? ? ? cout << array[i] << " ";
? ? cout << endl;
? ? return 0;
}
?
快速排序?
#include <stdio.h>
#include <stdlib.h>
int get_pos(int *a,int low,int high);
void quick_sort(int *a,int low,int high);
int main(int argc,char*argv[])
{
?? ?int i;
?? ?int a[10]={2,1,4,7,5,9,0,3,6,8};
?? ?quick_sort(a,0,9);
?? ?for(i=0;i<10;i++)
?? ??? ?printf("%d ",a[i]);
?? ?printf("\n");
?? ?return 0;
}
void quick_sort(int *a,int low,int high)
{
?? ?int pos;
?? ?if(low<high)
?? ?{
?? ??? ?pos = get_pos(a,low,high);
?? ??? ?quick_sort(a,0,pos-1);
?? ??? ?quick_sort(a,pos+1,high);
?? ?}
}
int get_pos(int *a,int low,int high)
{
?? ?int value=a[low];
?? ?while(low < high)
?? ?{
?? ??? ?while(low<high && value<=a[high])
?? ??? ??? ?high--;
?? ??? ?a[low]=a[high];
?? ??? ?while(low < high && value>=a[low])
?? ??? ??? ?low++;
?? ??? ?a[high] = a[low];
?? ?}
?? ?a[low]=value;
?? ?return low;
}
總結
- 上一篇: 树:二叉树的非递归遍历算法
- 下一篇: OD-标志寄存器判断语句对照表(汇编标志