Docsity
Docsity

Prepare for your exams
Prepare for your exams

Study with the several resources on Docsity


Earn points to download
Earn points to download

Earn points by helping other students or get them with a premium plan


Guidelines and tips
Guidelines and tips

data structures and algorithms, Cheat Sheet of Data Structures and Algorithms

data structures and algorithms

Typology: Cheat Sheet

2020/2021

Uploaded on 11/27/2022

dieu-linh-18
dieu-linh-18 🇻🇳

3 documents

1 / 147

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
ii
BỘ CÔNG THƯƠNG
TRƯỜNG ĐẠI HỌC KINH TẾ - KỸ THUẬT CÔNG NGHIỆP
KHOA CÔNG NGHỆ THÔNG TIN
Chủ biên PHÙNG THỊ THU HIỀN
VŨ THU UYÊN
TÀI LIỆU HỌC TẬP
MÔN CẤU TRÚC DỮ LIỆU GIẢI THUẬT
Đối tượng: Sinh viên trình độ Đại học
Ngành đào tạo: Công nghệ thông tin
Năm 2019
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21
pf22
pf23
pf24
pf25
pf26
pf27
pf28
pf29
pf2a
pf2b
pf2c
pf2d
pf2e
pf2f
pf30
pf31
pf32
pf33
pf34
pf35
pf36
pf37
pf38
pf39
pf3a
pf3b
pf3c
pf3d
pf3e
pf3f
pf40
pf41
pf42
pf43
pf44
pf45
pf46
pf47
pf48
pf49
pf4a
pf4b
pf4c
pf4d
pf4e
pf4f
pf50
pf51
pf52
pf53
pf54
pf55
pf56
pf57
pf58
pf59
pf5a
pf5b
pf5c
pf5d
pf5e
pf5f
pf60
pf61
pf62
pf63
pf64

Partial preview of the text

Download data structures and algorithms and more Cheat Sheet Data Structures and Algorithms in PDF only on Docsity!

ii

BỘ CÔNG THƯƠNG

TRƯỜNG ĐẠI HỌC KINH TẾ - KỸ THUẬT CÔNG NGHIỆP

KHOA CÔNG NGHỆ THÔNG TIN

Chủ biên PHÙNG THỊ THU HIỀN VŨ THU UYÊN

TÀI LIỆU HỌC TẬP

MÔN CẤU TRÚC DỮ LIỆU  GIẢI THUẬT

Đối tượng: Sinh viên trình độ Đại học

Ngành đào tạo: Công nghệ thông tin

Năm 2019

iii

MỤC LỤC

MỤC LỤC........................................................................................................................iii DANH MỤC CÁC HÌNH VẼ..........................................................................................vii

v 2 ............................................................................................................................................................. 78 4 ............................................................................................................................................................. 78 2 ............................................................................................................................................................. 78 *............................................................................................................................................................. 78 8 ............................................................................................................................................................. 78 +............................................................................................................................................................. 78 6 ............................................................................................................................................................. 78 /............................................................................................................................................................. 78 3 ............................................................................................................................................................. 78 /............................................................................................................................................................. 78 3 ............................................................................................................................................................. 78 +............................................................................................................................................................. 78 7 ............................................................................................................................................................. 78

  • ............................................................................................................................................................. 78 6 ............................................................................................................................................................. 78 6 ............................................................................................................................................................. 78 14 ........................................................................................................................................................... 78 14 ........................................................................................................................................................... 78 14 ........................................................................................................................................................... 78 14 ........................................................................................................................................................... 78 7 ............................................................................................................................................................. 78 5.2. Hàng đợi (Queue)........................................................................................................................... 78 5.2.1. Cấu trúc....................................................................................................................................... 78 5.2.2. Các phép xử lý.............................................................................................................................. 79 5.2.3. Ứng dụng ..................................................................................................................................... 84 CHƯƠNG 6: CÂY........................................................................................................... 87 6.1. Các khái niệm cơ bản...................................................................................................................... 87 6.2. Cây nhị phân ............................................................................................................. 88 6.2.1. Định nghĩa và các tính chất .......................................................................................................... 88

vi

viii Hình 7.1: Sơ đồ cây để tính số Fibonacci....................................................................... 112

ix

DANH MỤC CÁC BẢNG

Bảng 1: Ký hiệu để biểu diễn lưu đồ.................................................................................. 3 Bảng 2. Biểu diễn thời gian chạy của thuật toán.............................................................. 12 Bảng 3: Minh họa các bước thực hiện của biểu thức P..................................................... 77 Bảng 4: Minh họa các bước thực hiện của biểu thức M................................................... 78 Bảng 5: Minh họa các bước thực hiện duyệt đồ thị bằng hàng đợi................................... 85

1

CHƯƠNG 1: THIẾT KẾ VÀ PHÂN TÍCH GIẢI THUẬT

Mục tiêu của chương Nắm vững:

  • Các khái niệm về cấu trúc dữ liệu, giải thuật, chương trình và các đặc trưng của thuật toán:
  • Trình tự thực hiện các bước của thuật toán ứng d ụ ng trong các bài tập c ụ thể.
  • Độ phức tạp của giải thuật
  • Vận dụ ng lý thuyết viết giải thuật các bài tập từ đơn giản đến phức tạp. Nội dung của chương Nghiên cứu một số khái niệm cơ bản về giải thuật, các cách diễn tả giải thuật: bằng ngôn ngữ tự nhiện, và bằng ngôn ngữ lập trình c++. 1.1. Giải thuật và cấu trúc dữ liệu Khi cần giải quyết một bài toán trong thực tế với sự trợ giúp của máy tính điện tử, người sử dụ ng thường phải biết dữ liệu vào của bài toán (input) và yêu cầu dữ liệu ra (output) của bài toán. Bước tiếp theo, phải thiết lập được các bước thao tác cụ thể để từ input ta có được output. Công việc đó trong Tin học được gọi là xây dựng giải thuật. 1.1.1. Khái niệm giải thuật Giải thuật hay thuật toán - Algorithm là một khái niệm cơ sở của Tin học. Thuật ngữ “Algorithm” là dãy các câu lệnh chặt chẽ và rõ ràng xác đ ịnh một trình tự các thao tác trên một số đối tượng nào đó sao cho sau một số hữu hạn bước thực hiện đạt được kết quả mong muốn. Hay có thể diễn tả thuật toán là một dãy hữu hạn các quy tắc, thao tác hay phép toán để giải quyết một vấn đề. Có nhiều cách để biểu diễn một thuật toán, chẳng hạn như ngôn ngữ tự nhiên, ngôn ngữ lưu đồ, ngôn ngữ mã giả, ngôn ngữ lập trình, … 1.1.1.1. Diễn đạt bằng ngôn ngữ tự nhiên Ví dụ 1.1: Mô tả thuật giải tìm ước chung lớn nhất (UCLN) của hai số a và b là: Bước 1: Nhập vào hai số a và b. Bước 2: So sánh 2 số a,b chọn số nhỏ nhất gán cho UCLN. Bước 3: Nếu hai số a và b chia hết cho UCLN thì Thực hiện bước 5. Bước 4: Giảm UCLN một đơn vị và quay lại bước 3 Bước 5: In UCLN - kết thúc. Cách diễn đạt này tuy khá đơn giản và gần gũi với tư duy của con người nhưng phụ thuộc rất nhiều vào cách diễn đạt của người sử dụ ng. Ví dụ 1.2: Mô tả thuật giải cho bài toán tính tổng (với n nguyên, dương).

2 Bước 1: Nhập số các số hạng n. Bước 2: Cho S=0 (lưu trữ số 0 trong S) Bước 3: Cho i=1 (lưu trữ số 1 trong i) Bước 4: Kiểm tra nếu i<=n thì thực hiện bước 5, ngược lại thực hiện bước 8. Bước 5: Nhập ai Bước 6: Cho S=S+ ai (lưu trữ giá trị S + ai trong S) Bước 7: Tăng i lên 1 đơn v ị và quay lại bước 4. Bước 8: In S và kết thúc chương trình. Vi dụ 1.3: Mô tả thuật giải cho bài toán nhập vào 1 số n, sau đó lần lượt nhập vào n giá trị a 1 , a 2 ,…,an. Hãy tìm và in ra giá trị lớn nhất trong n số a 1 , a 2 ,…,an. Bước 1: Nhập số n. Bước 2: Nhập số thứ nhất a 1. Bước 3: Gán max=a 1. Bước 4: Gán i=2. Bước 5: Nếu i<=n thì thực hiện bước 6, ngược lại thực hiện bước 9. Bước 6: Nhập ai. Bước 7: Nếu max < ai thì gán max=ai. Bước 8: Tăng i lên một đơn vị và quay lại bước 5. Bước 9: In max - kết thúc. Vi dụ 1.4: Mô tả thuật giải cho bài toán tính bình phương của một số. Bước 1: Nhập giá trị cho x Bước 2: Tính giá trị xx và gán cho s Bước 3: Trả về giá trị s. Vi dụ 1.6: Mô tả thuật giải cho bài toán tăng lương hiện tại lên 5%. Bước 1: Nhập giá trị cho lương _cũ. Bước 2: Tính giá trị lương_cũ1.05 và gán cho lương_mới. Bước 3: Trả về giá trị lương_mới. Ví dụ 1.5. Mô tả thuật giải cho bài toán giải phương trình bậc hai. Bước 1: Yêu cầu cho biết giá trị của 3 hệ số a, b, c. Bước 2: Nếu a = 0, thông báo dữ liệu đầu vào không đảm bảo. Kết thúc giải thuật. Bước 3: Nếu a ≠ 0: 3.1: Tính Delta = b^2 - 4ac. 3.2: Nếu Delta > 0 thì xuất thông báo phương trình có 2 nghiệm phân biệt là x1, x2.

4 Nếu đúng là a = 0, thì đi đến bước 3. Nếu không, nghĩa là a ≠ 0, thì đi đến bước 4.

  • Bước 3: Xét điều kiện b = 0? Nếu b = 0, thì báo phương trình có vô số nghiệm. Chuyển đến bước 5. Nếu b  0, thông báo phương trình vô nghiệm. Chuyển đến bước 5.
  • Bước 4: Thông báo phương trình có một nghiệm duy nhất là x = - b/a.
  • Bước 5: Kết thúc thuật toán. Trong ví dụ trên ta có thể trình bày với lưu đồ sau: Hình 1.1: Lưu đồ thuật toán giải phương trình bậc nhất ax + b = 0. Ví dụ 1.7: Vẽ lưu đồ cho thuật toán đổi chỗ. Viết thuật toán để nhập vào 2 số A, B từ bàn phím sau đó đổi giá tr ị của biến A cho biến B và ngược lại. Để viết thuật toán cho bài toán này, chúng ta sẽ đưa thêm vào chương trình một biến trung gian (TG) sau đó tiến hành chuyển giá trị của biến A cho biến TG, chuyển giá trị của biến B cho biến A và cuối cùng chuyển giá tr ị của biến TG cho biến B. Thuật toán được trình bày như sau: Bắt đầu Nhập a, b x = -b/a^ a=^ 0? b= 0? Phương trình vô nghiệm Phương trình vô số nghiệm Kết thúc đúng sai đúng sai

5 Hình 1.2: Lưu đồ thuật toán đổi chỗ. Ví dụ 1.8: Vẽ lưu đồ cho thuật toán tính A = x^2 + y^2 Hình 1.3: Lưu đồ thuật toán tính A = x2+ y2. 1.1.1.3. Dùng mã giả Phương pháp này sử dụ ng các cú pháp của một ngôn ngữ lập trình c ụ thể để thể hiện giải thuật. Dùng mã giả vừa vận dụ ng được các khái niệm trong ngôn ngữ lập trình, vừa giúp người cài đặt dễ dàng nắm bắt được nội dung giải thuật. Tuy nhiên, trong mã giả vẫn dùng một phần ngôn ngữ tự nhiên. Ví dụ 1.9: Một đoạn mã giả của giải thuật giải phương trình ax^2 + bx + c = 0 (a ≠ 0), minh họa bằng ngôn ngữ C++. int main() { float a, b, c; // khai bao cac he so Đọc 2 số x,y A= x 2

  • y 2 Bắt đầu Kết thúc Xuất A

TG:=A

B:=TG

A:=B

Đọc 2 số A,B In ra A,B Bắt đầu Kết thúc

7  Cấu trúc lựa chọn (Selection) : Lựa chọn một công việc để thực hiện căn cứ vào một điều kiện nào đó. Có một số dạng như sau:

  • Cấu trúc 1: Nếu <điều kiện> (đúng) thì thực hiện <công việc>
  • Cấu trúc 2: Nếu <điều kiện> (đúng) thì thực hiện <công việc 1>, ngược lại (điều kiện sai) thì thực hiện <công việc 2>.
  • Cấu trúc 3: Trường hợp thực hiện <công việc i>.  Cấu trúc lặp (Repeating): Thực hiện lặp lại một công việc nhiều lần căn cứ vào một điều kiện nào đó. Có hai dạng như sau:
  • Lặp xác đị nh: là loại lặp mà khi viết chương trình, người lập trình đã xác đị nh được công việc sẽ lặp bao nhiêu lần.
  • Lặp không xác đị nh: là loại lặp mà khi viết chương trình người lập trình chưa xác đị nh được công việc sẽ lặp bao nhiêu lần. Số lần lặp sẽ được xác đị nh khi chương trình thực thi. 1.1.2. Khái niệm cấu trúc dữ liệu Trong một bài toán, dữ liệu bao gồm một tập các phần tử cơ sở, mà ta gọi là dữ liệu nguyên tử (atoms). Nó có thể là một chữ số, một ký tự… nhưng cũng có thể là một con số, hay một từ…, điều đó tùy thuộc vào từng bài toán. Trên cơ sở của các kiểu dữ liệu nguyên tử, liên kết chúng lại với nhau sẽ dẫn tới các cấu trúc dữ liệu khác. Khi đã xác đị nh được cấu trúc dữ liệu thích hợp, người lập trình sẽ bắt đầu tiến hành xây dựng thuật giải tương ứng theo yêu cầu của bài toán đặt ra trên cơ sở của cấu trúc dữ liệu đã được chọn. Để giải quyết một vấn đề có thể có nhiều phương pháp, do vậy sự lựa chọn phương pháp phù hợp là một việc mà người lập trình phải cân nhắc và tính toán. Sự lựa chọn này cũng có thể góp phần đáng kể trong việc giảm bớt công việc của người lập trình trong phần cài đặt thuật toán trên một ngôn ngữ cụ thể. Thường trong một ngôn ngữ lập trình bao giờ cũng có các cấu trúc dữ liệu tiền đị nh. Nếu như sử dụ ng một ngôn ngữ mà cấu trúc tiền đị nh của nó phù hợp với cấu trúc dữ liệu xác đị nh bởi người dùng thì rất thuận lợi. Nhưng không phải mọi cấu trúc dữ liệu tiền đị nh đều đáp ứng được mọi yêu cầu cần thiết. Vì vậy phải biết vận d ụ ng linh hoạt chúng để mô phỏng các cấu trúc dữ liệu đó chọn cho bài toán cần giải. 1.2. Cấu trúc dữ liệu và các vấn đề liên quan Khi giải quyết một bài toán trên máy tính, thường chỉ chú trọng đến việc xây dựng giải thuật mà quên đi tầm quan trọng của việc tổ chức dữ liệu trong bài toán. Giải thuật phản ánh các phép xử lý, còn đối tượng xử lý của giải thuật lại là dữ liệu. Chính dữ liệu chứa đựng các thông tin cần thiết để thực hiện giải thuật. Để xác đ ịnh được giải thuật phù hợp cần phải biết nó tác động đến loại dữ liệu nào và khi lựa chọn cấu trúc dữ liệu cũng cần phải hiểu rõ những thao tác nào tác động lên dữ liệu đó. Như

8 vậy, cấu trúc dữ liệu và giải thuật có mối quan hệ chặt chẽ với nhau, được thể hiện qua công thức: Cấu trúc dữ liệu + Giải thuật = Chương trình Với một cấu trúc dữ liệu đã chọn, sẽ có những giải thuật tương ứng, phù hợp. Khi cấu trúc dữ liệu thay đổi thường giải thuật cũng phải thay đổi theo. Hơn nữa, một cấu trúc dữ liệu tốt sẽ giúp giải thuật xử lý trên đó có thể phát huy tác dụ ng tốt hơn, vừa nhanh vừa tiết kiêm vật tư, giải thuật cũng đơn giản và dễ hiểu hơn. Thường trong một ngôn ngữ lập trình bao giờ cũng có các cấu trúc dữ liệu tiền đị nh (predefined data structures). Chẳng hạn: cấu trúc mảng (array) là cấu trúc rất phổ biến trong các ngôn ngữ. Nó thường được sử dụ ng đề tổ chức các tập dữ liệu, có số lựợng ấn đị nh và có cùng kiểu Nếu như sử dụ ng một ngôn ngữ mà cấu trúc dữ liệu tiền đ ịnh của nó phù hợp với cấu trúc dữ liệu xác đ ịnh bởi người dùng thì tất nhiên rất thuận tiện. Nhưng không phải các cấu trúc dữ liệu tiền đị nh của ngôn ngữ lập trình được sử d ụ ng đều đáp ứng được mọi yêu cầu cần thiết về cấu trúc. 1.3. Các phương pháp thiết kế giải thuật 1.3.1. Modul hoá Các bài toán giải được trên máy tính điện tử ngày càng đa dạng và phức tạp. Các giải thuật và chương trình để giải chúng cũng ngày càng có quy mô lớn và càng khó khi thiết lập cũng như khi muốn tìm hiểu. Tuy nhiên, ta cũng thấy rằng mọi việc sẽ đơn giản hơn nếu như có thê phân chia bài toán lớn của ta thành các bài toán nhỏ. Điều đó cũng có nghĩa là nếu coi bài toán của ta như một mô-đun chính thì cần chia nó thành các mô-đun con, mỗi mô-đun này lại được phân chia tiếp cho tới những mô-đun ứng với các phần việc cơ bản mà ta đã biết cách giải quyết. Như vậy việc tổ chức lời giải của bài toán sẽ được thể hiện theo một cấu trúc phân cấp. Chiến thuật giải quyết bài toán là chiến thuật "chia để tr ị" (divide and conquer). Để thể hiện chiến thuật đó, người ta dùng cách thiết kế "từ đỉnh xuống" (top-down design). Đó là cách phân tích tổng quát toàn bộ vấn đề, xuất phát từ dữ kiện và các m ụ c tiêu đặt ra, để đề cập đến nhũng công việc chú yếu, rổi sau đó mới đi dần vào giải quyết các phần cụ thể một cách chi tiết hơn. Cũng vì vậy mà người ta gọi là cách thiết kế từ khái quát đến chi tiết. 1.3.2. Tinh chỉnh từng bước Tinh chỉnh từng bước là phương pháp thiết kế giải thuật gắn liền với lập trình. Nó phản ánh tinh thần của quá trình mô-đun hoá bài toán và thiết kế kiểu top-down. Thoạt đầu chương trình thể hiện giải thuật được trình bày bằng ngôn ngữ tự nhiên phản ánh ý chính của công việc cần làm. Từ các bước sau, những lời, những ý đó sẽ được chi tiết hoá dần dần tương ứng với những công việc nhỏ hơn. Ta gọi đó là các bước tinh

10

2.{Chọn số nhỏ nhất} j =i; for (int k =j+1, k ≤ n, k++) if ( A[k] < A[j] ) j = k; {Đổi chỗ} B = A[i]; A[i]= A[j]; A[j] = B; } 1.4. Phân tích giải thuật 1.4.1. Đặt vấn đề Khi ta đã xây dựng được giải thuật và chương trình tương ứng để giải một bài toán, thì có thể có hàng loạt yêu cầu về phân tích được đặt ra như sau: Về tính đúng đắn của giải thuật: liệu nó có thể hiện được đúng lời giải của bài toán hay không? Thông thường, người ta có thể cài đặt chương trình thể hiện giải thuật đó trên máy tính và thử nghiệm nó nhờ một số bộ dữ liệu nào đó, rồi so sánh kết quả thử nghiệm với kết quả mà ta đã biết là đúng hay sai. Tuy nhiên cách thử này chỉ phát hiện được tính sai chứ chưa thể đảm bảo được tính đúng đắn của giải thuật. Với các công cụ toán học, người ta có thể chứng minh được tính đúng đắn của giải thuật nhưng công việc này là khá khó khăn. Về tính đơn giản của giải thuật : Thông thường ta vẫn mong muốn có được một giải thuật đơn giản, nghĩa là dễ hiểu, dễ lập trình, dễ chỉnh lý. Nhưng cách đơn giản để giải quyết một bài toán chưa hẳn là cách tốt nhất, nó thường gây ra một phí tổn về thời gian hoặc bộ nhớ khi thực hiện. Đối với chương trình chỉ để dùng một vài lần thì tính đơn giản này cần được coi trọng, tuy nhiên nếu chương trình sẽ được sử d ụ ng nhiều lần, nhất là đối với loại bài toán mà khối lượng dữ liệu đưa vào khá lớn (quản lý ngân hàng, bưu điện, nhân sự, …) thì thời gian thực hiện rõ ràng phải được coi trọng. Lúc đó yêu cầu đặt ra lại là tốc độ, là tài nguyên hệ thống, … 1.4.2. Thời gian thực hiện giải thuật Có hai cách tiểp cận đế đánh giá thời gian thực hiện của một giải thuật 1.4.2.1. Phương pháp thực nghiệm Với cách tiếp cận thực nghiệm chúng ta có thể cài đặt thuật toán và cho chạy chương trình trên một máy tính nào đó với một số dữ liệu vào. Thời gian chạy mà ta thu được sẽ phụ thuộc vào nhiều nhân tố:

  • Dữ liệu đầu vào
  • Chương trình dị ch, để chuyển chương trình mã nguồn thành chương trình mã máy.
  • Tổc độ thực hiện các phép toán cùa mảy tính được sừ dụ ng để chạy chương trình.
  • Độ phức tạp về thời gian của thuật toán

11 Vì vậy, trong cách tiếp cận thực nghiệm, ta không thể nói thời gian chạy của thuật toán là bao nhiêu đơn vị thời gian. Một cách tiếp cận khác để đánh giá thời gian chạy của thuật toán là phương pháp phân tích sử d ụ ng các công cụ toán học. 1.4.2.2. Phương pháp lý thuyết Ta sẽ coi thời gian thực hiện của giải thuật như là một hàm số của kích thước dữ liệu vào. Kích thước cùa dữ liệu vào là một tham số đặc trưng cho dữ liệu vào, nó có ảnh hưởng quyết đị nh đến thời gian thực hiện chương trình. Đơn v ị tính kích thước của dữ liệu vào phụ thuộc vào các giải thuật cụ thể. Ví dụ , trong thuật toán tính đị nh thức của ma trận vuông cấp n, ta có thể chọn cỡ của dữ liệu vào là cấp n của ma trận; còn đối với thuật toán sắp xếp mảng cỡ n thì cỡ của dữ liệu vào chính là cỡ n của mảng. Nói chung, cỡ của dữ liệu càng lớn thì thời gian thực hiện thuật toán càng lớn. Nhưng thời gian thực hiện thuật toán không chỉ phụ thuộc vào cỡ của dữ liệu vào mà còn phụ thuộc vào chính dữ liệu vào. Trong số các dữ liệu vào cùng một cỡ, thời gian chạy của thuật toán cũng thay đổi. Thông thường dữ liệu vào là một số nguyên dương n. Ta sẽ sử d ụ ng hàm số T(n), trong đó n là kích thước dữ liệu vào, để biểu diễn thời gian thực hiện cùa một giài thuật. Có thể xác đị nh thời gian thực hiện T(n) là sổ phép toán sơ cấp càn phải tiến hành khi thực hiện giái thuật. Các phép toán sơ cấp là các phép toán mà thời gian thực hiện bị chặn trên bởi một hằng số chỉ phụ thuộc vào cách cài đặt được sừ dụ ng. Chắng hạn các phép toán số học /, các phép toán so sánh !=,... là các phép toán sơ cấp. 1.4.2.3. Biểu diễn thời gian chạy của thuật toán Khi đánh giá thời gian thực hiện bằng phương pháp toán học, chúng ta sẽ bò qua yếu tố phụ thuộc vào cách cài đặt, chỉ tập trung vào xác đị nh độ lớn cùa thời gian thực hiện T(n). Ký hiệu toán học O (đọc là ô lớn) được sử d ụ ng để mô tả độ lớn của hàm T(n). T(n) = O(f(n)), biểu diễn này có nghĩa là thời gian chạy T(n) bị chặn trên bởi hàm f(n). Thế nhưng một hàm có vô số cận trên. Trong số các cận trên của thời gian chạy, chúng ta sẽ lấy cận trên chặt để biểu diễn thời gian chạy của thuật toán. Đị nh nghĩa. Ta nói f(n) là cận trên chặt của T(n) nếu

  • T(n) = O(f(n)), và
  • Nếu T(n) = O(g(n)) thì f(n) = O(g(n)). Nói một cách khác, f(n) là cận trên chặt của T(n) nếu nó là cận trên của T(n) và ta không thể tìm được một hàm g(n) là cận trên của T(n) mà lại tăng chậm hơn hàm f(n). Sau này khi nói thời gian chạy của thuật toán là O(f(n)), chúng ta cần hiểu f(n) là cận trên chặt của thời gian chạy. Nếu T(n) = O(1) thì điều này có nghĩa là thời gian chạy của thuật toán bị chặn trên bởi một hằng số nào đó, và ta thường nói thuật toán có thời gian chạy hằng.