優先級隊列(PriorityQueue)是個很有用的數據結構,很多編程語言都有實現。NodeJs是一個比較新潮的服務器語言,貌似還沒有提供相關類。這些天有用到優先級隊列,因為時間很充足,閑來無事,就自己實現了一下。代碼如下:
/**
* script: pqueue.js
* description: 優先級隊列類
* authors: alwu007@sina.cn
* date: 2016-04-19
*/
var util = require('util');
/**
* 優先級隊列類
* @param cmp_func 優先級比較函數,必需,參考數組排序參數
*/
var PQueue = exports.PQueue = function(cmp_func) {
//記錄數組
this._records = [];
//優先級比較方法
this._cmp_func = cmp_func;
};
//堆向上調整
PQueue.prototype._heapUpAdjust = function(index) {
var records = this._records;
var record = records[index];
var cmp_func = this._cmp_func;
while (index > 0) {
var parent_index = Math.floor((index - 1) / 2);
var parent_record = records[parent_index];
if (cmp_func(record, parent_record) < 0) {
records[index] = parent_record;
index = parent_index;
} else {
break;
}
}
records[index] = record;
};
//堆向下調整
PQueue.prototype._heapDownAdjust = function(index) {
var records = this._records;
var record = records[index];
var cmp_func = this._cmp_func;
var length = records.length;
var child_index = 2 * index + 1;
while (child_index < length) {
if (child_index + 1 < length && cmp_func(records[child_index], records[child_index + 1]) > 0) {
child_index ++;
}
var child_record = records[child_index];
if (cmp_func(record, child_record) > 0) {
records[index] = child_record;
index = child_index;
child_index = 2 * index + 1;
} else {
break;
}
}
records[index] = record;
};
//銷毀
PQueue.prototype.destroy = function() {
this._records = null;
this._cmp_func = null;
};
//將記錄插入隊列
PQueue.prototype.enQueue = function(record) {
var records = this._records;
records.push(record);
this._heapUpAdjust(records.length - 1);
};
//刪除並返回隊頭記錄
PQueue.prototype.deQueue = function() {
var records = this._records;
if (!records.length)
return undefined;
var record = records[0];
if (records.length == 1) {
records.length = 0;
} else {
records[0] = records.pop();
this._heapDownAdjust(0);
}
return record;
};
//獲取隊頭記錄
PQueue.prototype.getHead = function() {
return this._records[0];
};
//獲取隊列長度
PQueue.prototype.getLength = function() {
return this._records.length;
};
//判斷隊列是否為空
PQueue.prototype.isEmpty = function() {
return this._records.length == 0;
};
//清空隊列
PQueue.prototype.clear = function() {
this._records.length = 0;
};
我覺得,相對於其他排序算法而言,用堆實現優先級隊列,入隊時間波動較小,比較平穩。
