Chuyển đến nội dung chính

Data-Driven Programming

Data-Driven Programming Data driven progamming is a programming model where the data itself controls the flow of the program and not the program logic. It is a model where you control the flow by offering different data sets to the program where the program logic is some generic form of flow or of state-changes. set1: DOWN - STOP - START - STOP - UP - STOP set2: UP - DOWN - UP - DOWN For example if you have program that has four states: UP - DOWN - STOP - START You can control this program by offering input (data) that represents the states: The program code stays the same but data set (which is not of a dynamic input type but statically given to the computer) controls the flow. Although there are more than a few ideas as to what data driven programming is, allow me to give an example using a data structure and a function. Non data driven example: data_lloyd = {'name': 'Lloyd', 'lives': 'Alcoy } data_jason = {'name': 'Jason', 'lives':

CÁC THUẬT TOÁN SẮP XẾP CƠ BẢN

CÁC THUẬT TOÁN SẮP XẾP CƠ BẢN

img

Khái niệm

Bài toán sắp xếp là bài toán giải quyết việc tổ chức dữ liệu theo một trật tự nhất định, thường là tăng dần hoặc giảm dần.

phép toán cơ bản cho bài toán sắp xếp:

  1. Phép toán đổi chỗ: Là phép toán đảo giá trị 2 biến

     void swap(datatype &a, datatype &b) {
         datatype temp = a; 
         a = b;
         b = temp;
     }
    
  2. Phép toán so sánh: Trả về true nếu a > b và trả về false cho trường hợp ngược lại.

         bool compare(datatype a, datatype b) {
             if (a > b) {
                 return true;
             } else {
                 return false;
             }
         }
    
  3. Bảng ghi về độ phức tạp của các thuật toán sắp xếp

    Độ phức tạp càng lớn đồng nghĩa với việc thuật toán chạy càng chậm và càng lâu

img

Ba thuật toán sắp xếp cơ bản

1. Sắp xếp chèn (Insertion Sort)

Ý tưởng: Insertion Sort lấy ý tưởng từ việc chơi bài, dựa theo cách người chơi "chèn" thêm một quân bài mới vào bộ bài đã được sắp xếp trên tay.

Thuật toán:

  • Tại bước k = 1, 2, ..., n đưa phần tử thứ k trong mảng đã cho vào đúng vị trí trong dãy gồm k phần tử đầu tiên.
  • Kết quả là sau bước thứ k, sẽ có k phần tử đầu tiên được sắp xếp theo thứ tự.
    void insertionSort(int a[], int array_size) {
        int i, j, last;
        for (i=1; i < array_size; i++) {
            last = a[i];
            j = i;
        while ((j > 0) && (a[j-1] > last)) {
            a[j] = a[j-1];
            j = j - 1; }
            a[j] = last;
        } 
    }

2. Sắp xếp lựa chọn (Selection Sort)

Ý tưởng của Selection sort là tìm từng phần tử cho mỗi vị trí của mảng hoán vị A' cần tìm.

Thuật toán:

  • Tìm phần tử nhỏ nhất đưa vào vị trí 1
  • Tìm phần tử nhỏ tiếp theo đưa vào vị trí 2
  • Tìm phần tử nhỏ tiếp theo đưa vào vị trí 3
  • ...
    void selectionSort(int a[], int n){
        int i, j, min, temp;
        for (i = 0; i < n-1; i++) {
            min = i;
            for (j = i+1; j < n; j++){
                if (a[j] < a[min]) min = j;
            }
            swap(a[i], a[min]);
        }
    }

3. Sắp xếp nổi bọt (Bubble Sort)

Ý tưởng: Bubble Sort, như cái tên của nó, là thuật toán đẩy phần tử lớn nhất xuống cuối dãy, đồng thời những phần tử có giá trị nhỏ hơn sẽ dịch chuyển dần về đầu dãy. Tựa như sự nổi bọt vậy, những phần tử nhẹ hơn sẽ nổi lên trên và ngược lại, những phần tử lớn hơn sẽ chìm xuống dưới.

Thuật toán: Duyệt mảng từ phần tử đầu tiên. Ta sẽ so sánh mỗi phần tử với phần tử liền trước nó, nếu chúng đứng sai vị trí, ta sẽ đổi chỗ chúng cho nhau. Quá trình này sẽ được dừng nếu gặp lần duyệt từ đầu dãy đến cuối dãy mà không phải thực hiện đổi chỗ bất kì 2 phần từ nào (tức là tất cả các phần tử đã được sắp xếp đúng vị trí).

    void bubbleSort(int a[], int n){
        int i, j;
        for (i = (n-1); i >= 0; i--) {
            for (j = 1; j <= i; j++){
                if (a[j-1] > a[j])
                swap(a[j-1],a[j]);
            }
        }
    }

Đánh giá: Tuy đơn giản nhưng Bubble là thuật toán kém hiệu quả nhất trong 3 thuật toán ở mục này

4. So sánh 3 thuật toán

img

Sắp xếp trộn (Merge Sort)

Sắp xếp trộn (merge sort) là một thuật toán sắp xếp loại so sánh. Thuật toán này là một ví dụ tương đối điển hình của lối thuật toán chia để trị của John von Neumann:

  • Chia (Divide): Chia dãy gồm n phần tử cần sắp xếp thành 2 dãy, mỗi dãy có n/2 phần tử.
  • Trị (Conquer): Sắp xếp mỗi dãy con một cách đệ quy sử dụng sắp xếp trộn. Khi dãy chỉ còn một phần tử thì trả lại phần tử này.
  • Tổ hợp (Combine): Trộn (Merge) hai dãy con được sắp xếp để thu được dãy được sắp xếp gồm tất cả các phần tử của cả hai dãy con.
    MERGE-SORT(A, p, r)
        if p < r 
            then q ← (p + r)/2 // Chia (Divide)
                MERGE-SORT(A, p, q) // Trị (Conquer)
                MERGE-SORT(A, q + 1, r) // Trị (Conquer)
                MERGE(A, p, q, r) // Tổ hợp (Combine)
        endif
    MERGE(M, p, q, r)
        i1; j1
        for k ← p to r do
            if L[ i ] ≤ R[ j ]
            then
                M[k] ← L[ i ]
                ii + 1
            else
                M[k] ← R[ j ]
                jj + 1

Quick Sort

Quick Sort (QS) được phát triển bởi Hoare năm 1960. Theo thống kê tính toán, QS là thuật toán sắp xếp nhanh nhất hiện nay.

Tương tự như Merge sort, Quick sort là thuật toán sắp xếp được phát triển dựa trên kỹ thuật chia để trị:

  1. Neo đệ qui (Base case). Nếu dãy chỉ còn một phần tử thì nó là dãy đã sắp xếp và trả lại dãy này mà không phải làm gì cả.
  2. Chia (Divide):
    • Chọn một phần tử trong dãy và gọi nó là phần tử chốt p (pivot).
    • Chia dãy đã cho ra thành hai dãy con: Dãy con trái (L) gồm những phần tử không lớn hơn phần tử chốt, còn dãy con phải (R) gồm các phần tử không nhỏ hơn phần tử chốt. Thao tác này được gọi là thao tác Phân đoạn (Partition).
  3. Trị (Conquer): Lặp lại một cách đệ qui thuật toán đối với hai dãy con L và R.
  4. Tổng hợp (Combine): Dãy được sắp xếp là L p R.
    Quick-Sort(A, Left, Right)
        if (Left < Right ) {
            Pivot = Partition(A, Left, Right);
            Quick-Sort(A, Left, Pivot – 1);
            Quick-Sort(A, Pivot + 1, Right); }

Chọn phần tử chốt:

Việc chọn phần tử chốt nắm vai trò quyết định đối với hiệu năng của thuật toán. Tốt nhất là chọn phần tử chốt là trung vị của danh sách. Tuy nhiên cách này rất khó nên ta có thể chọn phần tử chốt theo những cách sau:

  • Chọn phần tử đứng đầu hoặc đứng cuối làm phần tử chốt.
  • Chọn phần tử đứng giữa dãy làm phần tử chốt.
  • Chọn phần tử trung vị trong 3 phần tử đứng đầu, đứng giữa và đứng cuối làm phần tử chốt.
  • Chọn phần tử ngẫu nhiên làm phần tử chốt. (Cách này có thể dẫn đến khả năng rơi vào các trường hợp đặc biệt).

Thuật toán Phân đoạn Partition: Mục đích của hàm Partition(A, left, right) là chia A[left..right] thành hai đoạn A[left..pivot –1] và *A[pivot+1..right], sao cho:

  • A[left..pivot –1] là tập hợp các phần tử có giá trị nhỏ hơn hoặc bằng A[pivot].
  • A[pivot+1..right] là tập hợp các phần tử có gía trị lớn hơn A[pivot]

img

Trên đây là một số những thuật toán sắp xếp mình đã tìm hiểu, nếu có gì sai sót, bạn góp ý cho mình tại địa chỉ email nhé. Mình sẽ cập nhật thêm chức năng bình luận trong tương lai để có thể dễ dàng tương tác cùng mọi người hơn

Hi vọng bài viết này có ích với bạn.

Bài đăng phổ biến từ blog này

Công cụ Lập Trình Vim

Vim là gì Vim là một trình soạn thảo văn bản Unix được bao gồm trong Linux, BSD và macOS. Nó được biết đến với tốc độ nhanh và hiệu quả, một phần vì nó là một ứng dụng nhỏ có thể chạy trong một thiết bị đầu cuối (mặc dù nó cũng có giao diện đồ họa), nhưng chủ yếu là vì nó có thể được điều khiển hoàn toàn bằng bàn phím mà không cần menu hoặc chuột. . Ví dụ, để chèn văn bản vào một tệp, bạn nhấn I và nhập. Để điều hướng hoặc ra lệnh (chẳng hạn như Lưu, Xóa lùi, Trang chủ, Kết thúc, v.v.), bạn nhấn Esc trên bàn phím rồi nhấn bất kỳ phím hoặc tổ hợp phím nào tương ứng với hành động bạn muốn thực hiện. Đó là một cách rất khác để chỉnh sửa văn bản so với những gì người dùng máy tính hiện đại mong đợi, nhưng đó là cách quản trị viên Unix trên toàn thế giới chỉnh sửa các tệp cấu hình, thay đổi, tập lệnh và hơn thế nữa. Vim cũng thường được gọi là Vi vì khi nó được viết bởi Bill Joy vào cuối những năm 1970, nó là viết tắt của visual editor. Trước Vi, ít ai tưởng tượng rằng máy tính có thể hoạt

Giới thiệu về Object trong JavaScript

Giới thiệu về Object trong JavaScript Trong JavaScript, một đối tượng là một tập hợp các cặp khóa-giá trị không có thứ tự. Mỗi cặp khóa-giá trị được gọi là một thuộc tính. Khóa của một thuộc tính có thể là một chuỗi. Và giá trị của một thuộc tính có thể là bất kỳ giá trị nào, ví dụ: một chuỗi, một số, một mảng và thậm chí là một hàm. JavaScript cung cấp cho bạn nhiều cách để tạo một đối tượng. Cách phổ biến nhất được sử dụng là sử dụng ký hiệu theo nghĩa đen của đối tượng. Ví dụ sau tạo một đối tượng trống bằng cách sử dụng ký hiệu theo nghĩa đen của đối tượng: let empty = {}; Code language: JavaScript ( javascript ) let person = { firstName : 'John' , lastName : 'Doe' }; Code language: JavaScript ( javascript ) Truy cập thuộc tính Để truy cập thuộc tính của một đối tượng, bạn sử dụng một trong hai ký hiệu: ký hiệu dấu chấm và ký hiệu dạng mảng. 1) Ký hiệu dấu chấm (.) Dưới đây minh họa cách sử dụng ký hiệu dấu chấm để truy cập thuộc tính của một đối tượn