Sunday, May 16, 2021

Những thuật toán sắp xếp mảng trong lập trình

Xin chào mừng bạn đến với blog thủ thuật lập trình, hôm nay mình sẽ giới thiệu cho các bạn một trong những thuật toán lập trình thường hay áp dụng nhiều nhất trong thực tiễn cũng như trong học tập.

Thuật toán sắp xếp là gì?

Sắp xếp là quá trình bố trí lại các phần tử trong một tập hợp theo một trình tự nào đó nhằm mục đích giúp quản lý và tìm kiếm các phần tử dễ dàng và nhanh chóng hơn.

Những thuật toán sắp xếp mảng trong lập trình

Tại sao phải sử dụng thuật toán sắp xếp

  • Để có thể sử dụng thuật toán tìm nhị phân
  • Để thực hiện thao tác nào đó được nhanh hơn

Những phương pháp sắp xếp bằng thuật toán.

  • Phương pháp Đổi chỗ trực tiếp (Interchange sort)
  • Phương pháp Nổi bọt (Bubble sort)
  • Phương pháp Chèn trực tiếp (Insertion sort)
  • Phương pháp Chọn trực tiếp (Selection sort)

I. Phương pháp Đổi chỗ trực tiếp (Interchange sort)

Sử dụng

Xét một mảng các số a[0], a[1], … a[n-1]

Nếu có i<j và a[i] > a[j], thì ta gọi đó là một nghịch thế

Mảng chưa sắp xếp sẽ có nghịch thế

Mảng đã có thứ tự sẽ không chứa nghịch thế

a[0] <= a[1] <=… <=[n -1]

Ý tưởng

Xuất phát từ đầu dãy, tìm tất cả nghịch thế chứa phần tử này, triệt tiêu chúng bằng cách đổi chỗ phần tử này với phần tử tương ứng trong cặp nghịch thế

Lặp lại xử lý trên với các phần tử tiếp theo trong dãy

Nhận xét.

Để sắp xếp một dãy số, ta có thể xét các nghịch thế có trong dãy và làm triệt tiêu dần chúng đi

Phương thức sử dụng.

void Swap(int &a, int &b){

    int temp = a;

    a = b;

    b = temp;

}

void InterchangeSort(int a[], int n){

    for (int i = 0; i < n - 1; i++)

        for (int j = i + 1; j < n; j++)

        if(a[i] > a[j])  //nếu có nghịch thế thì đổi chỗ

        Swap(a[i], a[j]);

}

II. Phương pháp Nổi bọt (Bubble sort)

Ý tưởng:

Xuất phát từ cuối dãy, đổi chỗ các cặp phần tử kế cận để đưa phần tử nhỏ hơn trong cặp phần tử đó về vị trí đầu dãy hiện hành, sau đó sẽ không xét đến nó ở bước tiếp theo

Ở lần xử lý thứ i có vị trí đầu dãy là i

Lặp lại xử lý trên cho đến khi không còn cặp phần tử nào để xét

Hàm BubbleSort

void BubbleSort(int a[], int n){

for (int i = 0; i < n - 1; i++)

for (int j = n - 1; j > i; j--)

   if(a[j] < a[j-1])

       Swap(a[j], a[j-1]);

}

III. Phương pháp Chèn trực tiếp (Insertion sort)

Nhận xét:

Mọi dãy a[0] , a[1] ,..., a[n-1] luôn có i-1 phần tử đầu tiên a[0] , a[1] ,... , a[i-2] đã có thứ tự (i ≥ 2)

Ý tưởng chính:

Tìm cách chèn phần tử a[i] vào vị trí thích hợp của đoạn đã được sắp để có dãy mới a[0] , a[1] ,... , a[i-1] trở nên có thứ tự

Vị trí này chính là pos thỏa : a[pos-1] <= a[i ]< a[pos] (1 <= pos <= i)

void InsertionSort(int a[], int n){

int pos, x;

for(int i = 1; i < n; i++){ //đoạn a[0] đã sắp

x = a[i]; 

pos = i;

while(pos > 0 && x < a[pos-1]){

a[pos] = a[pos-1]; // dời chỗ

pos--;

}

a[pos] = x;

}

}

IV. Phương pháp Chọn trực tiếp (Selection sort)

Nhận xét:

Mảng có thứ tự thì a[i] = min(a[i], a[i+1], …, a[n-1])

Ý tưởng: mô phỏng một trong những cách sắp xếp tự nhiên nhất trong thực tế:

Chọn phần tử nhỏ nhất trong n phần tử ban đầu, đưa phần tử này về vị trí đúng là đầu dãy hiện hành

Xem dãy hiện hành chỉ còn n-1 phần tử của dãy ban đầu, bắt đầu từ vị trí thứ 2; lặp lại quá trình trên cho dãy hiện hành... đến khi dãy hiện hành chỉ còn 1 phần tử

void SelectionSort(int a[], int n)

{

int min; // chỉ số phần tử nhỏ nhất trong dãy hiện hành

for (int  i = 0; i < n - 1; i++){

min = i; 

for(int j = i + 1; j < n; j++)

       if (a[j] < a[min])

       min = j; // ghi nhận vị trí phần tử nhỏ nhất

if (min != i)

       Swap(a[min], a[i]);

}

}

No comments:

Post a Comment