如何用JavaScript按层级打印数组存储的堆?求优化实现方案
堆的层级化打印实现方案
问题背景
我需要实现一个按层级打印数组形式堆的函数,用于可视化堆排序的执行步骤。自己编写的代码输出混乱、逻辑杂乱且效率低下,希望得到更简洁美观的实现。
原实现代码:
function printheap(a){ let i = 0; let c = 0; let t = "\t"; let s = " "; while(Math.floor(a.length/(2**i)>1)){ t += "\t" i++ } i = 0; while(Math.floor(a.length/(2**i)>1)){ t = t.slice(0, -1) s += " " process.stdout.write(t + a[c]) c++ for(let j = 0; j<(2**i)-1&&c<a.length; j++){ process.stdout.write(s + a[c]) c++ } console.log("\n") i++ } }
输入示例:[3, 8, 7, 15, 17, 30, 35, 2, 4, 5, 9]
期望输出:
3 8 35 15 17 30 7 2 4 5 9
优化实现方案
下面是一个逻辑清晰、排版整齐的实现,核心思路是通过计算堆的高度和每层的空格分布,确保堆结构居中对齐:
function printHeap(heap) { if (!heap.length) return; // 计算堆的总层数 const height = Math.floor(Math.log2(heap.length)) + 1; // 动态获取元素的最大宽度,保证排版对齐 const maxElementWidth = Math.max(...heap.map(num => num.toString().length)); let currentIndex = 0; for (let level = 0; level < height; level++) { // 当前层的元素数量 const levelCount = Math.min(2 ** level, heap.length - currentIndex); // 计算当前层整体需要的前置空格,实现居中 const totalLevelWidth = (2 ** (height - 1) - 1) * (maxElementWidth + 1) + maxElementWidth; const elementsTotalWidth = levelCount * maxElementWidth + (levelCount - 1) * maxElementWidth; const prefixSpaces = Math.floor((totalLevelWidth - elementsTotalWidth) / 2); // 打印前置空格 process.stdout.write(' '.repeat(prefixSpaces)); // 打印当前层的所有元素 for (let i = 0; i < levelCount; i++) { const element = heap[currentIndex + i]; // 格式化元素,补空格到统一宽度 const formattedElement = element.toString().padStart(maxElementWidth, ' '); process.stdout.write(formattedElement); // 元素间的分隔空格(最后一个元素不添加) if (i < levelCount - 1) { process.stdout.write(' '.repeat(maxElementWidth)); } } // 换行分隔层级 console.log('\n'); currentIndex += levelCount; } }
代码说明
- 堆高度计算:通过
log2计算堆的总层数,确定需要打印多少行 - 元素宽度统一:动态获取堆中最大元素的字符串长度,确保所有元素占据相同宽度,避免排版错位
- 居中对齐:通过计算每层的总宽度和元素占据的宽度,得出前置空格数,让当前层整体居中
- 层级遍历:按层遍历堆数组,逐行打印,每层元素间用统一宽度的空格分隔
调用printHeap([3, 8, 7, 15, 17, 30, 35, 2, 4, 5, 9])即可得到符合期望的可视化输出。
内容的提问来源于stack exchange,提问作者Bartolomeo Zisa
相关产品推荐
相关产品推荐

