การเรียงลำดับแบบฟอง

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

## การวิเคราะห์
300px|thumb|right|ภาพตัวอย่างแสดงการทำงานของการเรียงลำดับแบบฟองเพื่อเรียงลำดับจากน้อยไปมาก เร่มต้นทำงานจากทางซ้ายและเปรียบเทียบทีละคู่และสลับกันถ้าหากพบว่าตัวทางด้านซ้ายมีค่ามากกว่าตัวทางด้านขวา

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

การปรับปรุงประสิทธิภาพของการเรียงลำดับแบบฟองนั้นวิธีการหนึ่งก็คือการทำให้ค่าน้อยที่อยู่หลัง ๆ นั้นลงมาด้านหน้าได้เร็วขึ้น นั่นคือหลักการของ Cocktail Sort ซึ่งมีขั้นตอนวิธีคล้ายการเรียงลำดับแบบฟองมากเพียงแต่ทำงานทั้งขาไปและขากลับ ขาไปนั้นทำงานเหมือนการเรียงลำดับแบบฟองทุกประการ ส่วนขากลับก็เพียงกลับด้านของการเรียงลำดับแบบฟองนั่นเอง แต่การปรับปรุงดังนี้ก็ไม่ได้ทำให้ประสิทธิภาพในกรณีแย่ที่สุดดีกว่า O(n2) แต่อย่างใด

### ตัวอย่างทีละขั้นตอน
การเรียงลำดับเลข 5 1 4 2 8 ในลิสต์ จากน้อยไปมาก ในแต่ละขั้นตอนตัวหนาหมายถึงตัวที่กำลังถูกเปรียบเทียบ

**รอบที่ 1**

( **5** **1** 4 2 8 ) \to ( **1** **5** 4 2 8 ), เปรียบเทียบตัวปัจจุบันกับตัวถัดไป สลับเนื่องจาก 5 > 1

( 1 **5** **4** 2 8 ) \to ( 1 **4** **5** 2 8 ), สลับเนื่องจาก 5 > 4

( 1 4 **5** **2** 8 ) \to ( 1 4 **2** **5** 8 ), สลับเนื่องจาก 5 > 2

( 1 4 2 **5** **8** ) \to ( 1 4 2 **5** **8** ), ไม่สลับเพราะ 5 ไม่มากกว่า 8

**รอบที่ 2**

( **1** **4** 2 5 8 ) \to ( **1** **4** 2 5 8 ), ไม่สลับเพราะ 1 ไม่มากกว่า 4

( 1 **4** **2** 5 8 ) \to ( 1 **2** **4** 5 8 ), สลับเนื่องจาก 4 > 2

( 1 2 **4** **5** 8 ) \to ( 1 2 **4** **5** 8 ), ไม่สลับเพราะ 4 ไม่มากกว่า 5

( 1 2 4 **5** **8** ) \to ( 1 2 4 **5** **8** ), ไม่สลับเพราะ 5 ไม่มากกว่า 8

ถึงแม้ว่าข้อมูลในลิสต์จะเรียงหมดแล้ว แต่ว่าก็ต้องตรวจสอบอีกครั้งหนึ่ง

**รอบที่ 3**

( **1** **2** 4 5 8 ) \to ( **1** **2** 4 5 8 ), ไม่สลับเพราะ 1 ไม่มากกว่า 2

( 1 **2** **4** 5 8 ) \to ( 1 **2** **4** 5 8 ), ไม่สลับเพราะ 2 ไม่มากกว่า 4

( 1 2 **4** **5** 8 ) \to ( 1 2 **4** **5** 8 ), ไม่สลับเพราะ 4 ไม่มากกว่า 5

( 1 2 4 **5** **8** ) \to ( 1 2 4 **5** **8** ), ไม่สลับเพราะ 5 ไม่มากกว่า 8

ในรอบนี้ไม่มีการสลับ แสดงว่าลำดับเลขเรียงจากน้อยไปมากแล้ว

## การนำมาใช้งาน
### ตัวอย่าง[[รหัสเทียม]]

```pascal
begin bubbleSort ( A คือ แถวลำดับที่จะถูกเรียง )
   do
      ทำเครื่องหมายว่ายังไม่มีการสลับ
      for i = 1 to ขนาดของ(A)-1
         if A[i-1] > A[i] then
	    สลับ A[i-1] กับ A[i]
	    ทำเครื่องหมายว่ามีการสลับแล้ว
	 end if
      end for
   until ไม่มีการสลับแล้ว
end
```


### การปรับปรุงประสิทธิภาพ
ในการเรียงลำดับจากน้อยไปมากเสร็จหนึ่งรอบจะทำให้ค่าที่มากที่สุดลำดับที่ i ไปอยู่ในตำแหน่งที่ n-1 ดังนั้นจึงสามารถมองข้ามตำแหน่งที่ n-1 ในการทำงานรอบต่อไปได้

```pascal
begin bubbleSort ( A คือ แถวลำดับที่จะถูกเรียง )
   n = ขนาดของ(A)
   do
      ทำเครื่องหมายว่ายังไม่มีการสลับ
      for i = 1 to n-1
         if A[i-1] > A[i] then
	    สลับ A[i-1] กับ A[i]
	    ทำเครื่องหมายว่ามีการสลับแล้ว
	 end if
      end for
      n = n - 1
   until ไม่มีการสลับแล้ว
end
```


## ในการทำงานจริง

จะกล่าวได้ว่าการเรียงลำดับแบบฟองนั้นเป็นหนึ่งในขั้นตอนวิธีการเรียงลำดับที่ง่ายที่สุดเท่าที่เรารู้จัก ด้วย O(n2) ทำให้ประสิทธิภาพของมันลดลงอย่างมากแม้เราเพิ่มจำนวนสมาชิกที่จะเรียงเพียงเล็กน้อย แม้จะเปรียบเทียบขั้นตอนวิธีการเรียงลำดับที่มี O(n2) ด้วยกันนั้นการเรียงลำดับแบบแทรกก็นับว่ามีประสิทธิภาพดีกว่าในกรณีทั่ว ๆ ไป แต่ด้วยความง่ายของขั้นตอนวิธีและความง่ายในการเขียนทำให้เราพบเห็นการเรียงลำดับแบบฟองได้อยู่ทั่วไป และมักจะได้เป็นขั้นตอนวิธีการเรียงลำดับแรก ๆ ที่ผู้เริ่มเขียนโปรแกรมได้ศึกษานั่นเอง

## การเรียงรูปแบบอื่นที่แตกต่างออกไป

* Cocktail Sort

## การเรียกชื่อที่ผิด

## อ้างอิง

หมวดหมู่:ขั้นตอนวิธีการเรียงลำดับ
หมวดหมู่:การเรียงแบบเปรียบเทียบ
หมวดหมู่:การเรียงแบบเสถียร