Heap sort (C++)

achieve

  1. related information
  • Heap: Heap is a complete binary tree, the value of a node in the heap is always not greater than or not less than the value of its parent node;
    • Maximum heap (big root heap): the heap with the largest root node;
    • Minimal heap (small root heap): the heap with the smallest root node;
  • If a one-dimensional array is regarded as a complete binary tree stored sequentially, it has the following relationship:
    • For any parent node, assuming its subscript is x, the left child (if any) is subscript (2x + 1), and the right child (if any) is subscript (2x + 2).
  • Heap sort: a selection sort. Adjust the array with n elements into a heap (largest heap or smallest heap), take out the top element of the heap (placed at the beginning or end of the array), then re-adjust the remaining n-1 elements to a heap, and take out the heap again The top element, and so on, finally get a sorted array.
  1. Ideas
  • The example in this article is to build the largest pile, arranged in ascending order.
    • The idea is as follows: (the array is a, the number of elements is n)
      • Adjust the array a to the maximum heap, then a[0] is the top element (maximum);
      • Put the top element a[0] of the heap at the end of the array (a[0] is exchanged with a[n -1]);
      • Re-adjust the first n-1 elements to a heap (actually only a[0] may not satisfy the maximum heap at this time);
      • Put the top element a[0] of the heap at the second end of the array (a[0] and a[n -2] swap);
      • By analogy, the final array is arranged in ascending order;
    • In summary, there are actually only two problems that need to be solved:
      • 1 How to adjust the complete binary tree represented by the array to a heap?
      • 2 How to adjust a group of elements whose root node does not satisfy the heap into a heap?
  1. Code
/*
调整为最大堆( 解决问题2)
a为数组,n为元素数,将其看作一颗完全二叉树,s为一颗子树根节点的下标,
对s子树来说,仅s节点可能不满足最大堆,将其调整为最大堆
思路:假设 child = [ s 左右子较大值下标], temp = a[s],   
     (1)若 a[s] >= a[child],则无需调整,直接返回;
     (2)若 a[s] < a[child] :
        则用 a[child] 填充 s 节点;
        s = child, child = [ child 左右子较大值下标],循环(1)(2)
     (3)将 temp 填充到 child 节点。     
*/
void adjust_heap(int a[], int n, int s){
    
    
  int temp = a[s];
  int child = 2*s + 1; // 默认child指向s节点左子
  while(child < n){
    
    
    // s节点右子存在,且右子更大, 则child指向s节点右子
    if ((child + 1 < n -1) && (a[child] < a[child + 1])){
    
    
      child +=1;
    }

    // child节点值填充到s节点
    if (a[s] < a[child]) {
    
    
      a[s] = a[child];
      
      s = child;
      child = 2 * s + 1;
    }else {
    
    
      break;
    }
    a[s] = temp;
  }
}

/*
建最大堆( 解决问题1)
a为数组,n为元素数,将其看作一颗完全二叉树
思路:假设 last_f 为此二叉树中最后一个元素的父节点下标,   
   则 a[0] ~ a[last_f] 均为具有子的父节点,
     (1)将以 a[last_f] 为根节点的子树调整为最大堆(此时可认为子节点满足最大堆,只是last_f不满足);
     (2)将以 a[last_f - 1] 为根节点的子树调整为最大堆;
     (3)依次倒序调整,直到a[0]调整完毕,数组就变成了最大堆存储。
*/
void build_heap(int a[], int n) {
    
    
  if (n < 2){
    
    
    return;
  }

  int last_f = 0; // 最后一个有子节点的父节点
  if (n % 2 == 0){
    
    
    last_f = (n - 1) /2; // n为偶数,最后一个节点为左子节点
  } else {
    
    
    last_f = (n - 3) /2; // n为奇数,最后一个节点为右子节点
  }

  for (int i = last_f; i >=0; --i){
    
    
    adjust_heap(a, n, last_f);
  }
}

void heap_sort(int a[], int n) {
    
    
  // 建最大堆
  build_heap(a, n);
  for (int i = n - 1; i >=0; --i) {
    
    
    // 堆顶节点(a[0])与i节点交换值
    int temp = a[i];
    a[i] = a[0];
    a[0] = temp;

    // 将前i个节点重新调整为最大堆
    adjust_heap(a, i, 0);

    print(a, n);
  }
}

test

  1. Code
#include <iostream>
using namespace std;

void print(int a[], int num) {
    
    
  for (int i = 0; i < num; ++i) {
    
    
    cout << a[i] << " ";
  }
  cout << endl;
}

int main() {
    
    
  int a[] = {
    
    7, 6, 5, 4, 3, 2, 1};
  int n = sizeof(a) / sizeof(a[0]);
  print(a, n);
  heap_sort(a, n);
  print(a, n);
  cin.get();
  return 0;
}
  1. result
7 6 5 4 3 2 1
6 4 5 1 3 2 7
5 4 2 1 3 6 7
4 3 2 1 5 6 7
3 1 2 4 5 6 7
2 1 3 4 5 6 7
1 2 3 4 5 6 7
1 2 3 4 5 6 7
1 2 3 4 5 6 7

Guess you like

Origin blog.csdn.net/luoshabugui/article/details/109390826