ЁЯУ╢ рдзрдбрд╛ 07 тАФ Sorting: рд╡рд░реНрдЧрд╛рд▓рд╛ рдЙрдВрдЪреАрдиреБрд╕рд╛рд░ рд░рд╛рдВрдЧреЗрдд рд▓рд╛рд╡рдгреЗ
ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 07 ┬╖ рдкреБрдвреЗ: lesson-08-binary-search
ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ
рдзрдбреЗ 01тАУ07. comparison counters рдЕрд╕рд▓реЗрд▓реЗ рдЪрд╛рд░ sorts, рддреНрдпрд╛рдЪ 2,000 рдЙрдВрдЪреАрдВрд╡рд░ рд╡реЗрд│
рдореЛрдЬрд▓реЗрд▓реЗ, рдЖрдгрд┐ рддрд░реАрд╣реА рддреБрдореНрд╣реА sorted() рдХрд╛ рдмреЛрд▓рд╛рд╡рддрд╛ рдпрд╛рдЪреЗ рдХрд╛рд░рдг.
- dsa/algorithms.py тАФ
bubble_sort,insertion_sort,merge_sort,quick_sort, рдкреНрд░рддреНрдпреЗрдХ (sorted, comparisons) рдкрд░рдд рдХрд░рддреЛ - dsa/demo.py тАФ
sort
ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ
рд╡рд░реНрдЧрд╛рд▓рд╛ рдЙрдВрдЪреАрдиреБрд╕рд╛рд░ рд░рд╛рдВрдЧреЗрдд рд▓рд╛рд╡рд╛. Bubble: рд░рд╛рдВрдЧреЗрддреВрди рдЪрд╛рд▓рд╛, рдЪреБрдХреАрдЪреНрдпрд╛ рдХреНрд░рдорд╛рддрд▓реНрдпрд╛ рдХреЛрдгрддреНрдпрд╛рд╣реА рджреЛрди рд╢реЗрдЬрд╛рд▒реНрдпрд╛рдВрдЪреА рдЕрджрд▓рд╛рдмрджрд▓ рдХрд░рд╛, рдПрдЦрд╛рджреНрдпрд╛ рдлреЗрд░реАрдд рдХреЛрдгрд╛рдЪреАрдЪ рдЕрджрд▓рд╛рдмрджрд▓ рд╣реЛрдИрдкрд░реНрдпрдВрдд рдкреБрдиреНрд╣рд╛ рдХрд░рд╛ тАФ рд╣рд│реВ, рдкреНрд░рддреНрдпреЗрдХ рдлреЗрд░реА рдореНрд╣рдгрдЬреЗ рдкреВрд░реНрдг рд░рд╛рдВрдЧ. Insertion: рдкреБрдврдЪреЗ рдореВрд▓ рдШреНрдпрд╛ рдЖрдгрд┐ рддреНрдпрд╛рд▓рд╛ рдорд╛рдЧреЗ рддреНрдпрд╛рдЪреНрдпрд╛ рдЬрд╛рдЧреЗрдкрд░реНрдпрдВрдд рдиреНрдпрд╛ тАФ рд░рд╛рдВрдЧ рдЖрдзреАрдЪ рдЬрд╡рд│рдЬрд╡рд│ рдмрд░реЛрдмрд░ рдЕрд╕реЗрд▓ рддрд░ рдЬрд▓рдж. Merge: рд╡рд░реНрдЧрд╛рдЪреЗ рджреЛрди рдЕрд░реНрдзреЗ рдХрд░рд╛, рдкреНрд░рддреНрдпреЗрдХ рдЕрд░реНрдзрд╛ рдХреНрд░рдорд╛рдиреЗ рд▓рд╛рд╡рд╛ (рдкреБрдиреНрд╣рд╛ рдЕрд░реНрдзреЗ рдХрд░реВрдитАж), рдордЧ рджреЛрди рдХреНрд░рдорд╛рдиреЗ рд▓рд╛рд╡рд▓реЗрд▓реНрдпрд╛ рд░рд╛рдВрдЧрд╛ рдПрдХрддреНрд░ рдЧреБрдВрдлрд╛. Quick: рдПрдХ рдореВрд▓ рдирд┐рд╡рдбрд╛, рддреНрдпрд╛рдЪреНрдпрд╛рдкреЗрдХреНрд╖рд╛ рдмреБрдЯрдХреЗ рд╕рдЧрд│реЗ рдбрд╛рд╡реАрдХрдбреЗ, рдЙрдВрдЪ рдЙрдЬрд╡реАрдХрдбреЗ, рдкреНрд░рддреНрдпреЗрдХ рдмрд╛рдЬреВрд▓рд╛ рдкреБрдиреНрд╣рд╛ рдХрд░рд╛. рд╢реЗрд╡рдЯрдЪреЗ рджреЛрди рдЦреВрдкрдЪ рдХрдореА рдХрд╛рдо рдХрд░рддрд╛рдд тАФ рд╣реЗрдЪ n log n рд╡рд┐рд░реБрджреНрдз n┬▓.
ЁЯЧ║я╕П рдЖрдХреГрддреА
flowchart TD
A["[5 2 8 1 9 3]"] --> B["[5 2 8]"] & C["[1 9 3]"]
B --> B1["[2 5 8]"] ; C --> C1["[1 3 9]"]
B1 & C1 --> M["merge тЖТ [1 2 3 5 8 9]"]
тЭУ рдХрд╛рдп
| Sort | рд╡реЗрд│ | Space | Stable | рдЯрд┐рдкрд╛ |
|---|---|---|---|---|
| bubble | O(n┬▓) | O(1) | рд╣реЛ | рдлрдХреНрдд рдзрдбрд╛, рд╕рд╛рдзрди рдХрдзреАрдЪ рдирд╛рд╣реА |
| insertion | O(n┬▓), рдЬрд╡рд│рдЬрд╡рд│ sorted рдЕрд╕реЗрд▓ рддрд░ O(n) | O(1) | рд╣реЛ | рдЕрдЧрджреА рд▓рд╣рд╛рди рдХрд┐рдВрд╡рд╛ рдЬрд╡рд│рдЬрд╡рд│ sorted рд╕рд╛рдареА рдЙрддреНрддрдо |
| merge | рдиреЗрд╣рдореА O(n log n) | O(n) | рд╣реЛ | linked lists, external sorting |
| quick | рд╕рд░рд╛рд╕рд░реА O(n log n), worst O(n┬▓) | O(log n) | рдирд╛рд╣реА | рдкреНрд░рддреНрдпрдХреНрд╖рд╛рдд рд╕рд░реНрд╡рд╛рдд рдЬрд▓рдж in-place |
Timsort (sorted) |
O(n log n), runs рд╡рд░ O(n) | O(n) | рд╣реЛ | merge + insertion; Python рдЖрдгрд┐ Java рд╣реЗрдЪ рджреЗрддрд╛рдд |
- Stable = рд╕рдорд╛рди рдЙрдВрдЪреАрдЪреЗ рд╡рд┐рджреНрдпрд╛рд░реНрдереА рдЖрдкрд▓рд╛ рдореВрд│ рдХреНрд░рдо рдЯрд┐рдХрд╡рддрд╛рдд; рдПрдХрд╛рдорд╛рдЧреВрди рдПрдХ keys рдиреЗ sort
рдХрд░рддрд╛ рддреЗрд╡реНрд╣рд╛ рд╣реЗ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ (
sorted(rows, key=тАж)рджреЛрдирджрд╛). - Comparison sorts O(n log n) рдкреЗрдХреНрд╖рд╛ рдЪрд╛рдВрдЧрд▓реЗ рдХрд░реВ рд╢рдХрдд рдирд╛рд╣реАрдд; рд▓рд╣рд╛рди integers рд╕рд╛рдареА counting/radix sort рддреНрдпрд╛рд▓рд╛ рд╣рд░рд╡рддреЛ.
- рдПрдХрджрд╛ sort рдХрд░рд╛, рдордЧ binary search (рдзрдбрд╛ 08) рдХрд┐рдВрд╡рд╛ sweep (рдзрдбрд╛ 12).
ЁЯдФ рдХрд╛
рдХрд╛рдорд╛рд╡рд░ рддреБрдореНрд╣реА рдХрдзреАрдЪ sort рд▓рд┐рд╣рд┐рдгрд╛рд░ рдирд╛рд╣реА, рдЖрдгрд┐ рд░реЛрдЬ рдПрдХ рдмреЛрд▓рд╛рд╡рд╛рд▓. рдЖрдХрд╛рд░ рдорд╛рд╣реАрдд рдЕрд╕рд▓реЗ
рдХреА loop рдЪреНрдпрд╛ рдЖрддрд▓рд╛ sorted() рд╣рд╛ рддреБрдореНрд╣рд╛рд▓рд╛ рди рджрд┐рд╕рд▓реЗрд▓рд╛ n┬▓ рдХрдзреА рдЖрд╣реЗ рддреЗ рдХрд│рддреЗ,
рдЖрдгрд┐ heap (рдзрдбрд╛ 09) рдХрд┐рдВрд╡рд╛ dict (рдзрдбрд╛ 05) sorting рдкреВрд░реНрдгрдЪ рдХрдзреА рдЯрд╛рд│рддреЛ рддреЗрд╣реА.
ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)
рдкреНрд░рддреНрдпреЗрдХ sort рдПрдХ list рдШреЗрддреЛ рдЖрдгрд┐ рдирд╡реА list рд╡ рддрд┐рдЪрд╛ comparison count рдкрд░рдд рдХрд░рддреЛ;
demo.py sort рдЪрд╛рд░рд╣реА sorts рддреНрдпрд╛рдЪ random 2,000 рдЙрдВрдЪреАрдВрд╡рд░ рдЪрд╛рд▓рд╡рддреЛ, рддреЗ sorted рд╢реА
рдЬреБрд│рддрд╛рдд рд╣реЗ assert рдХрд░рддреЛ, рдордЧ рдЬрд╡рд│рдЬрд╡рд│ sorted рд░рд╛рдВрдЧреЗрд╡рд░ insertion рд╡рд┐рд░реБрджреНрдз bubble
рджрд╛рдЦрд╡рддреЛ, рдЖрдгрд┐ Timsort рдЪрд╛ рд╡реЗрд│.
ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛
python3 dsa/demo.py sort
python3 - <<'EOF'
import sys, random; sys.path.insert(0, "dsa"); from algorithms import quick_sort, merge_sort
worst = list(range(2000)) # already sorted: our quick_sort picks the middle pivot, so it is fine тАФ try the first element as pivot and watch n┬▓
print("quick on sorted input:", quick_sort(worst)[1], "comparisons")
rows = [("Katrina", "3A", 150), ("Aishwarya", "3A", 150), ("Dipika", "3B", 140)]
print(sorted(sorted(rows, key=lambda r: r[0]), key=lambda r: r[2])) # stable: ties keep the name order
EOF
тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ
Bubble ~2,000,000 comparisons, insertion ~1,000,000, merge ~19,000, quick
~13,000 тАФ рдЖрдгрд┐ milliseconds рдпрд╛ counts рдкреНрд░рдорд╛рдгреЗрдЪ рдпреЗрддрд╛рдд; рдЬрд╡рд│рдЬрд╡рд│ sorted рд░рд╛рдВрдЧреЗрд╡рд░
bubble рдЖрдгрд┐ insertion рджреЛрдШрд╛рдВрдирд╛рд╣реА ~2,000 рд▓рд╛рдЧрддрд╛рдд. sorted() рд╕рдЧрд│реНрдпрд╛рдд рдЬрд▓рдж рдЖрд╣реЗ.
sorted input рд╡рд░ quick: ~19,000 comparisons (рдордзрд▓рд╛ pivot рддреНрдпрд╛рд▓рд╛ рд╡рд╛рдЪрд╡рддреЛ). stable рджреБрд╣реЗрд░реА sort 150 рдЙрдВрдЪреАрд╡рд░ Aishwarya рд▓рд╛ Katrina рдЪреНрдпрд╛ рдЖрдзреА рдареЗрд╡рддреЛ.
ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ
n = 2,000 рд▓рд╛ n log n рд╡рд┐рд░реБрджреНрдз n┬▓ рд╣рд╛ рд╢рдВрднрд░ рдкрдЯреАрдЪрд╛ рдлрд░рдХ рдЖрд╣реЗ тАФ рддреБрдореНрд╣реА рддреЛ рдореЛрдЬрд▓рд╛рдд тАФ рдЖрдгрд┐ рдХреЛрдгрддреЗ sorts stable рдЖрд╣реЗрдд рдЖрдгрд┐ рддреЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ рдЖрд╣реЗ рд╣реЗ рддреБрдореНрд╣рд╛рд▓рд╛ рдорд╛рд╣реАрдд рдЖрд╣реЗ.
тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛
- loop рдЪреНрдпрд╛ рдЖрдд sorting (n┬▓ log n), рдЬрд┐рдереЗ рдмрд╛рд╣реЗрд░ рдПрдХ sort рдкреБрд░реЗрд╕рд╛ рд╣реЛрддрд╛.
sortunstable рдЖрд╣реЗ рдЕрд╕реЗ рд╕рдордЬреВрди рдЧрд░рдЬ рдирд╕рд▓реЗрд▓реЗ tie-breakers рд▓рд┐рд╣рд┐рдгреЗ (Python рдЪрд╛ stable рдЖрд╣реЗ).- sorted input рд╡рд░ рдкрд╣рд┐рд▓реНрдпрд╛ element рд▓рд╛ pivot рдШреЗрдКрди quick sort рд▓рд┐рд╣рд┐рдгреЗ: O(n┬▓).
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: database рдордзрд▓рд╛
ORDER BY, log pipelines, leaderboards, рдЖрдгрд┐ request handler рдордзрд▓рд╛ рдкреНрд░рддреНрдпреЗрдХsorted(...)тАФ рддреБрдореНрд╣реА рдЖрдХрд╛рд░ рдЖрдгрд┐ stability рдЪреНрдпрд╛ рд╣рдореАрд╡рд░рдЪ рдЕрд╡рд▓рдВрдмреВрди рдЕрд╕рддрд╛.
тПня╕П рдкреБрдвреЗ
рдзрдбрд╛ 08 тАФ binary search: рдХреНрд░рдорд╛рдиреЗ рд▓рд╛рд╡рд▓реЗрд▓реА рдиреЛрдВрджрд╡рд╣реА, рдЖрдгрд┐ рдЙрддреНрддрд░рд╛рд╡рд░ search.