Sorting algorithms. Sorting algorithms

Similar documents
Sorting DS 2017/2018

Fundamental Algorithms

Fundamental Algorithms

Bucket-Sort. Have seen lower bound of Ω(nlog n) for comparisonbased. Some cheating algorithms achieve O(n), given certain assumptions re input

Review Of Topics. Review: Induction

Data Structures and Algorithms

1. Basic Algorithms: Bubble Sort

Sorting. CS 3343 Fall Carola Wenk Slides courtesy of Charles Leiserson with small changes by Carola Wenk

Problem. Problem Given a dictionary and a word. Which page (if any) contains the given word? 3 / 26

Linear Selection and Linear Sorting

1. Basic Algorithms: Bubble Sort

Fast Sorting and Selection. A Lower Bound for Worst Case

Data selection. Lower complexity bound for sorting

Find an Element x in an Unsorted Array

Randomized Sorting Algorithms Quick sort can be converted to a randomized algorithm by picking the pivot element randomly. In this case we can show th

Sorting. Chapter 11. CSE 2011 Prof. J. Elder Last Updated: :11 AM

CS 361, Lecture 14. Outline

Central Algorithmic Techniques. Iterative Algorithms

Module 1: Analyzing the Efficiency of Algorithms

Outline. 1 Introduction. 3 Quicksort. 4 Analysis. 5 References. Idea. 1 Choose an element x and reorder the array as follows:

Lecture 1: Asymptotics, Recurrences, Elementary Sorting

Algorithms and Their Complexity

Algorithms, CSE, OSU Quicksort. Instructor: Anastasios Sidiropoulos

Advanced Analysis of Algorithms - Midterm (Solutions)

CSCI 3110 Assignment 6 Solutions

Space Complexity of Algorithms

COMP 9024, Class notes, 11s2, Class 1

CS 161 Summer 2009 Homework #2 Sample Solutions

Sorting. CMPS 2200 Fall Carola Wenk Slides courtesy of Charles Leiserson with changes and additions by Carola Wenk

COMP 382: Reasoning about algorithms

Week 5: Quicksort, Lower bound, Greedy

Randomized Load Balancing:The Power of 2 Choices

CS 332: Algorithms. Linear-Time Sorting. Order statistics. Slide credit: David Luebke (Virginia)

About complexity. Number theoretical algorithms

Bin Sort. Sorting integers in Range [1,...,n] Add all elements to table and then

Lecture 5: Loop Invariants and Insertion-sort

MIDTERM I CMPS Winter 2013 Warmuth

Module 1: Analyzing the Efficiency of Algorithms

Quicksort algorithm Average case analysis

Algorithms and Data Structures 2016 Week 5 solutions (Tues 9th - Fri 12th February)

COL 730: Parallel Programming

Data Structures and Algorithms Running time and growth functions January 18, 2018

CS325: Analysis of Algorithms, Fall Midterm

i=1 i B[i] B[i] + A[i, j]; c n for j n downto i + 1 do c n i=1 (n i) C[i] C[i] + A[i, j]; c n

CS Non-recursive and Recursive Algorithm Analysis

Analysis of Algorithm Efficiency. Dr. Yingwu Zhu

Quicksort. Where Average and Worst Case Differ. S.V. N. (vishy) Vishwanathan. University of California, Santa Cruz

1 Quick Sort LECTURE 7. OHSU/OGI (Winter 2009) ANALYSIS AND DESIGN OF ALGORITHMS

Algorithms. Quicksort. Slide credit: David Luebke (Virginia)

Recommended readings: Description of Quicksort in my notes, Ch7 of your CLRS text.

Lecture 4. Quicksort

Quicksort (CLRS 7) We previously saw how the divide-and-conquer technique can be used to design sorting algorithm Merge-sort

Inf 2B: Sorting, MergeSort and Divide-and-Conquer

b + O(n d ) where a 1, b > 1, then O(n d log n) if a = b d d ) if a < b d O(n log b a ) if a > b d

Divide-and-conquer: Order Statistics. Curs: Fall 2017

Amortized analysis. Amortized analysis

CS Analysis of Recursive Algorithms and Brute Force

Sorting and Searching. Tony Wong

data structures and algorithms lecture 2

N/4 + N/2 + N = 2N 2.

CSC 8301 Design & Analysis of Algorithms: Lower Bounds

Lecture 2. Fundamentals of the Analysis of Algorithm Efficiency

Lecture 17: Trees and Merge Sort 10:00 AM, Oct 15, 2018

CS 4407 Algorithms Lecture 2: Iterative and Divide and Conquer Algorithms

Chapter 2. Recurrence Relations. Divide and Conquer. Divide and Conquer Strategy. Another Example: Merge Sort. Merge Sort Example. Merge Sort Example

Searching. Sorting. Lambdas

Data Structures and Algorithm Analysis (CSC317) Randomized algorithms

Insertion Sort. We take the first element: 34 is sorted

CS483 Design and Analysis of Algorithms

Ch01. Analysis of Algorithms

CMPT 307 : Divide-and-Conqer (Study Guide) Should be read in conjunction with the text June 2, 2015

Data Structures and Algorithms CSE 465

Asymptotic Running Time of Algorithms

Computational Complexity - Pseudocode and Recursions

Asymptotic Analysis. Slides by Carl Kingsford. Jan. 27, AD Chapter 2

Analysis of Algorithms. Randomizing Quicksort

Longest Common Prefixes

Data Structures and Algorithms

Divide and conquer. Philip II of Macedon

CSCE 750, Spring 2001 Notes 2 Page 1 4 Chapter 4 Sorting ffl Reasons for studying sorting is a big deal pedagogically useful Λ the application itself

P, NP, NP-Complete, and NPhard

Algorithms. Algorithms 2.2 MERGESORT. mergesort bottom-up mergesort sorting complexity divide-and-conquer ROBERT SEDGEWICK KEVIN WAYNE

Problem Set 2 Solutions

Data Structures and Algorithms Chapter 3

Algorithm efficiency analysis

CIS 121. Analysis of Algorithms & Computational Complexity. Slides based on materials provided by Mary Wootters (Stanford University)

CPS 616 DIVIDE-AND-CONQUER 6-1

CS161: Algorithm Design and Analysis Recitation Section 3 Stanford University Week of 29 January, Problem 3-1.

Ch 01. Analysis of Algorithms

Data structures Exercise 1 solution. Question 1. Let s start by writing all the functions in big O notation:

Analysis of Algorithms - Midterm (Solutions)

5. DIVIDE AND CONQUER I

2.2 Asymptotic Order of Growth. definitions and notation (2.2) examples (2.4) properties (2.2)

Divide and Conquer Algorithms. CSE 101: Design and Analysis of Algorithms Lecture 14

Data Structures and Algorithm Analysis (CSC317) Randomized Algorithms (part 3)

Chapter 5 Data Structures Algorithm Theory WS 2017/18 Fabian Kuhn

ITEC2620 Introduction to Data Structures

CS 577 Introduction to Algorithms: Strassen s Algorithm and the Master Theorem

Digital Logic Design: a rigorous approach c

Analysis of Algorithms I: Asymptotic Notation, Induction, and MergeSort

Transcription:

Properties of sorting algorithms A sorting algorithm is Comparison based If it works by pairwise key comparisons. In place If only a constant number of elements of the input array are ever stored outside the array. Stable If it preserve thes relative order of elements with equal keys. The space complexity of a sorting algorithm is the amount of memory it uses in addition to the input array. Insertion Sort Merge Sort Quicksort Θ(1). Θ(n). Θ(n) (worst case).

Lower bound for comparison based sorting algorithms All possible runs of a comparison based sorting algorithm can be modeled by a decision tree. The height of the decision tree is a lower bound on the time complexity of the algorithm. The decision tree of insertion sort for n = 3 is shown below. 1:2 2:3 1:3 1,2,3 1:3 2,1,3 2:3 1,3,2 3,1,2 2,3,1 3,2,1

Lower bound for comparison based sorting algorithms Theorem For every comparison based sorting algorithm, the decision tree for n elements has height Ω(n log n). Proof. The number of leaves in the tree is n!. A binary tree with height h has 2 h leaves. Therefore, 2 h n! h log(n!). By Stirling s approximation, n! (n/e) n. Therefore, h log ((n/e) n ) = n log(n/e) = n log n n log e = Ω(n log n)

Lower bound for comparison based sorting algorithms Lemma A binary tree with height h has 2 h leaves. Proof. The proof is by induction on h. The base h = 0 is true. If T is a binary tree of height h > 0, then removing the root of T gives two trees T 1, T 2 of height at most h 1 each. By induction, each of T 1, T 2 has 2 h 1 leaves. Therefore, T has 2 2 h 1 = 2 h leaves.

Sorting in linear time We will see several sorting algorithms that run in Θ(n) time: Counting Sort. Radix Sort. Bucket Sort. These algorithms are not comparison based.

Counting Sort A = Input array. Values in A are from {0, 1,..., k}. B = Output array. 1 2 3 4 5 6 7 8 CountingSort(A, B, k) A 2 5 3 0 2 3 0 3 (1) Let C[0..k] be a new array 0 1 2 3 4 5 (2) for i = 0 to k C 0 0 0 0 0 0 (3) C[i] 0 (4) for j = 1 to A.length (5) C[A[j]] C[A[j]] + 1 % C[i] now contains the number of elements = i (6) for i = 1 to k (7) C[i] C[i] + C[i 1] % C[i] now contains the number of elements i (8) for j = A.length downto 1 (9) B[C[A[j]]] A[j] (10) C[A[j]] C[A[j]] 1

Counting Sort A = Input array. Values in A are from {0, 1,..., k}. B = Output array. 1 2 3 4 5 6 7 8 CountingSort(A, B, k) A 2 5 3 0 2 3 0 3 (1) Let C[0..k] be a new array 0 1 2 3 4 5 (2) for i = 0 to k C 0 0 1 0 0 0 (3) C[i] 0 (4) for j = 1 to A.length (5) C[A[j]] C[A[j]] + 1 % C[i] now contains the number of elements = i (6) for i = 1 to k (7) C[i] C[i] + C[i 1] % C[i] now contains the number of elements i (8) for j = A.length downto 1 (9) B[C[A[j]]] A[j] (10) C[A[j]] C[A[j]] 1

Counting Sort A = Input array. Values in A are from {0, 1,..., k}. B = Output array. 1 2 3 4 5 6 7 8 CountingSort(A, B, k) A 2 5 3 0 2 3 0 3 (1) Let C[0..k] be a new array 0 1 2 3 4 5 (2) for i = 0 to k C 0 0 1 0 0 1 (3) C[i] 0 (4) for j = 1 to A.length (5) C[A[j]] C[A[j]] + 1 % C[i] now contains the number of elements = i (6) for i = 1 to k (7) C[i] C[i] + C[i 1] % C[i] now contains the number of elements i (8) for j = A.length downto 1 (9) B[C[A[j]]] A[j] (10) C[A[j]] C[A[j]] 1

Counting Sort A = Input array. Values in A are from {0, 1,..., k}. B = Output array. 1 2 3 4 5 6 7 8 CountingSort(A, B, k) A 2 5 3 0 2 3 0 3 (1) Let C[0..k] be a new array 0 1 2 3 4 5 (2) for i = 0 to k C 2 0 2 3 0 1 (3) C[i] 0 (4) for j = 1 to A.length (5) C[A[j]] C[A[j]] + 1 % C[i] now contains the number of elements = i (6) for i = 1 to k (7) C[i] C[i] + C[i 1] % C[i] now contains the number of elements i (8) for j = A.length downto 1 (9) B[C[A[j]]] A[j] (10) C[A[j]] C[A[j]] 1

Counting Sort A = Input array. Values in A are from {0, 1,..., k}. B = Output array. 1 2 3 4 5 6 7 8 CountingSort(A, B, k) A 2 5 3 0 2 3 0 3 (1) Let C[0..k] be a new array 0 1 2 3 4 5 (2) for i = 0 to k C 2 2 2 3 0 1 (3) C[i] 0 (4) for j = 1 to A.length (5) C[A[j]] C[A[j]] + 1 % C[i] now contains the number of elements = i (6) for i = 1 to k (7) C[i] C[i] + C[i 1] % C[i] now contains the number of elements i (8) for j = A.length downto 1 (9) B[C[A[j]]] A[j] (10) C[A[j]] C[A[j]] 1

Counting Sort A = Input array. Values in A are from {0, 1,..., k}. B = Output array. 1 2 3 4 5 6 7 8 CountingSort(A, B, k) A 2 5 3 0 2 3 0 3 (1) Let C[0..k] be a new array 0 1 2 3 4 5 (2) for i = 0 to k C 2 2 4 3 0 1 (3) C[i] 0 (4) for j = 1 to A.length (5) C[A[j]] C[A[j]] + 1 % C[i] now contains the number of elements = i (6) for i = 1 to k (7) C[i] C[i] + C[i 1] % C[i] now contains the number of elements i (8) for j = A.length downto 1 (9) B[C[A[j]]] A[j] (10) C[A[j]] C[A[j]] 1

Counting Sort A = Input array. Values in A are from {0, 1,..., k}. B = Output array. 1 2 3 4 5 6 7 8 CountingSort(A, B, k) A 2 5 3 0 2 3 0 3 (1) Let C[0..k] be a new array 0 1 2 3 4 5 (2) for i = 0 to k C 2 2 4 7 7 8 (3) C[i] 0 (4) for j = 1 to A.length (5) C[A[j]] C[A[j]] + 1 B % C[i] now contains the number of elements = i (6) for i = 1 to k (7) C[i] C[i] + C[i 1] % C[i] now contains the number of elements i (8) for j = A.length downto 1 (9) B[C[A[j]]] A[j] (10) C[A[j]] C[A[j]] 1

Counting Sort A = Input array. Values in A are from {0, 1,..., k}. B = Output array. 1 2 3 4 5 6 7 8 CountingSort(A, B, k) A 2 5 3 0 2 3 0 3 (1) Let C[0..k] be a new array 0 1 2 3 4 5 (2) for i = 0 to k C 2 2 4 7 7 8 (3) C[i] 0 (4) for j = 1 to A.length (5) C[A[j]] C[A[j]] + 1 B 3 % C[i] now contains the number of elements = i (6) for i = 1 to k (7) C[i] C[i] + C[i 1] % C[i] now contains the number of elements i (8) for j = A.length downto 1 (9) B[C[A[j]]] A[j] (10) C[A[j]] C[A[j]] 1

Counting Sort A = Input array. Values in A are from {0, 1,..., k}. B = Output array. 1 2 3 4 5 6 7 8 CountingSort(A, B, k) A 2 5 3 0 2 3 0 3 (1) Let C[0..k] be a new array 0 1 2 3 4 5 (2) for i = 0 to k C 2 2 4 6 7 8 (3) C[i] 0 (4) for j = 1 to A.length (5) C[A[j]] C[A[j]] + 1 B 3 % C[i] now contains the number of elements = i (6) for i = 1 to k (7) C[i] C[i] + C[i 1] % C[i] now contains the number of elements i (8) for j = A.length downto 1 (9) B[C[A[j]]] A[j] (10) C[A[j]] C[A[j]] 1

Counting Sort A = Input array. Values in A are from {0, 1,..., k}. B = Output array. CountingSort(A, B, k) A 5 3 0 (1) Let C[0..k] be a new array 0 (2) for i = 0 to k C 2 (3) C[i] 0 (4) for j = 1 to A.length (5) C[A[j]] C[A[j]] + 1 1 2 3 4 5 6 7 8 2 2 3 0 3 1 2 3 4 5 2 4 6 7 8 B 0 3 % C[i] now contains the number of elements = i (6) for i = 1 to k (7) C[i] C[i] + C[i 1] % C[i] now contains the number of elements i (8) for j = A.length downto 1 (9) B[C[A[j]]] A[j] (10) C[A[j]] C[A[j]] 1

Counting Sort A = Input array. Values in A are from {0, 1,..., k}. B = Output array. CountingSort(A, B, k) A 5 3 0 (1) Let C[0..k] be a new array 0 (2) for i = 0 to k C 1 (3) C[i] 0 (4) for j = 1 to A.length (5) C[A[j]] C[A[j]] + 1 1 2 3 4 5 6 7 8 2 2 3 0 3 1 2 3 4 5 2 4 6 7 8 B 0 3 % C[i] now contains the number of elements = i (6) for i = 1 to k (7) C[i] C[i] + C[i 1] % C[i] now contains the number of elements i (8) for j = A.length downto 1 (9) B[C[A[j]]] A[j] (10) C[A[j]] C[A[j]] 1

Counting Sort A = Input array. Values in A are from {0, 1,..., k}. B = Output array. CountingSort(A, B, k) A 5 3 0 (1) Let C[0..k] be a new array 0 (2) for i = 0 to k C 1 (3) C[i] 0 (4) for j = 1 to A.length (5) C[A[j]] C[A[j]] + 1 1 2 3 4 5 6 7 8 2 2 3 0 3 1 2 3 4 5 2 4 6 7 8 B 0 3 3 % C[i] now contains the number of elements = i (6) for i = 1 to k (7) C[i] C[i] + C[i 1] % C[i] now contains the number of elements i (8) for j = A.length downto 1 (9) B[C[A[j]]] A[j] (10) C[A[j]] C[A[j]] 1

Counting Sort A = Input array. Values in A are from {0, 1,..., k}. B = Output array. CountingSort(A, B, k) A 5 3 0 (1) Let C[0..k] be a new array 0 (2) for i = 0 to k C 1 (3) C[i] 0 (4) for j = 1 to A.length (5) C[A[j]] C[A[j]] + 1 1 2 3 4 5 6 7 8 2 2 3 0 3 1 2 3 4 5 2 4 5 7 8 B 0 3 3 % C[i] now contains the number of elements = i (6) for i = 1 to k (7) C[i] C[i] + C[i 1] % C[i] now contains the number of elements i (8) for j = A.length downto 1 (9) B[C[A[j]]] A[j] (10) C[A[j]] C[A[j]] 1

Counting Sort A = Input array. Values in A are from {0, 1,..., k}. B = Output array. CountingSort(A, B, k) A 5 3 0 (1) Let C[0..k] be a new array 0 (2) for i = 0 to k C 0 (3) C[i] 0 (4) for j = 1 to A.length (5) C[A[j]] C[A[j]] + 1 1 2 3 4 5 6 7 8 2 2 3 0 3 1 2 3 4 5 2 2 4 7 7 B 0 0 2 2 3 3 3 5 % C[i] now contains the number of elements = i (6) for i = 1 to k (7) C[i] C[i] + C[i 1] % C[i] now contains the number of elements i (8) for j = A.length downto 1 (9) B[C[A[j]]] A[j] (10) C[A[j]] C[A[j]] 1

Counting Sort Time complexity: Θ(n + k). If k = O(n) then the time is Θ(n). CountingSort(A, B, k) (1) Let C[0..k] be a new array (2) for i = 0 to k (3) C[i] 0 (4) for j = 1 to A.length (5) C[A[j]] C[A[j]] + 1 2 5 3 0 2 3 0 3 % C[i] now contains the number of elements = i (6) for i = 1 to k (7) C[i] C[i] + C[i 1] % C[i] now contains the number of elements i (8) for j = A.length downto 1 (9) B[C[A[j]]] A[j] (10) C[A[j]] C[A[j]] 1 A C 1 2 3 4 5 6 7 8 0 0 1 2 3 4 5 2 2 4 7 7 B 0 0 2 2 3 3 3 5

Counting Sort Counting Sort is stable (elements with same key maintain their relative order). A 1 2 3 4 5 6 7 8 2 5 3 0 2 3 0 3 B 0 0 2 2 3 3 3 5

Radix Sort A = Input array. Values in A are numbers with d digits. RadixSort(A, d) (1) for i = 1 to d (2) Use a stable sort to sort array A on digit i 329 457 657 839 436 720 355 720 355 436 457 657 329 839 720 329 436 839 355 457 657 329 355 436 457 657 720 839

Time complexity In the following, assume that the stable sorting algorithm used by radix sort is Counting Sort. Claim Given n numbers, where each number has d digits in base k, the time complexity of Radix Sort is Θ(d(n + k)). Proof. The algorithm has d iterations. The time of a single iteration is Θ(n + k).

Time complexity Claim Given n b-bits numbers, and r b, the time complexity of Radix Sort is Θ((b/r)(n + 2 r )). Proof. Each number can be viewed as a number in base k = 2 r with d = b/r digits. The time complexity is Θ(d(n + k)) = Θ((b/r)(n + 2 r )). 011101001 b=9, r=3 3 5 1

Choosing r example Suppose that n = 50000 and b = 32. r d = b/r k = 2 r (b/r)(n + 2 r ) 1 32 2 32 (50000 + 2) = 1600064 2 16 4 16 (50000 + 4) = 800064 3 11 8 11 (50000 + 8) = 550088. 9 4 512 4 (50000 + 512) = 202048 10 4 1024 4 (50000 + 1024) = 204096 11 3 2048 3 (50000 + 2048) = 156144 12 3 4096 3 (50000 + 4096) = 162288 13 3 8192 3 (50000 + 8192) = 174576 14 3 16384 3 (50000 + 16384) = 199152 15 3 32768 3 (50000 + 32768) = 248304 16 2 65536 2 (50000 + 65536) = 231072.

Choosing r Claim Given n b-bits numbers, the time complexity of Radix Sort is Θ(n) if b log n Θ(bn/ log n) if b > log n. Proof. If b log n: For every r b, (b/r)(n + 2 r ) (b/r)(n + n) = 2b/r n. For b = r, the time is Θ(n) which is optimal. If b > log n: For r = log n, (b/r)(n + 2 r ) = Θ((b/ log n)n). If r < log n, the b/r term increases while the n + 2 r term remains Θ(n). If r > log n, the 2 r term increases faster than the r term in the denominator.

Choosing r example Suppose that n = 50000 and b = 32. log 2 n = 15.609, so an asymptotically optimal choice is r = 15.

Bucket Sort The Bucket Sort algorithm sorts an array whose elements are numbers from the interval [0, 1). The main idea is to partition the interval [0, 1) into n intervals of equal lengths. The elements of the array are partitioned into buckets according to the intervals. Then, each bucket is sorted using some sorting algorithm (for example, insertion sort).

Bucket Sort A = Input array. 0 A[i] < 1 for all i. 0.72 BucketSort(A) 0.17 1 (1) n A.length 0.78 2 (2) Let B[0..n 1] be a new array 0.26 3 (3) for i = 0 to n 1 0.39 4 (4) B[i] NULL 0.94 5 0.21 6 (5) for i = 1 to n 0.12 7 (6) Insert A[i] to list B[ na[i] ] 0.23 8 (7) for i = 0 to n 1 0.68 9 (8) Sort B[i] (with Insertion Sort) (9) Concatenate the lists B[0], B[1],..., B[n 1] in order A 0 B

Bucket Sort A = Input array. 0 A[i] < 1 for all i. 0.72 BucketSort(A) 0.17 1 (1) n A.length 0.78 2 (2) Let B[0..n 1] be a new array 0.26 3 (3) for i = 0 to n 1 0.39 4 (4) B[i] NULL 0.94 5 0.21 6 (5) for i = 1 to n 0.12 7 0.72 (6) Insert A[i] to list B[ na[i] ] 0.23 8 (7) for i = 0 to n 1 0.68 9 (8) Sort B[i] (with Insertion Sort) (9) Concatenate the lists B[0], B[1],..., B[n 1] in order A 0 B

Bucket Sort A = Input array. 0 A[i] < 1 for all i. 0.72 BucketSort(A) 0.17 1 (1) n A.length 0.78 2 0.17 (2) Let B[0..n 1] be a new array 0.26 3 (3) for i = 0 to n 1 0.39 4 (4) B[i] NULL 0.94 5 0.21 6 (5) for i = 1 to n 0.12 7 0.72 (6) Insert A[i] to list B[ na[i] ] 0.23 8 (7) for i = 0 to n 1 0.68 9 (8) Sort B[i] (with Insertion Sort) (9) Concatenate the lists B[0], B[1],..., B[n 1] in order A 0 B

Bucket Sort A = Input array. 0 A[i] < 1 for all i. 0.72 BucketSort(A) 0.17 1 (1) n A.length 0.78 2 0.17 (2) Let B[0..n 1] be a new array 0.26 3 (3) for i = 0 to n 1 0.39 4 (4) B[i] NULL 0.94 5 0.21 6 (5) for i = 1 to n 0.12 7 0.78 (6) Insert A[i] to list B[ na[i] ] 0.23 8 (7) for i = 0 to n 1 0.68 9 (8) Sort B[i] (with Insertion Sort) (9) Concatenate the lists B[0], B[1],..., B[n 1] in order A 0 B 0.72

Bucket Sort A = Input array. 0 A[i] < 1 for all i. 0.72 BucketSort(A) 0.17 1 (1) n A.length 0.78 2 0.12 (2) Let B[0..n 1] be a new array 0.26 3 0.39 (3) for i = 0 to n 1 0.39 4 (4) B[i] NULL 0.94 5 0.21 6 0.68 (5) for i = 1 to n 0.12 7 0.78 (6) Insert A[i] to list B[ na[i] ] 0.23 8 (7) for i = 0 to n 1 0.68 9 0.94 (8) Sort B[i] (with Insertion Sort) (9) Concatenate the lists B[0], B[1],..., B[n 1] in order A 0 B 0.17 0.23 0.21 0.26 0.72

Bucket Sort A = Input array. 0 A[i] < 1 for all i. 0.72 BucketSort(A) 0.17 1 (1) n A.length 0.78 2 0.12 (2) Let B[0..n 1] be a new array 0.26 3 0.39 (3) for i = 0 to n 1 0.39 4 (4) B[i] NULL 0.94 5 0.21 6 0.68 (5) for i = 1 to n 0.12 7 0.72 (6) Insert A[i] to list B[ na[i] ] 0.23 8 (7) for i = 0 to n 1 0.68 9 0.94 (8) Sort B[i] (with Insertion Sort) (9) Concatenate the lists B[0], B[1],..., B[n 1] in order A 0 B 0.17 0.21 0.23 0.26 0.78

Time complexity Assume that the elements of A are chosen randomly from [0, 1) (uniformly and independently). Let n i be the number of elements in B[i]. The expected time complexity is [ ] n 1 n 1 E Θ(n) + O(ni 2 ) = Θ(n) + E[O(ni 2 )] i=0 i=0 n 1 = Θ(n) + O(E[ni 2 ]) i=0 = Θ(n) + O(n E[n 2 1])

Time complexity Let X i = 1 if A[i] falls to bucket 1. n 1 = n i=1 X i ( n ) 2 E[n1] 2 = E X i i=1 i=1 n = E Xi 2 + = n i=1 E[X 2 i ] + n i=1 n X i X j j=1 j i n E[X i X j ] j=1 j i = ne[x 2 1 ] + n(n 1)E[X 1 X 2 ]

Time complexity Therefore, ( E[X1 2 ] = 0 1 1 ) + 1 1 n n = 1 n E[X 1 X 2 ] = 0 (1 1n ) + 1 1 2 n = 1 2 n 2 E[n1] 2 = n 1 1 + n(n 1) n n = 1 + n 1 2 n = 2 1 n. The expected time complexity of Bucket Sort is Θ(n).