优先队列 (堆实现)

共两部分 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 };
原文地址:https://www.cnblogs.com/sevenPP/p/3624610.html