• 优先队列 (堆实现)


    共两部分 C 实现 & C++类的编写

    -------------------------------------C实现------------------------------------------

    1 通过堆的性质 编写优先队列

    2 堆中的元素可根据实际需要 存储相应的值(可以是指针,结构体 或者 是一个对象),

       此处简单起见使用了整数

      1 //保持最大堆性质 参数inode为内部结点 注意结点从1开始,数组从0开始
      2 void MaxHeapify(int array[], int size, int inode)
      3 {
      4     int largest= inode;                //父结点
      5     int left = inode*2;                //左子结点
      6     int right = inode*2+1;            //右子结点
      7 
      8     if (left <= size && array[left-1] > array[largest-1])
      9     {
     10         largest = left;
     11     }
     12     if (right <= size && array[right-1] > array[largest-1])
     13     {
     14         largest = right;
     15     }
     16 
     17     if (largest != inode)                    //父结点小于 左子结点 或者 右子结点
     18     {
     19         int temp = array[inode-1];            //子结点值与父结点值交换
     20         array[inode-1] = array[largest-1];
     21         array[largest-1] = temp;
     22 
     23         MaxHeapify(array, size, largest);    //再次验证被交换的值的子结点是否满足 最大堆性质
     24     }
     25 }
     26 //建立最大堆 使每一个父结点大于子结点
     27 void BuildMaxHeap(int array[],int size)
     28 {
     29     for(int i=size/2; i>0; --i)     //最多有 size/2 个内部结点
     30     {
     31         MaxHeapify(array, size, i);
     32     }
     33 }
     34 //堆排序
     35 void HeapSort(int array[], int size)
     36 {
     37     BuildMaxHeap(array, size);  //建立最大堆  结果是最大值 为根结点
     38     int temp = 0;
     39     int heapSize = size;
     40     for (int i=size; i>1; --i)
     41     {
     42         temp=array[0];                //交换 根结点的值 与 最后面末尾的结点的值 
     43         array[0]=array[i-1];        //此时违背了最大堆的性质
     44         array[i-1] = temp;
     45 
     46         --heapSize;                //保持最大堆的性质之前 先去掉已排好序的元素,即减小堆的大小
     47         MaxHeapify(array, heapSize, 1);
     48     }
     49 };
     50 //返回堆中最大的值
     51 int HeapMax(int array[], int size)
     52 {
     53     return array[0];
     54 }
     55 //去掉并返回堆中最大的值,同时去掉最大值之后仍然保持最大堆的性质
     56 int HeapExtractMax(int array[], int size)
     57 {
     58     if (size < 0)
     59     {
     60         return -1;
     61     }
     62     else if(size == 1)
     63     {
     64         return array[0];
     65     }
     66     
     67     int max = array[0];
     68     array[0] = array[size-1];
     69     --size;
     70     MaxHeapify(array, size, 1);
     71 
     72     return max;
     73 }
     74 
     75 //增加指定关键字的值(此处是通过下标指定关键字,从1开始) 
     76 void HeapIncreaseKey(int array[], int size, int index, int key)
     77 {
     78     if(key<array[index-1])  //指定增加的值必须大于原先的值
     79         return;
     80     array[index-1] = key;
     81 
     82     while(index>1 && array[index/2-1] < array[index-1])
     83     {
     84         int tmp = array[index-1];
     85         array[index-1] = array[index/2-1];
     86         array[index/2-1] = tmp;
     87         index = index/2;
     88     }
     89 }
     90 //删除指定关键字的值,保持最大堆得性质
     91 void HeapDelete(int array[], int size, int index)
     92 {
     93     array[index-1] = array[size-1];
     94     --size;
     95     MaxHeapify(array, size, index); //确保index下的结点满足最大堆性质
     96 
     97     while(index>1 && array[index/2-1] < array[index-1])  //确保index的父结点满足最大堆性质
     98     {
     99         int tmp = array[index-1];
    100         array[index-1] = array[index/2-1];
    101         array[index/2-1] = tmp;
    102         index = index/2;
    103     }
    104 
    105 }
    106 //实现最大堆的插入操作,即给堆中插入新值,并且保持最大堆的性质
    107 void HeapInsert(int array[], int size, int key)
    108 {
    109     size = size+1;            //确保数组足够大不溢出
    110     array[size-1] = 0;        //此处直接复用HeapIncreaseKey,确保函数的性质
    111     HeapIncreaseKey(array, size, size, key);
    112 }
    113 
    114 void main()
    115 {
    116     //_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
    117 
    118     int Array[12] = {4, 1, 3, 2, 16, 9, 10, 14, 8, 7};
    119 
    120     BuildMaxHeap(Array, 10);
    121 
    122     for (int i=0; i<10; ++i)
    123     {
    124         cout << Array[i] << " ";
    125     }
    126     cout << "
    
    HeapMax:" << HeapMax(Array, 10) << endl;
    127 
    128     cout <<"
    HeapExtractMax: " << HeapExtractMax(Array, 10) << endl<<endl;
    129 
    130     HeapIncreaseKey(Array, 9, 2, 20);
    131     for (int i=0; i<9; ++i)
    132     {
    133         cout << Array[i] << " ";
    134     }
    135     HeapInsert(Array, 9, 17);
    136     cout << endl;
    137     for (int i=0; i<10; ++i)
    138     {
    139         cout << Array[i] << " ";
    140     }
    141     HeapDelete(Array, 10, 1);
    142     cout << endl;
    143     for (int i=0; i<10; ++i)
    144     {
    145         cout << Array[i] << " ";
    146     }
    147 
    148     system("pause");
    149 }

    ------------------------------------C++类的编写-----------------------------------

    1 通过C实现可改写成 优先队列的类

    2 改写类的时候,确保抽象接口的一致性

     1 const int SIZE = 100;
     2 class Queue
     3 {
     4 private:
     5     int queue[SIZE];
     6     int count;            //当前队列里的个数
     7     void MaxHeapify(int inode); //向下确保堆的最大性质
     8     void MaxHeapify_check_parent(int inode); //    向上确保堆得最大性质
     9     void BuildMaxHeap();
    10 public:
    11     void HeapSort();
    12     int HeapMax();
    13     int HeapExtractMax();
    14     void HeapIncreaseKey(int index, int key);
    15     void HeapDelete(int index);
    16     void MaxHeapInsert(int key);
    17     bool Empty();
    18 };
  • 相关阅读:
    网页中这 10 种字体的运用方式,不会让人觉得 Low
    如何估算文章阅读时长?
    如何养出一个三十几亿身家的儿子
    2018免费的隐私保护工具
    写一份好的产品说明书
    安装 Ubuntu 19.10 选用 zfs 文件系统
    ESXI常用命令
    Harbor ($docker login) Error saving credentials
    Vue中使用matomo进行访问流量统计的实现
    eslint Cannot read property 'range' of null错误
  • 原文地址:https://www.cnblogs.com/sevenPP/p/3624610.html
Copyright © 2020-2023  润新知