zoukankan      html  css  js  c++  java
  • 学习堆排序

    自己写代码调用了一下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 }
  • 相关阅读:
    移动端默认meta标签
    css3 变形(transform)、转换(transition)和动画(animation)
    Java_ToolKit用法
    Java_I/O输入输出_实现当用户输入姓名和密码时,将每一个姓名和密码加在文件中,如果用户输入done,就结束程序。
    Java_I/O输入输出_实现读取文件时出现一个表示读取进度的进度条。可以使用java.swing包提供的输入流类ProgressMonitorInputStream
    Java_Swing程序设计_尝试开发一个登陆窗体,包括用户名、密码以及提交按钮和重置按钮,当用户输入用户名my,密码love时,弹出登陆成功提示对话框。
    Eclipse通过jdbc连接oracle数据库
    Java_I/O输入输出_使用输入输出流读取文件,将一段文字加密后存入文件,然后读取,将加密前与后的文件输出
    asp.net缓存机制
    深入理解abstract class和interface
  • 原文地址:https://www.cnblogs.com/zanzan101/p/3329873.html
Copyright © 2011-2022 走看看