“Thời gian truy cập O (1)” nghĩa là gì?


126

Tôi đã thấy thuật ngữ "O (1) access time" này được sử dụng có nghĩa là "nhanh chóng" nhưng tôi không hiểu nghĩa của nó. Thuật ngữ khác mà tôi thấy với nó trong cùng ngữ cảnh là "thời gian truy cập O (n)". Ai đó có thể vui lòng giải thích một cách đơn giản những thuật ngữ này có nghĩa là gì?

Xem thêm


Điều này có thể hữu ích: stackoverflow.com/questions/471199/…
Mehrdad Afshari,

Câu trả lời:


161

Bạn sẽ muốn đọc về Thứ tự phức tạp.

http://en.wikipedia.org/wiki/Big_O_notation

Tóm lại, O (1) có nghĩa là nó mất một khoảng thời gian không đổi, chẳng hạn như 14 nano giây hoặc ba phút bất kể số lượng dữ liệu trong tập hợp.

O (n) có nghĩa là nó cần một khoảng thời gian tuyến tính với kích thước của tập hợp, vì vậy một tập hợp có kích thước gấp đôi sẽ mất gấp đôi thời gian. Bạn có thể không muốn đặt một triệu đối tượng vào một trong số này.


66
Nói một cách phức tạp, điều đó không có nghĩa là thời gian chạy (hoặc số lượng hoạt động, v.v.) là không đổi. Có nghĩa là có một hằng số sao cho thời gian chạy (hoặc số lượng hoạt động, v.v.) bị giới hạn ở trên bởi hằng số. Vẫn có thể có phương sai lớn trong thời gian chạy: ví dụ: int main() { int n; cin >> n; if(n == 0) { sleep(60 * 60 * 24 * 365); } cout << n; }O(1).
jason

Cái nhìn sâu sắc @jason!
Chris Ruskai

35

Về bản chất, Điều đó có nghĩa là cần cùng một khoảng thời gian để tra cứu một giá trị trong bộ sưu tập của bạn cho dù bạn có một số lượng nhỏ các mục trong bộ sưu tập của mình hay rất nhiều (trong giới hạn phần cứng của bạn)

O (n) có nghĩa là thời gian cần thiết để tra cứu một mục tỷ lệ thuận với số lượng mục trong bộ sưu tập.

Ví dụ điển hình của những điều này là mảng, có thể được truy cập trực tiếp, bất kể kích thước của chúng và danh sách được liên kết, phải được duyệt theo thứ tự ngay từ đầu để truy cập một mục nhất định.

Hoạt động khác thường được thảo luận là chèn. Một tập hợp có thể là O (1) để truy cập nhưng O (n) để chèn. Trên thực tế, một mảng có chính xác hành vi này, bởi vì để chèn một mục vào giữa, Bạn sẽ phải di chuyển từng mục sang bên phải bằng cách sao chép nó vào vị trí sau.


21

Mọi câu trả lời hiện đang trả lời cho câu hỏi này đều cho bạn biết rằng O(1)thời gian không đổi có nghĩa là (bất kỳ điều gì xảy ra với phép đo; có thể là thời gian chạy, số lần hoạt động, v.v.). Điều này không chính xác.

Nói rằng thời gian chạy O(1)có nghĩa là có một hằng số csao cho thời gian chạy được giới hạn ở trên c, độc lập với đầu vào. Ví dụ, trả về phần tử đầu tiên của một mảng các nsố nguyên là O(1):

int firstElement(int *a, int n) {
    return a[0];
}

Nhưng chức năng này O(1)quá:

int identity(int i) {
    if(i == 0) {
        sleep(60 * 60 * 24 * 365);
    }
    return i;
}

Thời gian chạy ở đây được giới hạn trên 1 năm, nhưng phần lớn thời gian chạy theo thứ tự nano giây.

Nói rằng thời gian chạy O(n)có nghĩa là có một hằng số csao cho thời gian chạy được giới hạn ở trên c * n, nơi nđo kích thước của đầu vào. Ví dụ: tìm số lần xuất hiện của một số nguyên cụ thể trong một mảng nsố nguyên chưa được sắp xếp bằng thuật toán sau O(n):

int count(int *a, int n, int item) {
    int c = 0;
    for(int i = 0; i < n; i++) {
        if(a[i] == item) c++;
    }
    return c;
}

Điều này là do chúng ta phải lặp qua mảng kiểm tra từng phần tử một.


19

O (1) có nghĩa là thời gian để truy cập thứ gì đó độc lập với số lượng item trong bộ sưu tập.

O (N) có nghĩa là thời gian truy cập một mục tỷ lệ thuận với số lượng (N) mục trong bộ sưu tập.


14

O (1) không nhất thiết có nghĩa là "nhanh chóng". Có nghĩa là thời gian cần là không đổi và không dựa trên kích thước của đầu vào cho hàm. Hằng số có thể nhanh hoặc chậm. O (n) có nghĩa là thời gian hàm thực hiện sẽ thay đổi tỷ lệ thuận với kích thước của đầu vào cho hàm, được ký hiệu là n. Một lần nữa, nó có thể nhanh hoặc chậm, nhưng sẽ chậm hơn khi kích thước của n tăng lên.


9

Nó được gọi là ký hiệu Big O và mô tả thời gian tìm kiếm các thuật toán khác nhau.

O (1) có nghĩa là thời gian chạy trong trường hợp xấu nhất là không đổi. Đối với hầu hết các tình huống, điều đó có nghĩa là bạn thực sự không cần phải tìm kiếm bộ sưu tập, bạn sẽ tìm thấy những gì bạn đang tìm kiếm ngay lập tức.


Thay thế "thời gian tìm kiếm" bằng "thời gian chạy trong trường hợp xấu nhất" và tôi ở bên bạn.
Jason Punyon

2
@Seb: Tôi nghĩ đó chỉ là một sự nhầm lẫn từ phía anh ấy, cụ thể là vì OP đã hỏi về thời gian truy cập.
jkeys

6

O(1)luôn thực thi trong cùng một thời điểm bất kể tập dữ liệu n. Ví dụ về O (1) sẽ là một ArrayList truy cập phần tử của nó bằng chỉ mục.

O(n)còn được gọi là Thứ tự tuyến tính, hiệu suất sẽ phát triển tuyến tính và tỷ lệ thuận với kích thước của dữ liệu đầu vào. Ví dụ về O (n) là chèn và xóa ArrayList ở vị trí ngẫu nhiên. Khi mỗi lần chèn / xóa tiếp theo ở vị trí ngẫu nhiên sẽ khiến các phần tử trong ArrayList dịch sang trái bên phải mảng bên trong của nó để duy trì cấu trúc tuyến tính của nó, chưa kể đến việc tạo mảng mới và sao chép các phần tử từ mảng cũ. sang mảng mới, do đó, tốn thời gian xử lý, gây tổn hại đến hiệu suất.


4

"Ký hiệu Big O" là một cách để thể hiện tốc độ của thuật toán. nlà lượng dữ liệu mà thuật toán đang làm việc. O(1)có nghĩa là, không có vấn đề bao nhiêu dữ liệu, nó sẽ thực thi trong thời gian không đổi. O(n)nghĩa là nó tỷ lệ với số lượng dữ liệu.


3

Về cơ bản, O (1) có nghĩa là thời gian tính toán của nó là không đổi, trong khi O (n) có nghĩa là nó sẽ phụ thuộc tuyến tính vào kích thước của đầu vào - tức là lặp qua một mảng có O (n) - chỉ lặp lại -, vì nó phụ thuộc vào số trong số các mục, trong khi tính toán tối đa giữa các số thông thường có O (1).

Wikipedia cũng có thể hữu ích: http://en.wikipedia.org/wiki/Computational_complexity_theory


3

Cách dễ nhất để phân biệt O (1) và O (n) là so sánh mảng và danh sách.

Đối với mảng, nếu bạn có giá trị chỉ mục phù hợp, bạn có thể truy cập dữ liệu ngay lập tức. (Nếu bạn không biết chỉ mục và phải lặp qua mảng, thì nó sẽ không còn là O (1) nữa)

Đối với danh sách, bạn luôn cần phải lặp lại nó cho dù bạn có biết chỉ mục hay không.


Tôi đang tìm kiếm một ví dụ về O (1) và chỉ câu trả lời này mới có lời giải thích cho nó.
neelmeg

3

Đây là một phép loại suy đơn giản; Hãy tưởng tượng bạn đang tải phim trực tuyến, với O (1), nếu bạn mất 5 phút để tải một phim thì vẫn mất khoảng thời gian như vậy để tải 20 phim. Vì vậy, không quan trọng bạn đang tải bao nhiêu phim, chúng sẽ mất cùng thời gian (5 phút) cho dù đó là một hay 20 phim. Một ví dụ bình thường của sự tương tự này là khi bạn vào thư viện phim, cho dù bạn đang xem một phim hay 5 phim, bạn chỉ cần chọn chúng cùng một lúc. Do đó chi tiêu cùng một thời gian.

Tuy nhiên, với O (n), nếu để tải một phim mất 5 phút thì bạn sẽ mất khoảng 50 phút để tải 10 phim. Vì vậy, thời gian không phải là bất biến hoặc bằng cách nào đó tỷ lệ thuận với số lượng phim bạn đang tải xuống.


1

Có nghĩa là thời gian truy cập là không đổi. Cho dù bạn đang truy cập từ 100 hay 100.000 bản ghi, thời gian truy xuất sẽ giống nhau.

Ngược lại, thời gian truy cập O (n) sẽ chỉ ra rằng thời gian truy xuất tỷ lệ thuận với số lượng bản ghi mà bạn đang truy cập.


1

Nó có nghĩa là truy cập mất thời gian không đổi, tức là không phụ thuộc vào kích thước của tập dữ liệu. O (n) có nghĩa là truy cập sẽ phụ thuộc vào kích thước của tập dữ liệu một cách tuyến tính.

Chữ O còn được gọi là big-O.


1

Giới thiệu về các thuật toán: Phiên bản thứ hai của Cormen, Leiserson, Rivest & Stein nói ở trang 44 rằng

Vì bất kỳ hằng số nào là một đa thức bậc 0, chúng ta có thể biểu diễn bất kỳ hàm hằng số nào dưới dạng Theta (n ^ 0) hoặc Theta (1). Tuy nhiên, ký hiệu thứ hai này là một sự lạm dụng nhỏ vì không rõ biến nào đang có xu hướng đến vô cùng. Chúng ta thường sử dụng ký hiệu Theta (1) để có nghĩa là một hằng số hoặc một hàm hằng đối với một số biến. ... Ta ký hiệu là O (g (n)) ... tập các hàm f (n) sao cho tồn tại các hằng số dương c và n0 sao cho 0 <= f (n) <= c * g (n) với mọi n> = n0. ... Lưu ý rằng f (n) = Theta (g (n)) ngụ ý f (n) = O (g (n)), vì ký hiệu Theta mạnh hơn ký hiệu O.

Nếu một thuật toán chạy trong thời gian O (1), điều đó có nghĩa là tiệm cận không phụ thuộc vào bất kỳ biến nào, có nghĩa là tồn tại ít nhất một hằng số dương mà khi nhân với một hằng số lớn hơn độ phức tạp tiệm cận (~ thời gian chạy) của hàm cho các giá trị của n trên một số lượng nhất định. Về mặt kỹ thuật, đó là thời gian O (n ^ 0).


-2

O (1) có nghĩa là Truy cập Ngẫu nhiên. Trong bất kỳ Bộ nhớ Truy cập Ngẫu nhiên nào, thời gian thực hiện để truy cập bất kỳ phần tử nào tại bất kỳ vị trí nào là như nhau. Ở đây thời gian có thể là bất kỳ số nguyên nào, nhưng điều duy nhất cần nhớ là thời gian cần thiết để truy xuất phần tử ở vị trí (n-1) hoặc thứ n sẽ giống nhau (tức là không đổi).

Trong khi O (n) phụ thuộc vào kích thước của n.


Nó không có gì để làm với truy cập ngẫu nhiên - xem câu trả lời được chấp nhận đăng tải gần một năm trước khi câu trả lời này cho biết thêm
Krease

-3

Theo góc nhìn của tôi,

O (1) có nghĩa là thời gian để thực hiện một thao tác hoặc lệnh tại một thời điểm là một, trong phân tích độ phức tạp theo thời gian của thuật toán cho trường hợp tốt nhất.


6
Cố gắng hơn nữa. Câu hỏi cụ thể đó không chỉ cần một góc nhìn mà còn cần một định nghĩa rõ ràng.
Alfabravo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.