การเรียงลำดับการแทรก: อัลกอริทึมด้วย C, C++, Java, Python ตัวอย่าง

การเรียงลำดับการแทรกคืออะไร?

การเรียงลำดับแบบแทรกเป็นหนึ่งในอัลกอริทึมการเรียงลำดับแบบเปรียบเทียบที่ใช้ในการเรียงลำดับองค์ประกอบด้วยการทำซ้ำกับองค์ประกอบหนึ่งครั้งละหนึ่งองค์ประกอบและวางองค์ประกอบไว้ในตำแหน่งที่ถูกต้อง

แต่ละองค์ประกอบจะถูกแทรกตามลำดับในรายการที่เรียงลำดับแล้ว ขนาดของรายการที่เรียงลำดับแล้วในตอนแรกคือขนาดเดียว อัลกอริธึมการเรียงลำดับการแทรกช่วยให้แน่ใจว่าองค์ประกอบ k แรกจะถูกจัดเรียงหลังจากการวนซ้ำที่ k

ลักษณะของอัลกอริทึมการเรียงลำดับการแทรก

อัลกอริทึมสำหรับการเรียงลำดับแบบแทรกมีคุณลักษณะสำคัญดังต่อไปนี้:

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

แทรกอย่างไร Operaทำงานเหรอ?

ในอัลกอริทึมการเรียงลำดับแบบแทรก การดำเนินการแทรกใช้เพื่อเรียงลำดับองค์ประกอบที่ไม่ได้เรียงลำดับ การดำเนินการนี้ช่วยในการแทรกองค์ประกอบใหม่ลงในรายการที่เรียงลำดับแล้ว

รหัสเทียมของการดำเนินการแทรก:

พิจารณารายการ A ขององค์ประกอบ N

A[N-1] is the element to be inserted in the sorted sublist A[0..N-2].
For i = N-1 to 1:
if A[i] < A[i-1], then swap A[i] and A[i-1]
else Stop   

สิ่งที่ใส่เข้าไป Operaทำงาน

ในตัวอย่างข้างต้น องค์ประกอบใหม่ 6 จะถูกแทรกลงในรายการที่เรียงลำดับแล้ว

ขั้นตอน 1) เมื่อเปรียบเทียบกับองค์ประกอบที่อยู่ติดกันทางซ้ายของ A[5], 9 > 6 เราจะสลับตำแหน่งที่ 9 และ 6 ตอนนี้องค์ประกอบที่ 6 ถูกย้ายไปที่ A[4]

ขั้นตอน 2) ตอนนี้ เราเปรียบเทียบ A[4] และ A[3] และเราพบว่า A[3] > A[4] เราสลับตำแหน่ง 6 และ 8 อีกครั้ง

ขั้นตอน 3) ตอนนี้เปรียบเทียบ A[3] และ A[2] โดยที่ A[2] > A[3] สลับตำแหน่งของ 7 และ 6

ขั้นตอน 4) เราเปรียบเทียบ A[1] และ A[2] และเมื่อ A[1] < A[2] กล่าวคือ องค์ประกอบที่อยู่ติดกันด้านซ้ายจะไม่ยิ่งใหญ่อีกต่อไป ตอนนี้เราสรุปได้ว่าใส่ 6 อย่างถูกต้อง และเราหยุดอัลกอริทึมที่นี่

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

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

งานเรียงลำดับการแทรก

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

C++ โปรแกรมสำหรับการเรียงลำดับการแทรก

#include <iostream>
using namespace std;

int main(){
    //unsorted list
    int unsorted[] = {9,8,7,6,5,4,3,3,2,1};
    
    //size of list
    int size_unsorted = sizeof(unsorted) / sizeof(unsorted[0]); 

    //printing unsorted list
    cout << "\nUnsorted: ";
    for(int i = 0 ; i < size_unsorted ; i++){
        cout << unsorted[i] << " ";
    } 

    int current_element,temp;

    for(int i = 1; i < size_unsorted; i++){        
        current_element = unsorted[i];
        for(int j = i-1; j >= 0 && unsorted[j] > current_element; j--){
            //swapping if current element is lesser
            temp = unsorted[j+1];
            unsorted[j+1] = unsorted[j];
            unsorted[j] = temp;
        }
    }

    //printing sorted list
    cout << "\nSorted: ";
    for(int i = 0 ; i < size_unsorted ; i++){
        cout << unsorted[i] << " ";
    } 

    return 0;
}

Output:

Unsorted: 9 8 7 6 5 4 3 3 2 1 
Sorted: 1 2 3 3 4 5 6 7 8 9

รหัส C สำหรับการเรียงลำดับการแทรก

#include <stdio.h>
int main() {
    //unsorted list
    int unsorted[] = {9,8,7,6,5,4,3,3,2,1};

    //size of list
    int size_unsorted = sizeof(unsorted) / sizeof(unsorted[0]);

    //printing unsorted list
    printf("\nUnsorted: ");
    for(int i = 0 ; i < size_unsorted ; i++){
        printf("%d ", unsorted[i]);
    }

    int current_element, temp;

    for(int i = 1; i < size_unsorted; i++){
        current_element = unsorted[i];
        for(int j = i-1; j >= 0 && unsorted[j] > current_element; j--){
            //swapping if current element is lesser
            temp = unsorted[j+1];
            unsorted[j+1] = unsorted[j];
            unsorted[j] = temp;
        }
    }

    //printing sorted list
    printf("\nSorted: ");
    for(int i = 0 ; i < size_unsorted ; i++){
        printf("%d ", unsorted[i]);
    }

    return 0;
}

Output:

Output:
Unsorted: 9 8 7 6 5 4 3 3 2 1 
Sorted: 1 2 3 3 4 5 6 7 8 9

Python โปรแกรมสำหรับการเรียงลำดับการแทรก

#unsorted list
unsorted = [9,8,7,6,5,4,3,3,2,1]

#size of list
size_unsorted = len(unsorted)

#printing unsorted list
print("\nUnsorted: ", end="")
for i in range(size_unsorted):
    print(unsorted[i], end=" ")

for i in range(1, size_unsorted):
    current_element = unsorted[i]
    j = i - 1
    while j >= 0 and unsorted[j] > current_element:
        #swapping if current element is lesser
        unsorted[j+1], unsorted[j] = unsorted[j], unsorted[j+1]
        j -= 1

#printing sorted list
print("\nSorted: ", end="")
for i in range(size_unsorted):
    print(unsorted[i], end=" ")

Output:

Unsorted: 9 8 7 6 5 4 3 3 2 1 
Sorted: 1 2 3 3 4 5 6 7 8 9

คุณสมบัติของการเรียงลำดับการแทรก

นี่คือคุณสมบัติที่สำคัญของการเรียงลำดับการแทรก:

  • ออนไลน์: การเรียงลำดับการแทรกสามารถเรียงลำดับองค์ประกอบตามที่ได้รับ นั่นคือถ้าเราได้เรียงลำดับรายการองค์ประกอบแล้วและผนวกองค์ประกอบเพิ่มเติมเข้ากับรายการ เราก็ไม่จำเป็นต้องรันขั้นตอนการเรียงลำดับทั้งหมดอีกครั้ง แต่เราจำเป็นต้องวนซ้ำเฉพาะองค์ประกอบที่เพิ่มเข้ามาใหม่เท่านั้น
  • ในสถานที่: ความซับซ้อนของพื้นที่ของอัลกอริทึมการเรียงลำดับแบบแทรกนั้นคงที่และไม่ต้องใช้พื้นที่เพิ่มเติม อัลกอริทึมนี้จะเรียงลำดับองค์ประกอบในตำแหน่งที่ต้องการ
  • เสถียร: ในการเรียงลำดับการแทรก เราจะไม่สลับองค์ประกอบหากค่าเท่ากัน ตัวอย่างเช่น สององค์ประกอบคือ x และ y เท่ากัน และ x ปรากฏก่อน y ในรายการที่ไม่เรียงลำดับ จากนั้นในรายการที่เรียงลำดับ x จะปรากฏก่อน y ทำให้การเรียงลำดับการแทรกมีความเสถียร
  • ปรับตัว: A อัลกอริทึมการเรียงลำดับ เป็นแบบปรับตัวได้หากใช้เวลาน้อยลงหากองค์ประกอบอินพุตหรือชุดย่อยขององค์ประกอบได้รับการเรียงลำดับแล้ว ตามที่เราได้กล่าวไว้ข้างต้น เวลาดำเนินการที่ดีที่สุดของการเรียงลำดับแบบแทรกคือ O(N) และเวลาดำเนินการที่แย่ที่สุดคือ O(N^2) การเรียงลำดับแบบแทรกเป็นหนึ่งในอัลกอริทึมการเรียงลำดับแบบปรับตัวได้

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

ความซับซ้อนของอวกาศ

การเรียงลำดับแบบแทรกไม่จำเป็นต้องใช้พื้นที่พิเศษเพื่อเรียงลำดับองค์ประกอบ ความซับซ้อนของพื้นที่จะคงที่ นั่นคือ O(1)

ความซับซ้อนของเวลา

เนื่องจากการเรียงลำดับแบบแทรกจะวนซ้ำแต่ละองค์ประกอบพร้อมกัน จึงต้องใช้การเรียงลำดับ N-1 ครั้งในการเรียงลำดับ N องค์ประกอบ ในแต่ละรอบ อาจสลับเป็นศูนย์หากองค์ประกอบได้รับการเรียงลำดับแล้ว หรือสลับหากองค์ประกอบได้รับการจัดเรียงในลำดับจากมากไปน้อย

  • สำหรับบัตรผ่าน 1 ค่าสวอปขั้นต่ำที่ต้องการคือศูนย์ และค่าสวอปสูงสุดที่ต้องการคือ 1
  • สำหรับบัตรผ่าน 2 ค่าสวอปขั้นต่ำที่ต้องการคือศูนย์ และค่าสวอปสูงสุดที่ต้องการคือ 2
  • สำหรับ pass N ค่า swap ขั้นต่ำที่ต้องการคือศูนย์ และค่า swap สูงสุดที่ต้องการคือ N
  • การสลับขั้นต่ำคือศูนย์ ดังนั้นความซับซ้อนของเวลาที่ดีที่สุดคือ O(N) สำหรับการวนซ้ำ N ครั้ง
  • การสลับสูงสุดทั้งหมดคือ (1+2+3+4+..+N) คือ N(N+1)/2 ความซับซ้อนของเวลาที่แย่ที่สุดคือ O(N^2)

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

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

สรุป

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