Tổng quat
Những người khác đã đưa ra các ví dụ sơ đồ tốt, chẳng hạn như sơ đồ cây. Tôi không thấy bất kỳ ví dụ mã đơn giản. Vì vậy, ngoài lời giải thích của tôi, tôi sẽ cung cấp một số thuật toán với các câu lệnh in đơn giản để minh họa cho sự phức tạp của các loại thuật toán khác nhau.
Trước tiên, bạn sẽ muốn có một ý tưởng chung về Logarit, mà bạn có thể nhận được từ https://en.wikipedia.org/wiki/Logarithm . Sử dụng khoa học tự nhiên e
và nhật ký tự nhiên. Các môn đồ kỹ thuật sẽ sử dụng log_10 (log cơ sở 10) và các nhà khoa học máy tính sẽ sử dụng log_2 (log cơ sở 2) rất nhiều, vì máy tính là dựa trên nhị phân. Đôi khi bạn sẽ thấy các chữ viết tắt của nhật ký tự nhiên ln()
, các kỹ sư thường bỏ _10 và chỉ sử dụng log()
và log_2 được viết tắt là lg()
. Tất cả các loại logarit đều phát triển theo kiểu tương tự nhau, đó là lý do tại sao chúng có cùng loại log(n)
.
Khi bạn xem các ví dụ mã bên dưới, tôi khuyên bạn nên xem O (1), sau đó O (n), sau đó O (n ^ 2). Sau khi bạn tốt với những người đó, sau đó nhìn vào những người khác. Tôi đã bao gồm các ví dụ rõ ràng cũng như các biến thể để chứng minh các thay đổi tinh tế vẫn có thể dẫn đến cùng một phân loại.
Bạn có thể nghĩ về O (1), O (n), O (logn), v.v. như các lớp hoặc loại tăng trưởng. Một số loại sẽ mất nhiều thời gian hơn để làm hơn những loại khác. Các loại này giúp cung cấp cho chúng tôi một cách sắp xếp hiệu suất thuật toán. Một số phát triển nhanh hơn khi đầu vào n phát triển. Bảng dưới đây cho thấy sự tăng trưởng về số lượng. Trong bảng dưới đây, hãy nghĩ về log (n) là trần của log_2.
Ví dụ mã đơn giản của các danh mục Big O khác nhau:
O (1) - Ví dụ về thời gian không đổi:
Thuật toán 1 in xin chào một lần và nó không phụ thuộc vào n, vì vậy nó sẽ luôn chạy trong thời gian không đổi, vì vậy nó là như vậy O(1)
.
print "hello";
Thuật toán 2 in xin chào 3 lần, tuy nhiên nó không phụ thuộc vào kích thước đầu vào. Ngay cả khi n phát triển, thuật toán này sẽ luôn chỉ in xin chào 3 lần. Điều đó đang được nói 3, là một hằng số, vì vậy thuật toán này cũng vậy O(1)
.
print "hello";
print "hello";
print "hello";
O (log (n)) - Ví dụ logarit:
- Thuật toán 3 - Điều này hoạt động như "log_2"
Thuật toán 3 biểu thị một thuật toán chạy trong log_2 (n). Lưu ý hoạt động bài của vòng lặp for nhân giá trị hiện tại của i với 2, do đó i
đi từ 1 đến 2 đến 4 đến 8 đến 16 đến 32 ...
for(int i = 1; i <= n; i = i * 2)
print "hello";
- Thuật toán 4 - Điều này hoạt động như "log_3"
Thuật toán 4 thể hiện log_3. Thông báo i
đi từ 1 đến 3 đến 9 đến 27 ...
for(int i = 1; i <= n; i = i * 3)
print "hello";
- Thuật toán 5 - Điều này hoạt động như "log_1.02"
Thuật toán 5 rất quan trọng, vì nó giúp chỉ ra rằng miễn là số đó lớn hơn 1 và kết quả được nhân lên nhiều lần so với chính nó, rằng bạn đang xem xét một thuật toán logarit.
for(double i = 1; i < n; i = i * 1.02)
print "hello";
O (n) - Ví dụ về thời gian tuyến tính:
Thuật toán này là đơn giản, mà in xin chào n lần.
for(int i = 0; i < n; i++)
print "hello";
Thuật toán này hiển thị một biến thể, trong đó nó sẽ in hello n / 2 lần. n / 2 = 1/2 * n. Chúng ta bỏ qua hằng số 1/2 và thấy rằng thuật toán này là O (n).
for(int i = 0; i < n; i = i + 2)
print "hello";
O (n * log (n)) - nlog (n) Ví dụ:
Hãy nghĩ về điều này như là một sự kết hợp của O(log(n))
và O(n)
. Việc lồng các vòng lặp giúp chúng ta có đượcO(n*log(n))
for(int i = 0; i < n; i++)
for(int j = 1; j < n; j = j * 2)
print "hello";
Thuật toán 9 giống như thuật toán 8, nhưng mỗi vòng lặp đã cho phép các biến thể, điều này vẫn dẫn đến kết quả cuối cùng là O(n*log(n))
for(int i = 0; i < n; i = i + 2)
for(int j = 1; j < n; j = j * 3)
print "hello";
O (n ^ 2) - n bình phương Ví dụ:
O(n^2)
có được dễ dàng bằng cách lồng tiêu chuẩn cho các vòng lặp.
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
print "hello";
Giống như thuật toán 10, nhưng với một số biến thể.
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j = j + 2)
print "hello";
O (n ^ 3) - n Ví dụ:
Điều này giống như thuật toán 10, nhưng với 3 vòng thay vì 2.
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
for(int k = 0; k < n; k++)
print "hello";
Giống như thuật toán 12, nhưng với một số biến thể vẫn mang lại O(n^3)
.
for(int i = 0; i < n; i++)
for(int j = 0; j < n + 5; j = j + 2)
for(int k = 0; k < n; k = k + 3)
print "hello";
Tóm lược
Ở trên đưa ra một số ví dụ thẳng về phía trước và các biến thể để giúp chứng minh những thay đổi tinh tế nào có thể được đưa ra mà thực sự không thay đổi phân tích. Hy vọng nó cung cấp cho bạn đủ hiểu biết.