自己写代码调用了一下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 }