算法踩坑3-堆排序

背景

接上面兩篇文章
算法踩坑-快速排序
算法踩坑2-插入排序

來繼續聊聊最近我寫的一些算法的小例程,這次要聊的是堆排序,是一個時間復雜度為NLogN的算法。

主要從以下幾方面來說的:

  • 堆排序思想
  • 堆排序實現
  • 堆排序優化

堆排序思想

堆排序是基于優先隊列的最大堆或者是最小堆實現的,每次刪除最大堆的頂部元素,然后通過LogN的時間來恢復最大堆的屬性,循環這個步驟,最終得到一個有序的序列來達到排序的目的。

堆排序實現

堆的初始化

PriorityQueue PQ_Initialize(int MaxElements) {
    PriorityQueue H = NULL;
    if (MaxElements < MinPQSize) {
        err(1, "隊列長度小于最小值10");
    }
    H = malloc(sizeof(struct HeapStruct));
    if (NULL == H) {
        err(1, "Out of space");
    }
    H->Elements = malloc((MaxElements + 1) * sizeof(ElementType));
    if (NULL == H->Elements) {
        err(1, "Out of space");
    }
    H->Capacity = MaxElements;
    H->Size = 0;
    H->Elements[0] = MinData;
    return H;
}

堆的插入

void PQ_InsertToMinQueue(ElementType x,PriorityQueue H) {
    if (PQ_IsFull(H)) {
        err(1, "隊列滿,不可插入數據");
    }
    // 最小堆,上慮操作
    int i;
    for (i = ++H->Size; H->Elements[i/2] > x; i /= 2) {
        H->Elements[i] = H->Elements[i/2];
    }
    H->Elements[i] = x;
}

堆的刪除

ElementType PQ_DeleteMin(PriorityQueue H) {
    if (PQ_IsEmpty(H)) {
        err(1, "Empty");
    }

    ElementType MinElem = H->Elements[1];
    
    // 最小堆,最后一個元素放在頂部,下慮操作
    ElementType lastElement = H->Elements[H->Size--];
    
    int i;
    int child;
    for (i = 1; i * 2<=H->Size; i=child) {
        // 找到孩子節點中小的往上移動
        child = i * 2;
        if (child+1 <= H->Size && H->Elements[child+1] < H->Elements[child] ) {
            child += 1;
        }
        if (child <= H->Size && H->Elements[child] < lastElement) {
            H->Elements[i] = H->Elements[child];
        } else {
            break;
        }
    }
    
    // 放到指定位置
    H->Elements[i] = lastElement;
    
    // 最小元素放在最后,
    // 使用堆排序的時候不用增加額外的空間保存排序后的數據,排序后的數據是倒敘的
    H->Elements[H->Size+1] = MinElem;
    
    return MinElem;
}

堆排序優化

使用一般的方式進行堆排序,需要額外的增加O(N)的內存開銷,在刪除頂部元素,并且把最后一個元素歸為的時候,最后一個位置剛好是空出來的,所以可以把刪除的元素放入最后的位置就不需要增加O(N)的內存開銷,達到了空間優化的目的。


    // 放到指定位置
    H->Elements[i] = lastElement;

    // 最小元素放在最后,
    // 使用堆排序的時候不用增加額外的空間保存排序后的數據,排序后的數據是倒敘的
    H->Elements[H->Size+1] = MinElem;

One More Thing

噢!我是算法,點我

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,288評論 25 708
  • 1 序 2016年6月25日夜,帝都,天下著大雨,拖著行李箱和同學在校門口照了最后一張合照,搬離寢室打車去了提前租...
    RichardJieChen閱讀 5,165評論 0 12
  • 四. 走向世界之巔——快速排序 你可能會以為歸并排序是最強的算法了,其實不然。回想一下,歸并的時間效率雖然高,但空...
    Leesper閱讀 1,772評論 9 7
  • 1 收拾行囊準備出發,我對于大學生涯還是有所期待的,總算可以離開待了二十年的小縣城,總算可以離開父母的管束,...
    雨默如嫣閱讀 320評論 0 1
  • 《大學,究竟應該學什么》里面談到,每個新生,乃至大二大三的學生,如果依然在相互對比著各自學校的大小、學校環境的優劣...
    卿言莫棄閱讀 739評論 0 1