数据结构实现 6.3:优先队列_基于动态数组实现(C++版)

数据结构实现 6.3:优先队列_基于动态数组实现(C++版)

  • 1. 概念及基本框架
  • 2. 基本操作程序实现
    • 2.1 入队操作
    • 2.2 出队操作
    • 2.3 查找操作
    • 2.4 其他操作
  • 3. 算法复杂度分析
    • 3.1 入队操作
    • 3.2 出队操作
    • 3.3 查找操作
  • 4. 完整代码

1. 概念及基本框架

6.2 中通过 最大二叉堆 实现了 优先队列 ,这一节我们通过动态数组来实现优先队列。

优先队列

优先队列队列 的一种,所以有队列的基本特性:
1.队列队头队尾 两端。
2.入队 操作只能从 队尾 进行,出队 操作只能从 队头 进行。
3.先 入队 的先 出队 ,即 先进先出(First In First Out),FIFO
还有一个隐含特性,队列可以自行 扩容(缩容),而不需要用户关心,很显然,动态数组已经满足了这个要求。
首先使用一个由 纯虚函数 构成的 抽象类 作为一个队列接口,接口内定义一些队列的基本操作。具体代码如下:

template <class T>
class Queue{
public:
	virtual int size() = 0;
	virtual bool isEmpty() = 0;
	virtual void print() = 0;
	//入队操作
	virtual void enqueue(T num) = 0;
	//出队操作
	virtual void dequeue() = 0;
	//获得队首元素
	virtual T front() = 0;
};

下面只需要通过继承 抽象类,并且重写 纯虚函数 ,就可以完成 优先队列 的实现。优先队列类的框架如下:

template <class T>
class ArrayPriorityQueue{
...
private:
	Array<T> arr;
};

同样,这里为了避免重复设计就可以兼容更多数据类型,引入了 泛型 ,即 模板 的概念。(模板的关键字是 classtypename
这里的 arr 表示一个 动态数组 ,同样,为了保护数据,变量设置为 private
注:这里没有显式的给出构造函数,因为子类中除了动态数组对象之外没有特别需要初始化的东西。编译器会默认先调用 动态数组 类(即父类)的构造函数,再去调用 优先队列 类(即子类)的构造函数。
实现了前面的程序之后,接下来就是一个队列的增、删、查以及一些其他基本操作,接下来利用代码去实现。

2. 基本操作程序实现

2.1 入队操作

template <class T>
class ArrayPriorityQueue{
public:
	...
	//入队操作
	void enqueue(T num){
		arr.addLast(num);
	}
	...
};

2.2 出队操作

template <class T>
class ArrayPriorityQueue{
public:
	...
	//出队操作
	void dequeue(){
		if (arr.isEmpty()){
			cout << "出队失败!" << endl;
			return;
		}
		arr.remove(findMax());
	}
	...
private:
	int findMax(){
		int index = 0;
		for (int i = 0; i < arr.size(); ++i){
			if (arr.get(i) > arr.get(index)){
				index = i;
			}
		}
		return index;
	}
	...
};

这里利用了一次遍历查找最大元素。

2.3 查找操作

template <class T>
class ArrayPriorityQueue{
public:
	...
	//获得队首元素
	T front(){
		return arr.get(findMax());
	}
private:
	int findMax(){
		int index = 0;
		for (int i = 0; i < arr.size(); ++i){
			if (arr.get(i) > arr.get(index)){
				index = i;
			}
		}
		return index;
	}
	...
};

这里利用了一次遍历查找最大元素。

2.4 其他操作

优先队列还有一些其他的操作,包括 队列大小 等的查询等操作。

template <class T>
class ArrayPriorityQueue{
public:
	int size(){
		return arr.size();
	}
	bool isEmpty(){
		return arr.isEmpty();
	}
	void print(){
		if (arr.isEmpty()){
			return;
		}
		cout << "ArrayPriorityQueue: ";
		cout << "Size = " << arr.size() << endl;
		cout << "front [";
		cout << arr.get(findMax()) << "...";
		cout << "] rear" << endl;
	}
	...
};

3. 算法复杂度分析

这里入队使用直接插入,出队时遍历查找的方法实现优先队列。

3.1 入队操作

函数 最坏复杂度 平均复杂度
enqueue O(1) O(1)

3.2 出队操作

函数 最坏复杂度 平均复杂度
dequeue O(n) O(n/2) = O(n)

3.3 查找操作

函数 最坏复杂度 平均复杂度
front O(n) O(n/2) = O(n)

总体情况:

操作 时间复杂度
O(1)
O(n)
O(n)

也可以采用入队时遍历放入适当位置,出队出队头。

4. 完整代码

程序完整代码(这里使用了头文件的形式来实现类)如下:
优先队列接口函数一览:

函数声明 函数类型 函数功能
int size() public 返回二叉堆的大小
bool isEmpty() public 返回优先队列是否为空(空为true)
void print() public 打印输出优先队列队头
void enqueue(T) public 入队元素到优先队列
void dequeue() public 从优先队列中出队一个元素
T front() public 获得优先队列队头元素

抽象类 接口代码:

#ifndef __QUEUE_H__
#define __QUEUE_H__

template <class T>
class Queue{
public:
	virtual int size() = 0;
	virtual bool isEmpty() = 0;
	virtual void print() = 0;
	//入队操作
	virtual void enqueue(T num) = 0;
	//出队操作
	virtual void dequeue() = 0;
	//获得队首元素
	virtual T front() = 0;
};

#endif

这里不再给出动态数组代码。

优先队列类 代码:

#ifndef __ARRAYPRIORITYQUEUE_H__
#define __ARRAYPRIORITYQUEUE_H__

#include "Queue.h"
#include "Array.h"

template <class T>
class ArrayPriorityQueue{
public:
	int size(){
		return arr.size();
	}
	bool isEmpty(){
		return arr.isEmpty();
	}
	void print(){
		if (arr.isEmpty()){
			return;
		}
		cout << "ArrayPriorityQueue: ";
		cout << "Size = " << arr.size() << endl;
		cout << "front [";
		cout << arr.get(findMax()) << "...";
		cout << "] rear" << endl;
	}
	//入队操作
	void enqueue(T num){
		arr.addLast(num);
	}
	//出队操作
	void dequeue(){
		if (arr.isEmpty()){
			cout << "出队失败!" << endl;
			return;
		}
		arr.remove(findMax());
	}
	//获得队首元素
	T front(){
		return arr.get(findMax());
	}
private:
	int findMax(){
		int index = 0;
		for (int i = 0; i < arr.size(); ++i){
			if (arr.get(i) > arr.get(index)){
				index = i;
			}
		}
		return index;
	}
private:
	Array<T> arr;
};

#endif

你可能感兴趣的:(C++,数据结构)