อัลกอริธึมการเรียงลำดับที่เก็บข้อมูล (Java, Python, ค/C++ Code ตัวอย่าง)

⚡ สรุปอย่างชาญฉลาด

อัลกอริทึม Bucket Sort จะกระจายข้อมูลอินพุตไปยังถังหลายถัง จัดเรียงข้อมูลในแต่ละถังอย่างอิสระ และรวบรวมถังเหล่านั้นเข้าด้วยกันเพื่อสร้างอาร์เรย์ที่เรียงลำดับแล้วในขั้นสุดท้าย

  • 🪣 แนวคิดหลัก: Bucket Sort จะแบ่งค่าออกเป็นกลุ่มๆ จัดเรียงแต่ละกลุ่ม แล้วนำมารวมกันตามลำดับ
  • 📊 เหมาะสมที่สุด: อัลกอริทึม Bucket Sort ทำงานได้ดีที่สุดกับตัวเลขทศนิยมที่มีการกระจายตัวอย่างสม่ำเสมอในช่วง [0.0, 1.0] หรือตัวเลขจำนวนเต็มที่กระจายตัวอย่างสม่ำเสมอ
  • ความซับซ้อนของเวลา: กรณีเฉลี่ยและกรณีที่ดีที่สุดจะใช้เวลาเชิงเส้น O(n+k) ส่วนกรณีที่แย่ที่สุดจะใช้เวลา O(n²)
  • ข้อดี: สามารถประมวลผลบัคเก็ตได้แบบขนาน เหมาะสำหรับการจัดเรียงข้อมูลขนาดใหญ่จากภายนอก
  • 🧪 การดำเนินการ: Code ใน C, C++, Pythonและ Java แสดงให้เห็นทั้งรูปแบบเลขทศนิยมและเลขจำนวนเต็ม

Bucket Sort คืออะไร?

การเรียงลำดับแบบบัคเก็ต (Bucket Sort) หรือที่เรียกกันทั่วไปว่า การเรียงลำดับแบบบิน (Bin Sort) เป็นวิธีการเรียงลำดับแบบกระจายโดยใช้การเปรียบเทียบ ซึ่งรับอาร์เรย์ที่ยังไม่เรียงลำดับเป็นอินพุต และสร้างอาร์เรย์ที่เรียงลำดับแล้วเป็นเอาต์พุต เทคนิคนี้จะกระจายองค์ประกอบไปยังบัคเก็ตหลาย ๆ อัน และเรียงลำดับแต่ละบัคเก็ตแยกกันโดยใช้อัลกอริทึมการเรียงลำดับอื่น เช่น การเรียงลำดับแบบแทรก (Insertion Sort) จากนั้น บัคเก็ตทั้งหมดจะถูกรวมเข้าด้วยกันเพื่อสร้างอาร์เรย์ที่เรียงลำดับแล้วในที่สุด

การเรียงลำดับแบบ Bucket Sort มักใช้เมื่อองค์ประกอบต่างๆ มีลักษณะดังนี้:

  1. ค่าจุดลอยตัว
  2. กระจายอย่างสม่ำเสมอในช่วงที่ทราบ

ความซับซ้อนเชิงเวลาของ Bucket Sort ขึ้นอยู่กับจำนวนถังที่ใช้และความสม่ำเสมอของการกระจายข้อมูลขาเข้า ในขณะที่อัลกอริธึมการเรียงลำดับอื่นๆ เช่น การเรียงลำดับเปลือก, การเรียงลำดับแบบผสาน, ฮีปเรียงลำดับ และ Quicksort อัลกอริทึม Bucket Sort สามารถทำได้ในเวลาที่มีประสิทธิภาพสูงสุด O(n*logn) และสามารถทำได้ในเวลาเชิงเส้น O(n) ภายใต้เงื่อนไขที่เอื้ออำนวย

การเรียงลำดับแบบ Bucket Sort ใช้แนวทางแบบกระจายและรวบรวม (scatter-gather) โดยจะกระจายองค์ประกอบไปยังถัง (bucket) ที่สอดคล้องกัน ทำการเรียงลำดับภายในแต่ละถัง และรวบรวมเข้าด้วยกันเพื่อสร้างอาร์เรย์ที่เรียงลำดับแล้วในขั้นตอนสุดท้าย แนวทางแบบกระจายและรวบรวมนี้จะกล่าวถึงในหัวข้อถัดไป

วิธีการกระจายและรวบรวม

ปัญหาขนาดใหญ่และซับซ้อนบางครั้งอาจแก้ไขได้ยากโดยตรง วิธีการกระจายและรวบรวม (scatter-gather) ช่วยแก้ปัญหาดังกล่าวโดยการแบ่งชุดข้อมูลทั้งหมดออกเป็นกลุ่มๆ แต่ละกลุ่มจะได้รับการประมวลผลแยกกัน และผลลัพธ์จะถูกนำมารวมกันอีกครั้งเพื่อสร้างคำตอบสุดท้าย

ต่อไปนี้คือวิธีที่อัลกอริทึม Bucket Sort นำวิธีการกระจายและรวบรวมมาใช้:

วิธีการกระจายและรวบรวม

การเรียงลำดับถังทำงานอย่างไร

หลักการทำงานพื้นฐานของ Bucket Sort มีดังนี้:

  1. มีการสร้างชุดถังเปล่าขึ้นมา โดยจำนวนถังอาจแตกต่างกันไปขึ้นอยู่กับนโยบายที่เลือก
  2. จากอาร์เรย์อินพุต แต่ละองค์ประกอบจะถูกจัดวางลงในถังที่ตรงกัน
  3. แต่ละถังจะถูกจัดเรียงแยกกันโดยใช้อัลกอริทึมการจัดเรียงรอง
  4. บัคเก็ตที่เรียงลำดับแล้วจะถูกรวมเข้าด้วยกันเพื่อสร้างอาร์เรย์เอาต์พุตเดียว

ชื่อเล่น Code

Start
Create N empty buckets
For each array element:
    Calculate bucket index
    Put that element into the corresponding bucket
For each bucket:
    Sort elements within each bucket
Merge all the elements from each bucket
Output the sorted array
End

วิธีที่ 1: อัลกอริทึมการเรียงลำดับบัคเก็ตสำหรับจุดลอยตัว Numbers

อัลกอริทึม Bucket Sort สำหรับจำนวนทศนิยมในช่วง [0.0, 1.0]:

ขั้นตอน 1) สร้างถังเปล่าจำนวนสิบ (10) ถัง ถังแรกบรรจุตัวเลขในช่วง [0.0, 0.1] ถังที่สองบรรจุตัวเลขในช่วง [0.1, 0.2] และต่อไปเรื่อยๆ

ขั้นตอน 2) สำหรับแต่ละองค์ประกอบอาร์เรย์:

  • ก. คำนวณดัชนีถังโดยใช้สูตร:
    ดัชนีของบัคเก็ต = จำนวนบัคเก็ต * องค์ประกอบของอาร์เรย์
  • b. แทรกองค์ประกอบลงใน bucket[bucket_index]

ขั้นตอน 3) จัดเรียงแต่ละที่เก็บข้อมูลแยกกันโดยใช้การเรียงลำดับการแทรก

ขั้นตอน 4) รวมบัคเก็ตทั้งหมดเข้าเป็นอาร์เรย์เดียวที่เรียงลำดับแล้ว

เรามาลองดูตัวอย่างการเรียงลำดับแบบ Bucket Sort กัน ในตัวอย่างนี้ เราจะเรียงลำดับอาร์เรย์ต่อไปนี้:

อัลกอริธึมการเรียงลำดับ Bucket สำหรับจุดลอยตัว Numbers

ขั้นตอน 1) ขั้นแรก เราสร้างถังเปล่า 10 ใบ ถังใบแรกบรรจุตัวเลขในช่วง [0.0, 0.1) ถังใบที่สองบรรจุตัวเลขในช่วง [0.1, 0.2) และต่อไปเรื่อยๆ

อัลกอริธึมการเรียงลำดับ Bucket สำหรับจุดลอยตัว Numbers

ขั้นตอน 2) สำหรับแต่ละองค์ประกอบในอาร์เรย์ ให้คำนวณดัชนีของกลุ่ม (bucket index) และวางองค์ประกอบนั้นลงในกลุ่มนั้น

ดัชนีถัง (Bucket Index) คำนวณโดยใช้สูตร:
        ดัชนีของบัคเก็ต = จำนวนบัคเก็ต * องค์ประกอบของอาร์เรย์

การคำนวณดัชนีถัง:
a) 0.78
      ดัชนีของบัคเก็ต = จำนวนบัคเก็ต * องค์ประกอบของอาร์เรย์
              =10*0.78
              = 7.8
ดังนั้น องค์ประกอบ 0.78 จะถูกเก็บไว้ใน bucket[floor(7.8)] หรือ bucket[7]

อัลกอริธึมการเรียงลำดับ Bucket สำหรับจุดลอยตัว Numbers

b) 0.17
      ดัชนีของบัคเก็ต = จำนวนบัคเก็ต * องค์ประกอบของอาร์เรย์
              =10*0.17
              = 1.7

องค์ประกอบอาร์เรย์ 0.17 ถูกเก็บไว้ใน bucket[floor(1.7)] หรือ bucket[1]

อัลกอริธึมการเรียงลำดับ Bucket สำหรับจุดลอยตัว Numbers

c) 0.39
      ดัชนีของบัคเก็ต = จำนวนบัคเก็ต * องค์ประกอบของอาร์เรย์
              =10*0.39
              = 3.9
0.39 ถูกเก็บไว้ใน bucket[floor(3.9)] หรือ bucket[3]

อัลกอริธึมการเรียงลำดับ Bucket สำหรับจุดลอยตัว Numbers

หลังจากวนลูปผ่านองค์ประกอบทั้งหมดในอาร์เรย์แล้ว กลุ่มข้อมูลจะมีลักษณะดังนี้:

อัลกอริธึมการเรียงลำดับ Bucket สำหรับจุดลอยตัว Numbers

ขั้นตอน 3) จากนั้นแต่ละกลุ่มจะถูกจัดเรียงโดยใช้การเรียงลำดับแบบแทรก (insertion sort) หลังจากดำเนินการจัดเรียงแล้ว ผลลัพธ์ที่ได้คือ:

อัลกอริธึมการเรียงลำดับ Bucket สำหรับจุดลอยตัว Numbers

ขั้นตอน 4) ในขั้นตอนสุดท้าย กลุ่มข้อมูลต่างๆ จะถูกรวมเข้าด้วยกันเป็นอาร์เรย์เดียว อาร์เรย์นั้นคือผลลัพธ์ที่เรียงลำดับแล้วของข้อมูลป้อนเข้า

แต่ละบัคเก็ตจะถูกต่อเข้ากับอาร์เรย์เอาต์พุต ตัวอย่างเช่น การต่อองค์ประกอบของบัคเก็ตที่สอง:

อัลกอริธึมการเรียงลำดับ Bucket สำหรับจุดลอยตัว Numbers

การรวมองค์ประกอบของบัคเก็ตสุดท้ายแสดงไว้ด้านล่าง:

อัลกอริธึมการเรียงลำดับ Bucket สำหรับจุดลอยตัว Numbers

หลังจากนำมาต่อกันแล้ว อาร์เรย์ที่ได้จะเป็นอาร์เรย์ที่เรียงลำดับตามต้องการ

อัลกอริธึมการเรียงลำดับ Bucket สำหรับจุดลอยตัว Numbers

โปรแกรม Bucket Sort ด้วยภาษา C/C++

Input:

//Bucket Sort Program in C/C++
//For values without integer parts
#include <bits/stdc++.h>
#define BUCKET_SIZE 10
using namespace std;
void bucketSort(float input[], int array_size)
{
  vector <float>bucket[BUCKET_SIZE];
  for (int i = 0; i < array_size; i++) {
    int index = BUCKET_SIZE*input[i];
    bucket[index].push_back(input[i]);
  }
  for (int i = 0; i < BUCKET_SIZE; i++)
    sort(bucket[i].begin(), bucket[i].end());
  int out_index = 0;
  for (int i = 0; i < BUCKET_SIZE; i++)
    for (int j = 0; j < bucket[i].size(); j++)
      input[out_index++] = bucket[i][j];
}
int main()
{
  float input[]={0.78,0.17,0.39,0.26,0.72,0.94,0.21,0.12,0.23,0.69};
  int array_size = sizeof(input)/sizeof(input[0]);

  bucketSort(input, array_size);
  cout <<"Sorted Output: 
";
  for (int i = 0; i< array_size; i++)
    cout<<input[i]<<" ";
  return 0;
}

Output:

Sorted Output:
0.12 0.17 0.21 0.23 0.26 0.39 0.69 0.72 0.78 0.94

โปรแกรม Bucket Sort ใน Python

Input:

# Bucket Sort Program in Python
# For values without integer parts
def bucketSort(input):
    output = []
    bucket_size = 10
    for bucket in range(bucket_size):
        output.append([])
    for element in input:
        index = int(bucket_size * element)
        output[index].append(element)
    for bucket in range(bucket_size):
        output[bucket] = sorted(output[bucket])
    out_index = 0
    for bucket in range(bucket_size):
        for element in range(len(output[bucket])):
            input[out_index] = output[bucket][element]
            out_index += 1
    return input

input = [0.78, 0.17, 0.39, 0.26, 0.72, 0.94, 0.21, 0.12, 0.23, 0.69]
print("Sorted Output:")
print(bucketSort(input))

Output:

Sorted Output:
[0.12, 0.17, 0.21, 0.23, 0.26, 0.39, 0.69, 0.72, 0.78, 0.94]

ถังเรียงลำดับใน Java

Input:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class BucketSort {
    private static final int BUCKET_SIZE = 10;
    public static void bucketSort(float[] input, int arraySize) {
        List<Float>[] bucket = new ArrayList[BUCKET_SIZE];
        for (int i = 0; i < arraySize; i++) {
            int index = (int)(BUCKET_SIZE * input[i]);
            if (bucket[index] == null) {
                bucket[index] = new ArrayList<>();
            }
            bucket[index].add(input[i]);
        }
        for (int i = 0; i < BUCKET_SIZE; i++) {
            if (bucket[i] != null) {
                Collections.sort(bucket[i]);
            }
        }
        int outIndex = 0;
        for (int i = 0; i < BUCKET_SIZE; i++) {
            if (bucket[i] != null) {
                for (float value: bucket[i]) {
                    input[outIndex++] = value;
                }
            }
        }
    }
    public static void main(String[] args) {
        float[] input = {0.78f,0.17f,0.39f,0.26f,0.72f,0.94f,0.21f,0.12f,0.23f,0.69f};
        int arraySize = input.length;
        bucketSort(input, arraySize);
        System.out.println("Sorted Output:");
        for (int i = 0; i < arraySize; i++) {
            System.out.print(input[i]+" ");
        }
    }
}

Output:

Sorted Output:
0.12 0.17 0.21 0.23 0.26 0.39 0.69 0.72 0.78 0.94

วิธีที่ 2: อัลกอริธึมการเรียงลำดับ Bucket สำหรับองค์ประกอบจำนวนเต็ม

อัลกอริทึม Bucket Sort สำหรับข้อมูลนำเข้าที่มีตัวเลขอยู่นอกช่วง [0.0, 1.0] จะแตกต่างจากแบบก่อนหน้าเล็กน้อย ขั้นตอนวิธีขั้นตอนที่จำเป็นสำหรับกรณีนี้มีดังต่อไปนี้:

ขั้นตอน 1) จงหาค่าสูงสุดและค่าต่ำสุดขององค์ประกอบในอาร์เรย์

ขั้นตอน 2) เลือกจำนวนถังเก็บข้อมูล n และกำหนดให้แต่ละถังว่างเปล่าในตอนเริ่มต้น

ขั้นตอน 3) คำนวณช่วงหรือช่วงของแต่ละที่เก็บข้อมูลโดยใช้สูตร:
        span = (maximum - minimum) / n

ขั้นตอน 4) สำหรับแต่ละองค์ประกอบอาร์เรย์:

  • 1. คำนวณดัชนีบัคเก็ต:
            bucket_index = (element - minimum) / span
  • 2. แทรกองค์ประกอบลงใน bucket[bucket_index]

ขั้นตอน 5) จัดเรียงแต่ละที่เก็บข้อมูลโดยใช้การเรียงลำดับการแทรก

ขั้นตอน 6) เชื่อมต่อที่เก็บข้อมูลทั้งหมดไว้ในอาร์เรย์เดียว

เรามาลองดูตัวอย่างการทำงานของอัลกอริทึม Bucket Sort กัน ในตัวอย่างนี้ เราจะเรียงลำดับอาร์เรย์ต่อไปนี้:

อัลกอริธึมการเรียงลำดับ Bucket สำหรับองค์ประกอบจำนวนเต็ม

ขั้นตอน 1) ขั้นตอนแรก เราจะหาค่าสูงสุดและค่าต่ำสุดของอาร์เรย์ที่กำหนด ในตัวอย่างนี้ ค่าสูงสุดคือ 24 และค่าต่ำสุดคือ 1

ขั้นตอน 2) ขั้นตอนต่อไป เราจะเลือกจำนวนถังเปล่า n ในตัวอย่างนี้ เราใช้ถัง 5 ใบ และกำหนดให้เป็นถังเปล่า

ขั้นตอน 3) ช่วงความกว้างของแต่ละถังคำนวณโดยใช้สูตร:
        span = (maximum - minimum) / n = (24 - 1) / 5 = 4

ดังนั้น ถังแรกจึงเก็บตัวเลขในช่วง [0, 5) ถังที่สองเก็บตัวเลขในช่วง [5, 10) และอื่นๆ ต่อไป

อัลกอริธึมการเรียงลำดับ Bucket สำหรับองค์ประกอบจำนวนเต็ม

ขั้นตอน 4) สำหรับแต่ละองค์ประกอบในอาร์เรย์ ให้คำนวณดัชนีของบัคเก็ตและวางองค์ประกอบนั้นลงในบัคเก็ตดังกล่าว ดัชนีของบัคเก็ตคำนวณโดยใช้สูตร:
        bucket_index = (element - minimum) / span

การคำนวณดัชนีถัง:

a) 11
bucket_index = (element – ​​minimum) / span
        = (11 – 1) / 4
        = 2

ดังนั้น องค์ประกอบที่ 11 จึงถูกเก็บไว้ในถัง[2]

อัลกอริธึมการเรียงลำดับ Bucket สำหรับองค์ประกอบจำนวนเต็ม

b) 9
bucket_index = (element – ​​minimum) / span
        = (9 – 1) / 4
        = 2

หมายเหตุ เนื่องจาก 9 เป็นองค์ประกอบขอบเขตสำหรับถัง[1] จึงถูกเพิ่มเข้าไปในถัง[1] แทนที่จะวางไว้ในถังเดียวกันกับองค์ประกอบก่อนหน้า

อัลกอริธึมการเรียงลำดับ Bucket สำหรับองค์ประกอบจำนวนเต็ม

หลังจากดำเนินการกับแต่ละองค์ประกอบแล้ว กลุ่มข้อมูลจะมีลักษณะดังนี้:

อัลกอริธึมการเรียงลำดับ Bucket สำหรับองค์ประกอบจำนวนเต็ม

ขั้นตอน 5) ตอนนี้ แต่ละกลุ่มข้อมูลจะถูกจัดเรียงโดยใช้การเรียงลำดับแบบแทรก (insertion sort) กลุ่มข้อมูลหลังจากจัดเรียงแล้วมีดังนี้:

อัลกอริธึมการเรียงลำดับ Bucket สำหรับองค์ประกอบจำนวนเต็ม

ขั้นตอน 6) ในขั้นตอนสุดท้าย บัคเก็ตต่างๆ จะถูกรวมเข้าด้วยกันเป็นอาร์เรย์เดียว แถว คือผลลัพธ์ที่เรียงลำดับแล้วของข้อมูลป้อนเข้า

อัลกอริธึมการเรียงลำดับ Bucket สำหรับองค์ประกอบจำนวนเต็ม

โปรแกรม Bucket Sort ด้วยภาษา C/C++

Input:

#include<bits/stdc++.h>
using namespace std;
void bucketSort(vector < double > & input, int No_Of_Buckets)
{
  double max_value = * max_element(input.begin(), input.end());
  double min_value = * min_element(input.begin(), input.end());
  double span = (max_value - min_value) / No_Of_Buckets;
  vector<vector <double>> output;
  for (int i = 0; i < No_Of_Buckets; i++)
    output.push_back(vector <double>());
  for (int i = 0; i < input.size(); i++)
  {
    double difference = (input[i] - min_value) / span
     - int((input[i] - min_value) / span);
    if (difference == 0 && input[i] != min_value)
      output[int((input[i] - min_value) / span) - 1].push_back(input[i]);
    else
      output[int((input[i] - min_value) / span)].push_back(input[i]);
  }
  for (int i = 0; i < output.size(); i++)
  {
    if (!output[i].empty())
      sort(output[i].begin(), output[i].end());
  }
  int index = 0;
  for (vector <double> & bucket: output)
  {
    if (!bucket.empty())
    {
      for (double i: bucket)
      {
        input[index] = i;
        index++;
      }
    }
  }
}
int main()
{
  vector <double> input ={11,9,21,8,17,19,13,1,24,12};
  int No_Of_Buckets = 5;
  bucketSort(input, No_Of_Buckets);
  cout<<"Sorted Output:";
  for (int i=0; i < input.size(); i++)
    cout <<input[i]<<" ";
  return 0;
}

Output:

Sorted Output:1 8 9 11 12 13 17 19 21 24

โปรแกรม Bucket Sort ใน Python

Input:

def bucketSort(input, No_Of_Buckets):
    max_element = max(input)
    min_element = min(input)
    span = (max_element - min_element) / No_Of_Buckets
    output = []
    for bucket in range(No_Of_Buckets):
        output.append([])
    for element in range(len(input)):
        diff = (input[element] - min_element) / span - int(
            (input[element] - min_element) / span
        )
        if diff == 0 and input[element] != min_element:
            output[int((input[element] - min_element) / span) - 1].append(
                input[element]
            )
        else:
            output[int((input[element] - min_element) / span)].append(input[element])
    for bucket in range(len(output)):
        if len(output[bucket]) != 0:
            output[bucket].sort()
    index = 0
    for bucket in output:
        if bucket:
            for element in bucket:
                input[index] = element
                index = index + 1
input = [11, 9, 21, 8, 17, 19, 13, 1, 24, 12]
No_Of_Buckets = 5
bucketSort(input, No_Of_Buckets)
print("Sorted Output:
", input)

Output:

Sorted Output:
[1, 8, 9, 11, 12, 13, 17, 19, 21, 24]

ถังเรียงลำดับใน Java

Input:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class BucketSort {
    public static void bucketSort(List < Double > input, int No_Of_Buckets) {
        double max_value = Collections.max(input);
        double min_value = Collections.min(input);
        double span =(max_value - min_value) / No_Of_Buckets;
        List<List<Double>> output = new ArrayList<>();
        for (int i = 0; i < No_Of_Buckets; i++) {
            output.add(new ArrayList<>());
        }
        for (Double value: input) {
            double difference = (value - min_value) / span - ((value - min_value) / span);
            if (difference == 0 && value != min_value) {
                output.get((int)((value - min_value) / span) - 1).add(value);
            } else {
                output.get((int)((value - min_value) / span)).add(value);
            }
        }
        for (List <Double> bucket: output) {
            if (!bucket.isEmpty()) {
                Collections.sort(bucket);
            }
        }
        int index = 0;
        for (List <Double> bucket: output) {
            if (!bucket.isEmpty()) {
                for (Double value: bucket) {
                    input.set(index,value);
                    index++;
                }
            }
        }
    }
    public static void main(String[] args) {
        List <Double> input = new ArrayList<>();
        input.add(11.0);
        input.add(9.0);
        input.add(21.0);
        input.add(8.0);
        input.add(17.0);
        input.add(19.0);
        input.add(13.0);
        input.add(1.0);
        input.add(24.0);
        input.add(12.0);
        int No_Of_Buckets = 5;
        bucketSort(input, No_Of_Buckets);
        System.out.println("Sorted Output:");
        for (Double value: input) {
            System.out.print(value + " ");
        }
    }
}

Output:

Sorted Output:
1.0 8.0 9.0 11.0 12.0 13.0 17.0 19.0 21.0 24.0

ข้อดีและข้อเสียของการจัดเรียงแบบ Bucket Sort

ข้อดี จุดด้อย
ประมวลผลข้อมูลที่มีการกระจายตัวอย่างสม่ำเสมอได้เร็วกว่า ใช้พื้นที่มากกว่าเมื่อเทียบกับอัลกอริธึมการเรียงลำดับแบบ in-place
สามารถใช้เป็นวิธีการจัดเรียงภายนอกสำหรับชุดข้อมูลขนาดใหญ่ได้ ทำงานได้ไม่ดีเมื่อข้อมูลไม่กระจายสม่ำเสมอ
สามารถประมวลผลถังแต่ละใบได้อย่างอิสระและพร้อมกัน จำเป็นต้องมีความรู้เกี่ยวกับช่วงและลักษณะการกระจายของข้อมูลล่วงหน้า

การวิเคราะห์ความซับซ้อนของการเรียงลำดับแบบ Bucket

ความซับซ้อนของเวลาในการจัดเรียงถัง

  • ความซับซ้อนของเคสที่ดีที่สุด: หากองค์ประกอบทั้งหมดในอาร์เรย์กระจายอย่างสม่ำเสมอและเรียงลำดับไว้ล่วงหน้าภายในแต่ละบัคเก็ตแล้ว จะใช้เวลา O(n) ในการกระจายองค์ประกอบลงในบัคเก็ตที่เกี่ยวข้อง จากนั้นจึงเรียงลำดับแต่ละบัคเก็ตโดยใช้ การเรียงลำดับการแทรก ต้นทุนคือ O(k) ดังนั้นความซับซ้อนโดยรวมคือ O(n+k)
  • ความซับซ้อนของเคสโดยเฉลี่ย: ในกรณีทั่วไป เราถือว่าข้อมูลนำเข้ามีการกระจายอย่างสม่ำเสมอ ดังนั้นอัลกอริทึม Bucket Sort จึงมีประสิทธิภาพเชิงเวลาแบบเชิงเส้นที่ O(n+k) โดยใช้เวลา O(n) ในการกระจายองค์ประกอบ และใช้เวลา O(k) ในการเรียงลำดับโดยใช้การเรียงลำดับแบบแทรก
  • ความซับซ้อนของกรณีที่เลวร้ายที่สุด: ในกรณีที่แย่ที่สุด องค์ประกอบต่างๆ จะไม่กระจายตัวอย่างสม่ำเสมอและกระจุกตัวอยู่ในถังหนึ่งหรือสองถัง ในกรณีนั้น การเรียงลำดับแบบ Bucket Sort จะทำงานในลักษณะที่คล้ายกับ... อัลกอริทึมเรียงลำดับแบบบับเบิลดังนั้น ในกรณีที่เลวร้ายที่สุด ความซับซ้อนเชิงเวลาของ Bucket Sort คือ O(n²)

ความซับซ้อนของพื้นที่ในการเรียงลำดับแบบ Bucket

ความซับซ้อนเชิงพื้นที่ของ Bucket Sort คือ O(n*k) โดยที่ n คือจำนวนองค์ประกอบ และ k คือจำนวนถังที่จำเป็นในการเก็บองค์ประกอบเหล่านั้นระหว่างการเรียงลำดับ

คำถามที่พบบ่อย

ใช้ Bucket Sort เมื่อค่าอินพุตมีการกระจายอย่างสม่ำเสมอในช่วงที่ทราบ โดยเฉพาะอย่างยิ่งตัวเลขทศนิยมในช่วง [0.0, 1.0] วิธีนี้ให้เวลาการประมวลผลเชิงเส้นกับข้อมูลดังกล่าว แต่ทำงานได้ไม่ดีกับข้อมูลที่มีการกระจายแบบกระจุกตัวหรือไม่ทราบช่วง

Bucket Sort จะมีเสถียรภาพก็ต่อเมื่ออัลกอริธึมการเรียงลำดับภายในที่ใช้ในแต่ละบัคเก็ตมีเสถียรภาพ Insertion Sort จะรักษาระดับลำดับสัมพัทธ์ขององค์ประกอบที่เท่ากัน ดังนั้นการใช้งาน Bucket Sort มาตรฐานโดยใช้ Insertion Sort จึงถือว่ามีเสถียรภาพ

Bucket Sort จัดกลุ่มองค์ประกอบตามช่วงค่าและเรียงลำดับแต่ละกลุ่มด้วยอัลกอริทึมอื่น ในขณะที่ Radix Sort จัดกลุ่มตัวเลขทีละหลักและใช้การเรียงลำดับแบบนับจำนวนภายใน Bucket Sort ให้ความสำคัญกับตัวเลขทศนิยมที่มีการกระจายอย่างสม่ำเสมอ ในขณะที่ Radix Sort ให้ความสำคัญกับตัวเลขจำนวนเต็มหรือสตริงที่มีความกว้างคงที่

ความซับซ้อนของเวลาในกรณีที่เลวร้ายที่สุดของ Bucket Sort คือ O(n²) ซึ่งเกิดขึ้นเมื่อองค์ประกอบอินพุตทั้งหมดตกอยู่ในถังเดียว ทำให้การเรียงลำดับภายใน (โดยทั่วไปคือการเรียงลำดับแบบแทรก) ทำงานในลักษณะกำลังสอง การกระจายแบบสม่ำเสมอช่วยหลีกเลี่ยงสถานการณ์นี้ได้

ใช่แล้ว ในการจัดการกับค่าลบ ให้หาทั้งค่าต่ำสุดและค่าสูงสุด จากนั้นคำนวณดัชนีของกลุ่มโดยใช้ (ค่าขององค์ประกอบ – ค่าต่ำสุด) / ช่วงค่า วิธีนี้จะเปลี่ยนค่าลบให้ไปอยู่ในพื้นที่ดัชนีที่ไม่เป็นลบ และทำให้ตรรกะการเรียงลำดับแบบ Bucket Sort มาตรฐานดำเนินต่อไปได้โดยไม่เปลี่ยนแปลง

แพลตฟอร์มที่ขับเคลื่อนด้วย AI เช่น VisuAlgo, Algorithm Visualizer และคำแนะนำทีละขั้นตอนที่สร้างโดย ChatGPT tracสื่อเหล่านี้ช่วยให้ผู้เรียนเห็นภาพการจัดเรียงแบบ Bucket Sort ได้ชัดเจนขึ้น โดยจะแสดงภาพเคลื่อนไหวของขั้นตอนการกระจาย การจัดเรียง และการรวบรวม ทำให้เข้าใจคณิตศาสตร์ของดัชนีถังและตรรกะการแบ่งส่วนได้ง่ายขึ้น

ระบบแนะนำที่ขับเคลื่อนด้วย AI จะวิเคราะห์ขนาดของชุดข้อมูล การกระจายค่า และข้อจำกัดของหน่วยความจำ เพื่อแนะนำอัลกอริทึมที่เหมาะสม สำหรับข้อมูลทศนิยมที่มีการกระจายอย่างสม่ำเสมอ ระบบเหล่านี้จะแนะนำ Bucket Sort แต่สำหรับข้อมูลจำนวนเต็มที่มีช่วงค่าผสมกัน ระบบอาจแนะนำ Quick Sort หรือ Radix Sort แทน

สรุปโพสต์นี้ด้วย: