学习堆排序

自己写代码调用了一下STL的堆,然后自己也写了一个,还不确定自己的写法是不是和STL的一眼,目前只是非常朴素的实现了而已,有时间比较一下,看看差别:

(似乎make_heap的方式不一样,我是一个一个insert的)

  1 #include <vector>
  2 #include <algorithm>
  3 
  4 using namespace std;
  5 
  6 
  7 // 向上调整
  8 void adjust_up(int* ptr_begin, int idx);
  9 // 插入新元素
 10 void heap_insert(int* ptr_begin, int*& ptr_end, int ele);
 11 // 返回顶元素
 12 int heap_peek(int* ptr_begin, int*& ptr_end);
 13 // 向下调整
 14 void adjust_down(int* ptr_begin, int* ptr_end, int idx);
 15 // 堆排序
 16 void heap_sort(int* ptr_begin, int* ptr_end);
 17 
 18 inline void print_v(vector<int>& v)
 19 {
 20     vector<int>::iterator iter;
 21     for (iter = v.begin(); iter != v.end(); iter++)
 22     {
 23         printf("%d ", *iter);
 24     }
 25     printf("
");
 26 }
 27 inline void print_arr(int* ptr_begin, int* ptr_end)
 28 {    
 29     for(int* iter = ptr_begin; iter != ptr_end; iter++)
 30         printf("%d ", *iter);
 31     printf("
");
 32 }
 33 int main()
 34 {
 35     int arr[10] = {14,16,1,9,27,4,3,5,8,31};
 36     vector<int> v(arr, arr+(sizeof(arr)/sizeof(int)));
 37     print_v(v);
 38     make_heap(v.begin(), v.end());        //建立一个最大堆,亦即:一个完全二叉树,一个用数组存放的完全二叉树
 39     printf("result of make_heap:	");
 40     print_v(v);
 41     pop_heap(v.begin(), v.end());        //把堆顶元素(最大的元素)放到vector尾部,可以通过v.back()取出
 42     printf("result of pop_heap:	");
 43     print_v(v);
 44     make_heap(v.begin(), v.end());
 45     printf("result of make_heap:	");
 46     print_v(v);
 47 
 48     v.push_back(2);                        //放到vector的最后
 49     printf("result of push_back:	");
 50     print_v(v);
 51     push_heap(v.begin(), v.end());        //把vector最后一个元素插入到整个heap中
 52     printf("result of push_heap:	");
 53     print_v(v);
 54     pop_heap(v.begin(), v.end());        //把堆顶元素(最大的元素)放到vector的最后
 55     printf("result of pop_heap:	");
 56     print_v(v);
 57 
 58     // 用自己写的方法
 59     int my_heap[100];
 60     int* end_of_heap = my_heap;
 61     int len = sizeof(arr)/sizeof(int);
 62     for(int i = 0; i < len; i++)
 63     {
 64         heap_insert(my_heap, end_of_heap, arr[i]);
 65     }
 66 
 67     printf("my function:
");
 68     printf("insert into the heap:	");
 69     print_arr(my_heap, end_of_heap);                    
 70     heap_insert(my_heap, end_of_heap, 2);                            //插入新元素后的堆
 71     printf("result of heap_insert:	");
 72     print_arr(my_heap, end_of_heap);                    
 73     
 74     // 循环取出堆顶元素
 75     while (my_heap != end_of_heap)
 76     {
 77         printf("top of heap :	%d
", heap_peek(my_heap, end_of_heap));    //取出堆顶元素
 78         printf("result of heap_peek:	");
 79         print_arr(my_heap, end_of_heap);    
 80     }
 81 
 82     // 堆排序
 83     int* end_of_arr = arr + sizeof(arr)/sizeof(int);
 84     heap_sort(arr, end_of_arr);
 85     printf("堆排序结果:	");
 86     print_arr(arr, end_of_arr);
 87 
 88 
 89     getchar();
 90     return 0;
 91 }
 92 
 93 // 堆排序
 94 void heap_sort(int* ptr_begin, int* ptr_end)
 95 {
 96     // 不知道真的堆排序是不是这么写的,感觉不应该这样,有时间的话看一下
 97     int* ptr_tmp = ptr_begin;
 98     while (ptr_tmp != ptr_end)
 99     {
100         heap_insert(ptr_begin, ptr_tmp, *ptr_tmp);
101     }
102     while(ptr_begin != ptr_tmp)
103     {
104         heap_peek(ptr_begin, ptr_tmp);
105     }
106 }
107 
108 // 将尾部元素上移
109 void adjust_up(int* ptr_begin, int idx)
110 {
111     if(idx <= 0)
112         return;
113     int parent_idx = (idx+1)/2 - 1;
114     if(ptr_begin[parent_idx] < ptr_begin[idx])
115     {
116         swap(ptr_begin[parent_idx], ptr_begin[idx]);
117         adjust_up(ptr_begin, parent_idx);
118     }
119 }
120 
121 // 插入新元素
122 void heap_insert(int* ptr_begin, int*& ptr_end, int ele)
123 {
124     int idx = ptr_end - ptr_begin;
125     *ptr_end++ = ele;
126     adjust_up(ptr_begin, idx);    
127 }
128 
129 // 返回顶元素
130 int heap_peek(int* ptr_begin, int*& ptr_end)
131 {
132     int tmp = *ptr_begin;
133     *ptr_begin = *(--ptr_end);
134     *ptr_end = tmp;
135     adjust_down(ptr_begin, ptr_end, 0);
136     return tmp;
137 }
138 
139 // 将首元素下移
140 void adjust_down(int* ptr_begin, int* ptr_end, int idx)
141 {
142     int len = ptr_end - ptr_begin;
143     if(idx >= len)
144         return;
145     int tmp = *ptr_begin;
146     int left_idx = (idx+1)*2 - 1;
147     int right_idx = (idx+1)*2;
148     if (left_idx >= len)
149     {
150         return;
151     }else if(right_idx >= len)
152     {
153         if (ptr_begin[idx] < ptr_begin[left_idx])
154         {
155             swap(ptr_begin[idx], ptr_begin[left_idx]);
156             adjust_down(ptr_begin, ptr_end, left_idx);
157         }
158     }else
159     {
160         if (ptr_begin[left_idx] > ptr_begin[right_idx])
161         {
162             if (ptr_begin[idx] < ptr_begin[left_idx])
163             {
164                 swap(ptr_begin[idx], ptr_begin[left_idx]);
165                 adjust_down(ptr_begin, ptr_end, left_idx);
166             }
167         } 
168         else
169         {
170             if (ptr_begin[idx] < ptr_begin[right_idx])
171             {
172                 swap(ptr_begin[idx], ptr_begin[right_idx]);
173                 adjust_down(ptr_begin, ptr_end, right_idx);
174             }
175         }
176     }
177 }
原文地址:https://www.cnblogs.com/zanzan101/p/3329873.html