C++で連結リストを挿入ソートする方法を解説
連結リストが与えられたとき、そのリストに対して挿入ソート(Insertion Sort)を実行することを考えてみましょう。例えば、リストが [9,45,23,71,80,55] の場合、ソート後のリストは [9,23,45,55,71,80] となります。
配列と異なり、連結リストでは要素の挿入・削除がポインタの付け替えだけで行えるため、挿入ソートとの相性が良いという特徴があります。
アルゴリズムの手順
この問題を解くために、以下の手順に従います。
- 任意の値を持つダミーノード(番兵ノード)を新しく作成します。
- node を与えられたリストの先頭に設定します。
- node が NULL でない間、以下を繰り返します。
- nextNode を node の次のノードとし、dummyHead をダミーの次のノード、prevDummyHead をダミー自身に設定します。
- 以下の条件を満たすまでループします。
- dummyHead が存在しない、または dummyHead の値が node の値より大きい場合:
- node の次を dummyHead につなぎます。
- prevDummyHead の次を node につなぎます。
- ループを抜けます。
- それ以外の場合は、prevDummyHead を dummyHead に、dummyHead をその次のノードに進めます。
- dummyHead が存在しない、または dummyHead の値が node の値より大きい場合:
- node を nextNode に進めます。
- 最後に、ダミーの次のノード(ソート済みリストの先頭)を返します。
ダミーノードを用意することで、先頭への挿入処理を特別扱いせずに統一的なコードで書けるのがポイントです。
実装例
以下のC++コードで、実際の動作を確認してみましょう。
class Solution {
public:
ListNode* insertionSortList(ListNode* a) {
ListNode* dummy = new ListNode(-1);
ListNode* node = a;
while (node != NULL) {
ListNode* nextNode = node->next;
ListNode* dummyHead = dummy->next;
ListNode* prevDummyHead = dummy;
while (true) {
if (!dummyHead || dummyHead->val > node->val) {
node->next = dummyHead;
prevDummyHead->next = node;
break;
}
prevDummyHead = dummyHead;
dummyHead = dummyHead->next;
}
node = nextNode;
}
return dummy->next;
}
};
入力
[9,45,23,71,80,55]
出力
[9,23,45,55,71,80]
計算量について
このアルゴリズムの時間計算量は O(n²) です。各ノードについて、ソート済み部分リストの中から挿入位置を線形探索するためです。一方、追加のメモリはダミーノードと数個のポインタのみで済むため、空間計算量は O(1) となります。要素数が少ないリストや、ほぼソート済みのデータに対しては効率的に動作します。
-
C++でマルチレベル連結リストをフラット化する方法を解説
この記事では、マルチレベル連結リスト(Multilevel Linked List)をフラット化するプログラムをC++で作成する方法について解説します。フラット化とは、第1レベルのノードをすべて先に並べ、その後に第2レベルのノードが続くように、階層構造を持つリストを1本の直線的な連結リストへ変換する操作のことです。マルチレベル連結リストとはマルチレベル連結リストとは、多次元的なデータ構造の一種です。各ノードは2つのポインタを持ちます。1つは次のノードを指す「next」ポインタ、もう1つは1つ以上のノードからなる子リストを指す「child」ポインタです。この子ポインタは、他のリストのノードを指す
-
C#で学ぶ挿入ソート(Insertion Sort)の基本と実装方法
挿入ソートとは挿入ソート(Insertion Sort)は、配列から要素を1つずつ取り出し、その要素を配列内の正しい位置に挿入していくソートアルゴリズムです。この処理を繰り返すことで、最終的に配列全体が昇順に並べ替えられます。トランプの手札を整理するイメージに近く、直感的に理解しやすいのが特徴です。以下は、C#で挿入ソートを実装したサンプルプログラムです。サンプルコードusing System; namespace InsertionSortDemo { class Example { static void Main(string[] args) {