《编程珠玑》阅读小记(11)

章节简述

本章主要介绍堆,用该数据结构解决下面两个重要的问题:

排序,采用堆排序算法对n元数组排序,所花的时间不会超过O(nlogn),而且只需要几个字的额外空间;优先级队列,堆通过插入新元素和提取最小元素这两种操作来维护元素集合,每个操作所需的时间都为O(logn);

本章采用自底向上的组织结构,从细节开始逐步过渡到正题。

堆数据结构

该部分介绍堆数据结构的设计思想。

优先级队列实现向量排序算法

优先级队列提供了一种简单的向量排序算法,优先在优先级队列中依次插入每个元素,,然后按序删除它们,程序实现代码如下:

/************************************************************************//* * 优先级队列的类实现 *//************************************************************************/#ifndef _PRIQUEUE_H_#define _PRIQUEUE_H_#include <iostream>template<typename T>class PriQueue{private:int n, maxsize;T *x;void swap(int i, int j){T temp = x[i];x[i] = x[j];x[j] = temp;}public:PriQueue(int m) :maxsize(m){x = new T[maxsize + 1];n = 0;}void insert(T t){int i, p;x[++n] = t;//自底向上类似siftup函数内容实现优先级序列for (i = n ; i > 1 && x[p=i/2] > x[i] ; i = p)swap(p, i);}//输出队列顶并调整队列结构T extramin(){/*cout << “队列中的数据为:” << endl;for (int i = 1; i <= n; i++)cout << x[i] << “\t”;cout << endl;*/int i, c;T t = x[1];x[1] = x[n–];//自顶向下调整队列结构for (i = 1; (c = 2 * i) <= n; i = c){if (c + 1 <= n && x[c + 1] < x[c])c++;if (x[i] <= x[c])break;swap(c, i);}return t;}};#endif

main主程序实现如下:

/************************************************************************//* 《编程珠玑》第十四章 堆* 问题:程序的输入包含两个整数m和n,其中m<n。输出是0~n-1范围内m个随机整数的有序列表,不允许重复* 方案:使用堆数据结构思想,构造优先级队列,设计出一种向量排序算法*//************************************************************************/#include <iostream>#include <algorithm>#include <cstdlib>#include “PriQueue.h”using namespace std;template<typename T>void pqsort(T *v , int n){PriQueue<T> pq(n);for (int i = 0; i < n; i++){pq.insert(v[i]);}for (int j = 0; j < n; j++){v[j] = pq.extramin();}}const int N = 10;int main(){int arr[N] = { 4, 12 , 56 , 32 , 24 , 68 , 33 , 6 , 7 , 2 };cout << “排序前输入数据为 :”<<endl;for (int j = 0; j < N; j++){cout << arr[j] << “\t”;}cout << endl;pqsort(arr,N);cout << “排序后输出数据为 : ” << endl;for (int j = 0; j < N; j++){cout << arr[j] << “\t”;}cout << endl;system(“pause”);return 0;}

对于上面实现的优先级队列向量排序算法,n次insert和extractmin操作在最坏情况下的开销是O(nlogn),优于快速排序算法的最坏O(n^2)的复杂度,但是缺点是,该算法需要额外的n+1的字节的空间来存储数组x[0…n];

下面讨论的堆排序,改进了基于优先级队列的向量排序算法,代码更加简洁,而且不需要辅助数组,使用的空间更少。

堆排序算法

对于优先级队列实现的向量排序算法,需要两个数组,一个用于优先级队列,一个用于待排序的元素;而堆排序算法只需要一个数组,因此节省了空间开销。 思想:使用单个数组x同时表示两种抽象结构,左边是堆,右边是输入元素序列。元素的初始顺序是随意的,而最终则是有序的。 算法实现:

这里写代码片原理

本章最终总结以下几个原理:

莫找借口失败,只找理由成功。(不为失败找理由,要为成功找方法

《编程珠玑》阅读小记(11)

相关文章:

你感兴趣的文章:

标签云: