js实现的大根堆算法(基于链式的m叉树)

2024-03-27 21:58
文章标签 算法 实现 js 链式 根堆

本文主要是介绍js实现的大根堆算法(基于链式的m叉树),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

面向过程版本

var COUNT = 3;
/*获取待排序数据,数据的个数和值随机生成
*/
function getData() {var arr = [];var i = 0;var len = Math.max(10, ~~(Math.random() * 30 ));while(i <  len) {arr.push(~~(Math.random() * 100 ));i++;}   return arr;
}
/*节点构造函数@param val {any} 节点的值@param position {int} 节点的位置,即第几个节点
*/
function Node(val, position) {// 叉数,例如二叉树var count = COUNT;// 初始化节点的孩子为nullwhile(count) {this[count--] = null;}this.position = position;// 父节点、前继节点、后继节点this.parent = null;this.pre = null;this.next = null;// 孩子个数this.childs = 0;this.val = val;
}
/*构造COUNT叉树
*/
function makeTree(arr) {var i = 1;var root = new Node(arr[0], 0);var position = 1;var count = COUNT;// 初始化队列var queue = [root];// 保存上一个遍历的节点,用于前后节点的连接var preNodePtr;// 构造m叉树完成后,从哪个节点开始遍历这棵树,从最后一个非叶子节点开始var neededNode;// 是否已经找到了最后一个非叶子节点var isFind = false;// 用于寻找最后的非叶子节点var preNode = root;// 利用队列进行广度遍历while(queue.length) {var node = queue.shift();i = 1;// 给当前节点配置孩子数据,个数为COUNTwhile(i <= count) {// 判断当前的节点数是否已经超过数据的长度if (position < arr.length) {var newNode = new Node(arr[position], position);node[i] = newNode;newNode.parent = node;newNode.pre = preNode;preNode.next = newNode;node.childs++;queue.push(newNode);preNode = newNode;i++;position++;} // 全部数据赋值完成else {break;}}// 是否找到了最后的非叶子节点if (!isFind) {// 当前节点的孩子数为0,说明前一节点为最后一个非叶子节点if (node.childs === 0) {neededNode = preNodePtr;isFind = true;return {root: root,startNode: neededNode};} // 当前节点的孩子数小于分支数COUNT,说明当前节点为最后的非叶子节点else if (node.childs < COUNT){neededNode = node;isFind = true;return {root: root,startNode: neededNode};}// 保存前一个节点else {preNodePtr = node;}}}return root;
}
// 找出一棵树的最后非叶子节点,已经在makeTree里实现
function findNode(root) {var queue = [root];var node;var count = COUNT;var i = 1;var preNodePtr;while(queue.length) {node = queue.shift();if (node.childs === 0) {return preNodePtr;} else if (node.childs < COUNT) {return node;}preNodePtr = node;while(i <= count) {queue.push(node[i++]);}count = COUNT;  }
}
// 根据一颗无序的m叉树构建m叉大堆树
function buildHeapTree(root, startNode) {var node = startNode;// 从最后一个非叶子节点开始,到根节点结束,遍历其中的所有节点,调整成m叉堆的形式,最后根节点为值最大的节点while(node) {adjustHeapTree(node);node = node.pre;}return root;
}
// 以node节点为根节点,endNode为结束节点。把node子树调整成m叉堆,
function adjustHeapTree(node, endNode) {var i = 1;var max = node.val;var position = 0;var isEnd = false;while(i <= COUNT) {// 是否已经到达了结束节点,是则结束所有步骤if (endNode && node[i] && node[i].position >= endNode.position) {isEnd = true;break;}// 找到node节点和孩子中的最大值。if (node[i] && node[i].val > max) {max = node[i].val;position = i;}i++;}var temp;// 如果node节点的值不是最大的,那么和值最大的孩子节点进行值的互换if (position !== 0) {temp = node.val;node.val = node[position].val;node[position].val = temp;/*是否已经到达结束节点,是的话不需要再进行调整后续的子树,因为孩子节点的position和父节点的大以被置换值的孩子节点为根节点,调整成m叉树   */!isEnd && adjustHeapTree(node[position], endNode);}   
}/*对排序的主流程
*/
function heapSort(root, startNode) {if (!root.childs) {return;}var node = startNode;// 获取整个树的最后一个节点,即最后一个非叶子节点的最后一个节点var lastChild = getNodeLastChild(node);var endNode = lastChild;var temp;// 首先构建m叉堆buildHeapTree(root, startNode);while(endNode !== root) {// 把m叉堆中值最大的节点,即根节点的值和最后一个孩子的值互换temp = root.val;root.val = endNode.val;endNode.val = temp;// 以根节点为起点,endNode为终点,调整子树为m叉堆adjustHeapTree(root, endNode);// 终点根节点方向,往前挪一位,此时,endNode后面的节点都是有序的endNode = endNode.pre;}
}
// 或许某个节点的最后一个孩子节点
function getNodeLastChild(node) {var count = COUNT;while(count) {if (node[count]) {return node[count];}count--;}return null;
}
// 广度遍历root为根节点的m叉树
function echo(root) {var queue =[root];var result = [];var i = 1;while(queue.length) {i = 1;var node = queue.shift();result.push(node.val);while(i <= node.childs) {queue.push(node[i++]);}}console.log('sort: data',JSON.stringify(result),'\n');return result;
}
// 断言堆排序算法产生的数据是升序的
function assert(result) {var i = 0;while(i < result.length - 2) {if (result[i] > result[i+1]) {console.log('error',i, result,'\n');break;}i++;}
}
function start() {var data = getData();console.log('source data:',JSON.stringify(data));var {root, startNode} = makeTree(data);heapSort(root, startNode);assert(echo(root));
}
start();

粗糙的面向对象版本

function HeapSort(count) {this.data = [];this.COUNT = count || 2;
}HeapSort.prototype = {getData: function() {var arr = [];var i = 0;var len = Math.max(10, ~~(Math.random() * 30 ));while(i <  len) {arr.push(~~(Math.random() * 100 ));i++;}   this.data = arr;return arr;},makeTree: function makeTree() {var arr = this.data;var i = 1;var root = this.getNode(arr[0], 0);var position = 1;var count = this.COUNT;var queue = [root];var preNodePtr;var neededNode;var isFind = false;var preNode = root;while(queue.length) {var node = queue.shift();i = 1;while(i <= count) {if (position < arr.length) {var newNode = this.getNode(arr[position], position);node[i] = newNode;newNode.parent = node;newNode.pre = preNode;preNode.next = newNode;node.childs++;queue.push(newNode);preNode = newNode;i++;position++;} else {break;}}if (!isFind) {if (node.childs === 0) {neededNode = preNodePtr;isFind = true;this.startNode = neededNode;this.root = root;} else if (node.childs < this.COUNT){neededNode = node;isFind = true;this.startNode = neededNode;this.root = root;} else {preNodePtr = node;}}}return root;},findNode: function findNode(root) {var queue = [root];var node;var count = COUNT;var i = 1;var preNodePtr;while(queue.length) {node = queue.shift();if (node.childs === 0) {return preNodePtr;} else if (node.childs < this.COUNT) {return node;}preNodePtr = node;while(i <= count) {queue.push(node[i++]);}count = this.COUNT; }},buildHeapTree: function buildHeapTree() {var node = this.startNode;while(node) {this.adjustHeapTree(node);node = node.pre;}},adjustHeapTree: function adjustHeapTree(node, endNode) {var i = 1;var max = node.val;var position = 0;var isEnd = false;while(i <= this.COUNT) {if (endNode && node[i] && node[i].position >= endNode.position) {isEnd = true;break;}if (node[i] && node[i].val > max) {max = node[i].val;position = i;}i++;}var temp;if (position !== 0) {temp = node.val;node.val = node[position].val;node[position].val = temp;!isEnd && this.adjustHeapTree(node[position], endNode);}   },heapSort: function heapSort() {if (!this.root.childs) {return;}var root = this.root;var node = this.startNode;var lastChild = this.getNodeLastChild(node);var endNode = lastChild;var temp;this.buildHeapTree();while(endNode !== root) {temp = root.val;root.val = endNode.val;endNode.val = temp;this.adjustHeapTree(root, endNode);endNode = endNode.pre;}},getNodeLastChild: function getNodeLastChild(node) {var count = this.COUNT;while(count) {if (node[count]) {return node[count];}count--;}return null;},echo: function echo() {var queue =[this.root];var result = [];var i = 1;while(queue.length) {i = 1;var node = queue.shift();result.push(node.val);while(i <= node.childs) {queue.push(node[i++]);}}this.result = result;console.log('sort: data',JSON.stringify(result),'\n');},assert: function assert() {var result = this.result;var i = 0;while(i < result.length - 2) {if (result[i] > result[i+1]) {console.log('error',i, result,'\n');break;}i++;}},start: function start() {this.getData();console.log('source data:',JSON.stringify(this.data));this.makeTree();this.heapSort();this.echo();this.assert();},getNode(val, position) {var node = {};var count = this.COUNT;while(count) {node[count--] = null;}node.position = position;node.parent = null;node.pre = null;node.next = null;node.childs = 0;node.val = val;return node;}
}
new HeapSort().start();

算法正确性验证

var end = 10000;
var i = 0;
var time = setInterval(function() {if (i > end) {clearInterval(time);}i++;start();//new HeapSort().start();
},10)

算法性能比较

// 插入排序 
function insertSort(arr) {
for (var i = 1;i<arr.length;i++) {
var j=i-1;
var key = arr[i];
while (j>=0 && key<arr[j]) {
arr[j+1] = arr[j];
j--;
}
arr[j+1] = key;
}
}// 希尔排序
function shellSortRecursion(arr,step) {if(step<1) {return;}for (var i = step;i<arr.length;i++) {var j = i-step;var key = arr[i];while (j>=0 && key<arr[j]) {arr[j+step] = arr[j];j-=step;}arr[j+step] = key;}step = Math.floor(step/2);shellSortRecursion(arr,step);
}function start() {var data = getData();var start = new Date().getTime();var {root, startNode} = makeTree(data);heapSort(root, startNode);//insertSort(data)//shellSortRecursion(data,5)console.log((new Date().getTime() - start)/1000);
}
start();

这篇关于js实现的大根堆算法(基于链式的m叉树)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/853511

相关文章

SpringBoot集成redisson实现延时队列教程

《SpringBoot集成redisson实现延时队列教程》文章介绍了使用Redisson实现延迟队列的完整步骤,包括依赖导入、Redis配置、工具类封装、业务枚举定义、执行器实现、Bean创建、消费... 目录1、先给项目导入Redisson依赖2、配置redis3、创建 RedissonConfig 配

Python的Darts库实现时间序列预测

《Python的Darts库实现时间序列预测》Darts一个集统计、机器学习与深度学习模型于一体的Python时间序列预测库,本文主要介绍了Python的Darts库实现时间序列预测,感兴趣的可以了解... 目录目录一、什么是 Darts?二、安装与基本配置安装 Darts导入基础模块三、时间序列数据结构与

Python使用FastAPI实现大文件分片上传与断点续传功能

《Python使用FastAPI实现大文件分片上传与断点续传功能》大文件直传常遇到超时、网络抖动失败、失败后只能重传的问题,分片上传+断点续传可以把大文件拆成若干小块逐个上传,并在中断后从已完成分片继... 目录一、接口设计二、服务端实现(FastAPI)2.1 运行环境2.2 目录结构建议2.3 serv

C#实现千万数据秒级导入的代码

《C#实现千万数据秒级导入的代码》在实际开发中excel导入很常见,现代社会中很容易遇到大数据处理业务,所以本文我就给大家分享一下千万数据秒级导入怎么实现,文中有详细的代码示例供大家参考,需要的朋友可... 目录前言一、数据存储二、处理逻辑优化前代码处理逻辑优化后的代码总结前言在实际开发中excel导入很

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

Nginx部署HTTP/3的实现步骤

《Nginx部署HTTP/3的实现步骤》本文介绍了在Nginx中部署HTTP/3的详细步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录前提条件第一步:安装必要的依赖库第二步:获取并构建 BoringSSL第三步:获取 Nginx

MyBatis Plus实现时间字段自动填充的完整方案

《MyBatisPlus实现时间字段自动填充的完整方案》在日常开发中,我们经常需要记录数据的创建时间和更新时间,传统的做法是在每次插入或更新操作时手动设置这些时间字段,这种方式不仅繁琐,还容易遗漏,... 目录前言解决目标技术栈实现步骤1. 实体类注解配置2. 创建元数据处理器3. 服务层代码优化填充机制详

Python实现Excel批量样式修改器(附完整代码)

《Python实现Excel批量样式修改器(附完整代码)》这篇文章主要为大家详细介绍了如何使用Python实现一个Excel批量样式修改器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录前言功能特性核心功能界面特性系统要求安装说明使用指南基本操作流程高级功能技术实现核心技术栈关键函

Java实现字节字符转bcd编码

《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima

SpringBoot全局域名替换的实现

《SpringBoot全局域名替换的实现》本文主要介绍了SpringBoot全局域名替换的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录 项目结构⚙️ 配置文件application.yml️ 配置类AppProperties.Ja