数据结构—堆

  •  堆的概念

     堆数据结构是一种数组对象,它可以被视为一棵完全二叉树结构。

     堆结构的二叉树存储是最大堆:每个父节点的都大于孩子节点。

     最小堆:每个父节点的都小于孩子节点。

  •   堆的结构
  1 #include <vector>
  2 template<class T>
  3 class Heap
  4 {
  5 public:
  6     Heap();
  7     Heap(const T* array, size_t size)
  8     {
  9         for (size_t i = 0; i < size; i++)
 10         {
 11             _array.push_back(array[i]);
 12         }
 13         //建堆
 14         for (int i = (_array.size() - 2)/2; i >= 0; i--)
 15         {
 16             _AdjustDown(i);
 17         }
 18     }
 19     //插入一个数据x到堆中
 20     void  Push(const T& x)
 21     {
 22         _array.push_back(x);
 23         _AdjustUp(_array.size() - 1);
 24     }
 25     //删除堆顶元素
 26     void Pop()
 27     {
 28         assert(_array.size() > 0);
 29         swap(_array[0], _array[_array.size() - 1]);
 30         _array.pop_back();
 31         _AdjustDown(0);
 32     }
 33     T& GetTop()
 34     {
 35         assert(_array.size() > 0);
 36         return _array[0];
 37     }
 38     //将根节点向下调整
 39     void _AdjustDown(int root)
 40     {
 41         int child = root * 2 + 1;
 42         while (child < _array.size())
 43         {
 44             //比较出左右孩子中大的那个
 45             if (child + 1 < _array.size() && _array[child + 1] > _array[child])
 46             {
 47                 child++;
 48             }
 49             //与根节点相比
 50             if (_array[child]>_array[root])
 51             {
 52                 swap(_array[child], _array[root]);
 53                 root = child;
 54                 child = root * 2 + 1;
 55             }
 56             else
 57             {
 58                 break;
 59             }
 60         }
 61     }
 62     //一个节点向上调整
 63     void _AdjustUp(int child)
 64     {
 65         int parent = (child - 1) / 2;
 66         while (child > 0)
 67         {
 68             if (_array[child] > _array[parent])
 69             {
 70                 swap(_array[child], _array[parent]);
 71                 child = parent;
 72                 parent = (child - 1) / 2;
 73             }
 74             else
 75             {
 76                 break;
 77             }
 78         }
 79     }
 80     void Print()
 81     {
 82         for (size_t i = 0; i < _array.size(); ++i)
 83         {
 84             cout << _array[i] << " ";
 85         }
 86         cout << endl;
 87     }
 88     //判断是否为空
 89     bool Empty()
 90     {
 91         return _array.empty();
 92     }
 93     size_t Size()
 94     {
 95         return _array.size();
 96     }
 97 
 98 public:
 99     vector<T> _array;
100 };
  • 堆的应用:

 100w个数中找出最大的前K个数

 1 //100w个数中找出最大的前k个数
 2 #define M 1000000
 3 #define N 100
 4 void _Adjustdown(int *Ma, int k, int root)
 5 {
 6     int child = root * 2 + 1;
 7     while (child < k)
 8     {
 9         if ((child + 1 )< k&&Ma[child + 1] < Ma[child])
10         {
11             child++;
12         }
13         if (Ma[child] < Ma[root])
14         {
15            swap(Ma[child], Ma[root]);
16            root = child;
17            child = root * 2 + 1;
18         }
19         else
20         {
21             break;
22         }
23     }
24    
25 }
26 int* FindMaxKNum(int* array,int *Ma,int size,int k)
27 {
28     for (int i = 0; i < k; i++)
29     {
30         Ma[i] = array[i];
31     }
32 
33     for (int i = (k - 2) / 2; i >= 0; --i)
34     {
35         _Adjustdown(Ma, k, i);
36     }
37     for (int i = k; i < size; ++i)
38     {
39         if (array[i] > Ma[0])
40         {
41             Ma[0] = array[i];
42             _Adjustdown(Ma, k, 0);
43         }
44     }
45     return Ma;
46 }
47 void TestFindPreKNum()
48 {
49     int *array = new int[M];
50     int *Ma = new int[N];
51     for (int i = 0; i < M; i++)
52     {
53         array[i] = i;
54     }
55 
56     int* ret = FindMaxKNum(array, Ma, M,N);
57     for (int i = 0; i < N; ++i)
58     {
59         cout << *(ret + i) << "  ";
60     }
61     cout << endl;
62     delete []array;
63     delete []Ma;
64 
65 }

 

posted @ 2016-06-07 12:18  A_carat_tear  阅读(253)  评论(0编辑  收藏  举报