本文へスキップ
製品デスクトップツールTASTECAD図面の確認TASTEFILESファイル管理TASTEFTPファイル転送TASTESSHリモートワークスペースTASTEZIP圧縮と展開開発ツールTASTECODERust 統合開発環境TASTESTUDIO統合開発・テスト環境TASTEETLデータ統合(ETL)サーバーTASTEREMOTEリモートデスクトップサーバーTASTEGEO空間情報サーバーTASTEMAILメールワークスペースはじめるダウンロードドキュメント購入すべての製品
マーケットプレイス
ニュース
技術ニュース今日の開発ニュース開発ドキュメントプログラミング言語RustTypeScriptJavaScriptPythonGoC#JavaCC++KotlinDartWebフロントエンド フレームワークNext.jsReactVue.js · NuxtSvelteKitAngularサーバー フレームワークSpring BootDjangoFastAPIASP.NET CoreNestJS · Expressアプリ・デスクトップ フレームワークTauriFlutterReact NativeElectronアルゴリズムアルゴリズムの基礎主要アルゴリズム発展アルゴリズム実務のアルゴリズム
コミュニティプロジェクト開発ログプロンプトAIツールの問題ショーケースコミュニティガイド
協業技術移転ウェブサイト構築デスクトップアプリ構築リリース・決済パイプライン販売パートナーお問い合わせ
サービスリモートデスクトップインストールパッケージのカスタマイズ
TASTEDEV
製品

デスクトップツール

TASTECAD複雑な図面を、軽やかにひらくTASTEFILES必要なファイルだけを、最速でTASTEFTPファイルが行き交う、いちばん端正な道TASTESSHサーバーとあなたを、より確かにつなぐTASTEZIPより速くまとめ、より安全にひらく

開発ツール

TASTECODERust アプリの編集・ビルド・デバッグ・テストまでひとつのウィンドウでTASTESTUDIO編集からリモートテスト、承認した AI 修正までTASTEETL値を見ながら、データを運ぶ

サーバー

TASTEREMOTE自社サーバーで運用するリモートデスクトップTASTEGEOGeoServer 互換の空間情報サーバーを Rust で作り直しますTASTEMAILメールの主導権を、もう一度自分の手に

はじめる

ダウンロード全製品の最新版ドキュメント各製品の使い方購入サブスクリプション・永久ライセンスすべての製品全製品を一覧で
すべての製品
マーケットプレイスニュース
技術

ニュース

今日の開発ニュース言語・フレームワーク・GitHub・AI の公式発表開発ドキュメント言語・フレームワーク・アルゴリズムのガイド

プログラミング言語

RustTypeScriptJavaScriptPythonGoC#JavaCC++KotlinDart

フレームワーク

Webフロントエンド フレームワークNext.jsReactVue.js · NuxtSvelteKitAngular
サーバー フレームワークSpring BootDjangoFastAPIASP.NET CoreNestJS · Express
アプリ・デスクトップ フレームワークTauriFlutterReact NativeElectron

アルゴリズム

アルゴリズムの基礎計算量解析 · ソート · 探索 · 基本データ構造 · 木構造とヒープ主要アルゴリズムグラフ探索 · 最短経路と最小全域木 · 動的計画法 · 貪欲法 · 分割統治法 · バックトラッキング発展アルゴリズム文字列アルゴリズム · 数学と整数論 · ビット演算 · セグメント木 · Union-Find実務のアルゴリズムコーディング面接対策 · LRUキャッシュ · レート制限 · コンシステントハッシュ法
開発ドキュメントをすべて見る
コミュニティ
プロジェクトビルダーと作品を探す開発ログ決定と試行錯誤プロンプト再利用できる指示AIツールの問題Claude・Codex・Gemini の問題と回避策ショーケース完成した成果コミュニティガイドオープンにつくる方法
協業
技術移転Rust・egui でネイティブアプリを作るウェブサイト構築10言語、アカウント、ドキュメントとダウンロードデスクトップアプリ構築Rust・egui、WebView なしリリース・決済パイプライン署名・MSI・deb・rpm・AppImage・ハッシュ販売パートナー紹介して決済額の30%お問い合わせ構築・提携・投資のご相談
サービス
リモートデスクトップブラウザから自分のパソコンへインストールパッケージのカスタマイズ必要な機能だけ、設定は事前に
購入
JA
한국어EnglishDeutschEspañolFrançaisItalianoPortuguês (Brasil)日本語简体中文繁體中文
ログイン
ログイン
TASTEDEV

小さなツールから、より良い開発へ。

support@tastedev.netTASTEDEVを支援
製品製品ラインナップ購入ドキュメントダウンロードマーケットプレイスサポート
コミュニティプロジェクト開発ログプロンプトAIツールの問題ショーケース
ポリシープライバシーポリシー利用規約サブスクリプション規約返金ポリシーコミュニティガイドライン
アカウントログイン新規登録
訪問者
今日
012345678901234567890123456789012345678901234567890123456789
昨日
012345678901234567890123456789012345678901234567890123456789
累計閲覧
0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
商号
GXSOFT
代表者
CHOI YOUNG GU
事業者登録番号
853-44-00368
所在地
9F V24, 351 Gyeongin-ro, Michuhol-gu, Incheon, Republic of Korea
電話
+82-10-4404-1523
メール
whitecalvin@tastedev.net
個人情報保護責任者
CHOI YOUNG GU

© 2026 TASTEDEV製品情報は検証済みの開発ソースに基づいています。リリース・改善中

ソート ドキュメント
ソート
Sorting ConceptsHow It WorksImplementationComplexityPractice ProblemsReal-World Use
ディスカッション

ソート ガイド · 3/6

Implementation

この章は現在、英語でのみ提供しています。

Merge sort and quicksort in Python, explained line by line, then the same merge sort in C++, Java and TypeScript.

Merge sort in Python

def merge_sort(items):
    if len(items) <= 1:
        return items[:]
    mid = len(items) // 2
    left = merge_sort(items[:mid])
    right = merge_sort(items[mid:])
    return merge(left, right)


def merge(left, right):
    merged = []
    i = j = 0
    while i < len(left) and j < len(right):
        if left[i] <= right[j]:
            merged.append(left[i])
            i += 1
        else:
            merged.append(right[j])
            j += 1
    merged.extend(left[i:])
    merged.extend(right[j:])
    return merged


print(merge_sort([38, 27, 43, 3, 9, 82, 10]))  # [3, 9, 10, 27, 38, 43, 82]
  • len(items) <= 1: the base case. items[:] returns a copy, so the input is never modified.
  • mid = len(items) // 2: split in the middle and sort each half recursively.
  • The merge loop appends the smaller of the two front elements.
  • left[i] <= right[j]: on ties the left element goes first, which makes the sort stable. Using < would break stability.
  • extend: when one side runs out, the sorted rest of the other is appended.

Every slice allocates a new list; faster versions reuse one buffer and index ranges, as in C++ and Java below.

Quicksort in Python

import random


def quicksort(a, lo=0, hi=None):
    if hi is None:
        hi = len(a) - 1
    while lo < hi:
        lt, gt = partition3(a, lo, hi)
        if lt - lo < hi - gt:          # recurse on the smaller side only
            quicksort(a, lo, lt - 1)
            lo = gt + 1
        else:
            quicksort(a, gt + 1, hi)
            hi = lt - 1


def partition3(a, lo, hi):
    pivot = a[random.randint(lo, hi)]
    lt, i, gt = lo, lo, hi
    while i <= gt:
        if a[i] < pivot:
            a[lt], a[i] = a[i], a[lt]
            lt += 1
            i += 1
        elif a[i] > pivot:
            a[i], a[gt] = a[gt], a[i]
            gt -= 1
        else:
            i += 1
    return lt, gt


data = [5, 2, 8, 2, 9, 1, 5, 5]
quicksort(data)
print(data)  # [1, 2, 2, 5, 5, 5, 8, 9]
  • random.randint(lo, hi): a random pivot makes the O(n²) case unlikely on any input, including sorted data.
  • partition3: a three-way partition (the Dutch national flag problem). Afterwards a[lo:lt] is smaller than the pivot, a[lt:gt+1] equals it and a[gt+1:hi+1] is larger. Equal keys are never revisited, so duplicates stay fast.
  • In the a[i] > pivot branch i does not advance, because the value swapped in from a[gt] has not been examined yet.
この章について質問がありますか?
前の章How It Works次の章Complexity
  • while lo < hi plus recursing on the smaller side caps recursion depth at O(log n), well below Python's default limit of 1000.
  • Merge sort in C++

    #include <cstddef>
    #include <iostream>
    #include <vector>
    
    template <typename T>
    void merge_sort(std::vector<T>& a, std::vector<T>& buf, std::size_t lo, std::size_t hi) {
        if (hi - lo <= 1) return;                 // half-open range [lo, hi)
        std::size_t mid = lo + (hi - lo) / 2;
        merge_sort(a, buf, lo, mid);
        merge_sort(a, buf, mid, hi);
        std::size_t i = lo, j = mid, k = lo;
        while (i < mid && j < hi) {
            if (a[j] < a[i]) buf[k++] = a[j++];   // right only if strictly smaller: stable
            else buf[k++] = a[i++];
        }
        while (i < mid) buf[k++] = a[i++];
        while (j < hi) buf[k++] = a[j++];
        for (std::size_t t = lo; t < hi; ++t) a[t] = buf[t];
    }
    
    template <typename T>
    void merge_sort(std::vector<T>& a) {
        std::vector<T> buf(a.size());
        merge_sort(a, buf, 0, a.size());
    }
    
    int main() {
        std::vector<int> v{38, 27, 43, 3, 9, 82, 10};
        merge_sort(v);
        for (int x : v) std::cout << x << ' ';
        std::cout << '\n';
    }

    One buffer, half-open ranges, and only operator<. In production code, std::stable_sort does this job.

    Merge sort in Java

    import java.util.Arrays;
    
    public class MergeSort {
        public static void sort(int[] a) {
            int[] buf = new int[a.length];
            sort(a, buf, 0, a.length);
        }
    
        private static void sort(int[] a, int[] buf, int lo, int hi) {
            if (hi - lo <= 1) return;
            int mid = lo + (hi - lo) / 2;          // no (lo + hi) overflow
            sort(a, buf, lo, mid);
            sort(a, buf, mid, hi);
            int i = lo, j = mid, k = lo;
            while (i < mid && j < hi) {
                buf[k++] = (a[j] < a[i]) ? a[j++] : a[i++];
            }
            while (i < mid) buf[k++] = a[i++];
            while (j < hi) buf[k++] = a[j++];
            System.arraycopy(buf, lo, a, lo, hi - lo);
        }
    
        public static void main(String[] args) {
            int[] v = {38, 27, 43, 3, 9, 82, 10};
            sort(v);
            System.out.println(Arrays.toString(v));
        }
    }

    System.arraycopy copies the merged range back. For objects, take a Comparator<? super T> and test c.compare(a[j], a[i]) < 0.

    Merge sort in TypeScript

    function mergeSort<T>(items: readonly T[], compare: (a: T, b: T) => number): T[] {
      if (items.length <= 1) return items.slice();
      const mid = Math.floor(items.length / 2);
      const left = mergeSort(items.slice(0, mid), compare);
      const right = mergeSort(items.slice(mid), compare);
      const merged: T[] = [];
      let i = 0;
      let j = 0;
      while (i < left.length && j < right.length) {
        if (compare(right[j], left[i]) < 0) merged.push(right[j++]);
        else merged.push(left[i++]);
      }
      while (i < left.length) merged.push(left[i++]);
      while (j < right.length) merged.push(right[j++]);
      return merged;
    }
    
    console.log(mergeSort([38, 27, 43, 3, 9, 82, 10], (a, b) => a - b));

    The comparator follows the Array.prototype.sort contract (negative means a first), and T makes it generic.

    Summary

    • Merge sort stays stable thanks to one detail: on ties, take from the left.
    • Random pivots, three-way partitioning and smaller-side recursion make quicksort robust.
    • Across languages the core is identical: one reusable buffer and half-open ranges.

    コメント 0件

    人気のコメント順新しい順

    ログイン · ログインするとコメントできます。