Thứ Tư, 25 tháng 1, 2017

Một số thuật toán

Thuật toán (giải thuật) là các phương cách được định nghĩa rõ ràng cho việc hoàn tất một số sự việc từ trạng thái ban đầu cho trước.

Các thuật toán sắp xếp:
  • Nổi bọt (bubble sort): là phương pháp sắp xếp đơn giản, dễ hiểu thường được dạy trong khoa học máy tính. Giải thuật bắt đầu từ đầu của tập dữ liệu. Nó so sánh hai phần tử đầu, nếu phần tử đứng trước lớn hơn phần tử đứng sau thì đổi chỗ chúng cho nhau. Tiếp tục làm như vậy với cặp phần tử tiếp theo cho đến cuối tập hợp dữ liệu. Sau đó nó quay lại với hai phần tử đầu cho đến khi không còn cần phải đổi chỗ nữa. 
  • Chèn (insertion sort): là thuật toán sắp xếp xử lý chèn phần tử đang xét vào vị trí thích hợp của dãy số đã sắp xếp phía trước sao cho dãy số vẫn là dãy sắp xếp có thứ tự.
  • Chọn (selection sort): là phương pháp sắp xếp bằng cách chọn phần tử bé nhất xếp vào vị trí thứ nhất, tương tự với các phần tử nhỏ thứ hai, thứ ba,...
  • Trộn (merge sort): Cùng với "sắp xếp nhanh", đều dựa vào tư tưởng "chia để trị" (divide and conquer). Thủ tục cơ bản là việc trộn hai danh sách đã được sắp xếp vào một danh sách mới theo thứ tự. Nó có thể bắt đầu trộn bằng cách so sánh hai phần tử một (chẳng hạn phần tử thứ nhất với phần tử thứ hai, sau đó thứ ba với thứ tư...) và sau khi kết thúc bước 1 nó chuyển sang bước 2. Ở bước 2 nó trộn các danh sách hai phần tử thành các danh sách bốn phần tử. Cứ như vậy cho đến khi hai danh sách cuối cùng được trộn thành một.
  • Vun đống (heapsort): Là một trong phương pháp sắp xếp chọn. Ở mỗi bước của sắp xếp chọn ta chọn phần tử lớn nhất (hoặc nhỏ nhất) đặt vào cuối (hoặc đầu) danh sách, sau đó tiếp tục với phần còn lại của danh sách. Thông thường sắp xếp chọn chạy trong thời gian O(n2). Nhưng heapsort đã giảm độ phức tạp này bằng cách sử dụng một cấu trúc dữ liệu đặc biệt được gọi là đống (heap). Đống là cây nhị phân mà trọng số ở mỗi đỉnh cha lớn hơn hoặc bằng trọng số các đỉnh con của nó. Một khi danh sách dữ liệu đã được vun thành đống, gốc của nó là phần tử lớn nhất, thuật toán sẽ giải phóng nó khỏi đống để đặt vào cuối danh sách. Sắp xếp vun đống chạy trong thời gian O(n log n).
  • Sắp xếp nhanh (quick sort): là một thuật toán theo tư tưởng chia để trị. Nó dựa trên thủ tục phân chia như sau: để chia một dãy ta chọn một phần tử được gọi là "chốt" (pivot), chuyển tất cả các phần tử nhỏ hơn chốt về trước chốt, chuyển tất cả các phần tử lớn hơn chốt về sau nó (nếu sắp xếp theo dãy theo thứ tự tăng dần), nếu sắp xếp dãy theo thứ tự giảm dần ta chuyển tất cả các phần tử nhỏ hơn chốt về bên phải chốt và lớn hơn chốt về bên trái chốt. Thủ tục này có thể thực hiện trong thời gian tuyến tính. Tiếp tục phân chia các dãy con đó như trên cho đến khi các dãy con chỉ còn một phần tử.

    Điểm khác biệt giữa sắp xếp nhanh và sắp xếp trộn là trong sắp xếp trộn việc xác định thứ tự được xác định khi "trộn", tức là trong khâu tổng hợp lời giải sau khi các bài toán con đã được giải, còn sắp xếp nhanh đã quan tâm đến thứ tự các phần tử khi phân chia một danh sách thành hai danh sách con.

    Ngoài ra còn nhiều giải thuật sắp xếp khác, trong đó nhiều giải thuật sắp xếp được cải tiến từ các giải thuật trên. Trong sau giải thuật liệt kê trên, ta thường coi các giải thuật chèn, chọn, nổi bọt là các giải thuật cơ bản, độ phức tạp trong trường hợp trung bình của chúng là O(n^2). Ba giải thuật còn lại thường được coi là giải thuật cao cấp, độ phức tạp tính toán trung bình của chúng là O(n log n).

Cấu trúc dữ liệu

Cấu trúc dữ liệu là cách lưu trữ, tổ chức dữ liệu sao cho có thể sử dụng một cách hiệu quả. Một cấu trúc dữ liệu được thiết kế tốt cho phép thực hiện nhiều phép toán, sử dụng càng ít tài nguyên, thời gian xử lý và không gian bộ nhớ tốt.

Các kiểu dữ liệu:
  • Kiểu dữ liệu cơ bản: Boolean, Integer, Float, String...
  • Kiểu kết hợp: Array, Struct/Tuple,...
  • Kiểu dữ liệu trừu tượng: Hàng đợi (queue), Ngăn xếp (stack), Cây (tree), Đồ thị (tree), Băm (hash),..
 Cấu trúc dữ liệu tuyến tính:
  • Mảng (array),
  • Danh sách liên kết (linked list): Danh sách liên kết (linked list), Skip List (danh sách nhảy cóc - tối ưu xác suất tìm kiếm), danh sách liên kết đôi, danh sách liên kết vòng
  • Cây nhị phân: Cây tìm kiếm tự cân bằng, Cây AVL, Cây tìm kiếm nhị phân, Cây đỏ đen (Read-Black Tree), Cây cân bằng, Splay tree...
  • B-cây (B-tree): Là một tổng quát hóa của cây nhị phân tìm kiếm. Một nút có thể có nhiều con...
  • Heap (đống): là cấu trúc dữ liệu dựa trên Cây, thỏa mãn tính chất đống: Nếu B là nút con của A thì khóa(A)>=khóa(B). Hay ứng dụng cho thuật toán đồ thị như Dijkstra, hay thuật toán sắp sếp HeapSort;
  • Băm (hash): hashtable (bảng băm)
  • Đồ thị (grahp): Ma trận kề,...
 Cấu trúc dữ liệu trừu tượng:
  • Ngăn xếp: Stack
  • Hàng đợi: Queue, hàng đợi ưu tiên (priority queue)
Một số ví dụ, bài viết liên quan:
 https://www.codeproject.com/Articles/16337/Back-to-Basics-Generic-Data-Structures-and-Algorit