JavaScriptでスタックの要素を再帰的に並べ替える方法
はじめに
本記事では、整数の配列(スタックとして扱う)を受け取り、再帰処理とpush・popメソッドのみを使って、その配列をその場(in-place)で昇順に並べ替えるJavaScript関数を実装する方法を解説します。
このアルゴリズムのポイントは、以下の2つの再帰関数を組み合わせる点にあります。
- sortStack:スタックから要素を1つずつ取り出し(pop)、残りのスタックを再帰的に並べ替えてから、要素を適切な位置に挿し戻します。
- sortedInsert:指定した要素を、スタックが空になるか、スタック末尾の要素より大きくなるまで再帰的にpopし、正しい位置に挿入します。
サンプルコード
実際のコードは次のようになります。
const stack = [-3, 14, 18, -5, 30];
// スタック全体を並べ替える関数
const sortStack = (stack = []) => {
if (stack.length > 0) {
let t = stack.pop(); // 先頭の要素を取り出す
sortStack(stack); // 残りのスタックを再帰的にソート
sortedInsert(stack, t); // 取り出した要素を正しい位置に挿入
};
}
// 要素をソート済みの位置へ再帰的に挿入する関数
const sortedInsert = (stack, e) => {
if (stack.length == 0 || e > stack[stack.length - 1]) {
stack.push(e); // スタックが空、または挿入位置に達したら追加
} else {
let x = stack.pop(); // 条件を満たすまで要素を退避
sortedInsert(stack, e);
stack.push(x); // 退避していた要素を元に戻す
}
}
sortStack(stack);
console.log(stack);実行結果
コンソールには次のように出力されます。
[ -5, -3, 14, 18, 30 ]
処理の流れと計算量
このアルゴリズムは「挿入ソート」を再帰で表現したものです。各要素を挿入するたびに最大でO(n)回のpop/pushが発生し得るため、全体的な時間計算量はO(n²)となります。一方で、補助的な配列や一時変数をほとんど使わずに済むため、空間効率に優れたin-placeなソートとして知られています。
再帰の仕組みを理解する練習問題としても非常に良い題材なので、ぜひ自分でも動きを追ってみてください。
-
JavaScriptのimportで波括弧「{}」を使う理由とは?名前付きエクスポートの基本をわかりやすく解説
JavaScript(ESモジュール)でモジュールを読み込む際、import 文に波括弧 { } を付けるかどうか迷ったことはありませんか?実はこの波括弧は、名前付きエクスポート(named export)を読み込むために必要な記法です。本記事では、実際のコード例を使いながら、{ } の役割と使い方を詳しく解説します。 importで { } を使う場面とは JavaScriptのESモジュールでは、エクスポート方法によって読み込み側の書き方が変わります。 名前付きエクスポート:export { 関数名 } のようにエクスポートされたものを読み込む場合は、import { 名前 } fro
-
JavaScriptでスタックを実装する方法【サンプルコード付きで解説】
スタック(Stack)は、最後に追加した要素が最初に取り出される「LIFO(Last In, First Out)」方式の基本的なデータ構造です。本記事では、JavaScriptを使ってスタックを実装する方法を、ブラウザ上で実際に動作するサンプルコードとともにわかりやすく解説します。 スタックの基本操作 push:スタックの一番上に新しい要素を追加します。 pop:スタックの一番上から要素を取り出して削除します。要素がない場合はアンダーフローとして扱います。 display:スタック内に格納されているすべての要素を表示します。 サンプルコード 以下は、JavaScriptでスタックを実装し