1. Trang chủ
  2. » Giáo án - Bài giảng

Bài giảng Cấu trúc dữ liệu và Giải thuật

252 280 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 252
Dung lượng 15,68 MB
File đính kèm BaiGiang_CauTrucDLGT.rar (15 MB)

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

BÀI 1.TỔNG QUAN VỀ GIẢI THUẬT VÀ CẤU TRÚC DỮ LIỆU121.Thuật Toán122.Một số quy ước133.Độ Phức Tạp Của Thuật Toán14BÀI 2. DANH SÁCH ĐẶC (MẢNG – ARRAY LIST)191.Khái niệm:192.Các thao tác xử lí trên mảng193.Ưu khuyết điểm của mảng25BÀI 3. DANH SÁCH LIÊN KẾT (LIST)271.Danh sách liên kết đơn271.1.Khái niệm:271.2.Các thao tác xử lí cơ bản trên DSLK291.3.Ưu khuyết điểm của DSLK482.Danh sách liên kết kép (double list)482.1.Khái niệm:482.2.Các thao tác xử lí cơ bản trên DSLK kép503.Danh sách liên kết vòng (circular list)503.1.Khái niệm danh sách liên kết vòng:503.2.Các thao tác xử lí cơ bản trên DSLK vòng50BÀI 4. STACK – QUEUE (Ngăn Xếp – Hàng Đợi)511.Stack511.1.Khái niệm511.2.Stack (Danh sách đặc)521.2.1.Các thao tác xử lý trên stack521.3.Stack (Danh sách liên kết)561.4.Ứng dụng562.Queue592.1.Khái niệm:592.2.Queue (Danh sách đặc)602.2.1.Các thao tác xử lý trên queue602.2.2.Hàng đợi vòng (Circular Queue)652.3.Dùng danh sách liên kết tạo queue702.4.Ứng dụng70BÀI 5. ĐỆ QUI (Recursion)711.Khái quát về đệ qui712.Thi hành hàm tính giai thừa723.Phân loại đệ qui734.Khử đệ qui785.Bài toán tháp Hà Nội81BÀI 6. TÌM KIẾM – SẮP XẾP (Search Sort)831.Tìm Kiếm (Search)831.1.Tìm kiếm tuyến tính841.2.Tìm kiếm nhị phân( Binary Search)862.Sắp xếp (Sort)892.1.Đổi chỗ trực tiếp – Interchange Sort892.2.Nổi bọt – Bubble Sort942.3.Chọn trực tiếp – Selection Sort982.4.Chèn trực tiếp – Insertion Sort1002.5.Chèn nhị phân – Binary Insertion Sort1032.6.Shaker Sort1042.7.Shell Sort1092.8.Heap Sort1132.9.Quick Sort1182.10.Merge Sort1232.11.Radix Sort ( Sắp xếp theo cơ số)1292.12.Sắp xếp ngoại (External Sort)139BÀI 7. CÂY (TREE) CÂY NHỊ PHÂN (BINARY TREE) CÂY NHỊ PHÂN TÌM KIẾM (BINARY SEARCH TREE) CÂY NHỊ PHÂN CÂN BẰNG AVL (ADELSON – VELSKII – LANDIS)1431.Cây (Tree)1432.Cây nhị phân1453.Cây Nhị Phân Tìm Kiếm (Binary Search Tree)1614.Cây Nhị Phân (tìm kiếm) Cân Bằng AVL (Adelson – Velskii – Landis)1715.Cây đỏ đen (red black tree)1856.Cây tập hợp1867.Cây biểu thức187BÀI 8. BẢNG BĂM (Hash Function Hash Table)1891.Hàm băm (Hash Function) Bảng băm (Hash Table)1892.Giải quyết sự đụng độ trên bảng băm191BÀI 9. ĐỒ THỊ (Graph)1941.Các khái niệm cơ bản1942.Đồ thị Euler và đồ thị Hamilton2033.Biểu diễn đồ thị2044.Các thao tác trên đồ thị2085.Cây2196.Tô màu đồ thị2257.Topological Sorting226TÀI LIỆU THAM KHẢO228

Trang 1

BỘ NÔNG NGHIỆP VÀ PHÁT TRIỂN NÔNG THÔN

TRƯỜNG CAO ĐẲNG NGHỀ CÔNG NGHỆ VÀ NÔNG LÂM NAM BỘ

KHOA CÔNG NGHỆ THÔNG TIN

Địa chỉ: QL 1K, Phường Bình An, TX Dĩ An, Tỉnh Bình

Dương Email: it.svoctaf@gmail.com

Trang 2

Bài 1.

TỔNG QUAN VỀ GIẢI THUẬT VÀ CẤU TRÚC DỮ

LIỆU

1 Thuật Toán

Một dãy hữu hạn các chỉ thị có thể thi hành để đạt mục tiêu đề ra

Ví dụ: Thuật toán tính tổng tất cả các số nguyên dương nhỏ hơn n:

Bước 1: S=0, i=0;

Bước 2: nếu i<n thì s=s+i;

Ngược lại: qua bước 4;

Biểu Diễn Bằng Mã Giả

» Ngôn ngữ tựa ngôn ngữ lập trình:

Trang 3

3 Độ Phức Tạp Của Thuật Toán

Một thuật toán hiệu quả:

Trang 4

 Thời gian sử dụng CPU thấp, …

Phân tích độ phức tạp thuật toán:

 Phương pháp thực nghiệm

 Phương pháp xấp xỉ toán học

Phương Pháp Thực Nghiệm

• Cài thuật toán rồi chọn các bộ dữ liệu thử nghiệm

• Thống kê các thông số nhận được khi chạy các bộ dữ liệu đó

Ưu điểm: Dễ thực hiện.

Nhược điểm:

 Chịu sự hạn chế của ngôn ngữ lập trình

 Ảnh hưởng bởi trình độ của người lập trình

 Chọn được các bộ dữ liệu thử đặc trưng cho tất cả tập các dữ liệu vào củathuật toán: khó khăn và tốn nhiều chi phí

 Phụ thuộc vào phần cứng

Phương Pháp Xấp Xỉ

• Đánh giá giá thuật toán theo hướng xấp xỉ qua các khái niệm O()

Ưu điểm: Ít phụ thuộc môi trường cũng như phần cứng hơn.

Nhược điểm: Phức tạp.

• Các trường hợp độ phức tạp quan tâm:

Đơn vị đo thời gian thực hiện:

Đơn vị của T(n) không phải là đơn vị đo thời gian bình thường như giờ, phút giây mà thường được xác định bởi số các lệnh được thực hiện trong một máy tính lý tưởng

- Trường hợp tốt nhất (phân tích chính xác)

- Trường hợp xấu nhất (phân tích chính xác)

- Trường hợp trung bình (mang tích dự đoán)

Trang 5

Cách tính độ phức tạp:

Gồm có qui tắc cộng, qui tắc nhân, qui tắc tổng quát để phân tích một chươngtrình, độ phức tạp của chương trình có gọi chương trình con không đệ qui, độ phức tạpcủa chương trình có đệ qui

Qui tắc cộng:

Nếu T1(n) và T2(n) là thời gian thực hiện của hai đoạn chương trình P1 và P2;

và T1(n)=O(f(n)), T2(n)=O(g(n) thì thời gian thực hiện của đoạn hai chương trình

đó nối tiếp nhau là T(n)=O(max(f(n),g(n)))

Ví dụ:

- Lệnh gán x:=15 có O(1)

- Lệnh đọc dữ liệu READ(x) có O(1)

Vậy thời gian thực hiện cả hai lệnh trên nối tiếp nhau là O(max(1,1))=O(1)

Qui tắc nhân:

Nếu T1(n) và T2(n) là thời gian thực hiện của hai đoạn chương trình P1và P2 và

T1(n) = O(f(n)), T2(n) = O(g(n)) thì thời gian thực hiện của đoạn hai đoạn chương

trình đó lồng nhau là T(n) = O(f(n).g(n))

Qui tắc tổng quát để phân tích một chương trình:

-Thời gian thực hiện của mỗi lệnh gán, READ, WRITE là O(1)

- Thời gian thực hiện của một chuỗi tuần tự các lệnh được xác định bằng qui tắc cộng.Như vậy thời gian này là thời gian thi hành một lệnh nào đó lâu nhất trong chuỗi lệnh

- Thời gian thực hiện cấu trúc IF là thời gian lớn nhất thực hiện lệnh sau THEN hoặcsau ELSE cộng với thời gian kiểm tra điều kiện Thường thời gian kiểm tra điều kiện làO(1)

- Thời gian thực hiện vòng lặp:Thời gian thực hiện vòng lặp là tổng (tất cả các lần lặp)thời gian thực hiện thân vòng lặp Nếu thời gian thực hiện thân vòng lặp không đổi thìthời gian thực hiện vòng lặp là tích của số lần lặp với thời gian thực hiện thân vòng lặp

Ví dụ: Tính thời gian thực hiện của đoạn chương trình

procedure Bubble (var a: array[1 n] of integer);

var i,j,temp: integer;

begin

{1} for i:=1 to n-1 do

{2} for j:=n downto i+1 do

{3} if a[j-1]>a[j] then begin

Trang 6

{4} temp:=a[j-1];

{5} a[j-1]:=a[j];

{6} a[j]:=temp; end;

end;

- Cả ba lệnh đổi chỗ {4} {5} {6} tốn O(1) thời gian, do đó lệnh {3} tốn O(1).

- Vòng lặp {2} thực hiện (n-i) lần, mỗi lần O(1) do đó vòng lặp {2} tốn

O((n-i).1)=O(n-i).

- Vòng lặp {1} lặp (n-1) lần vậy độ phức tạp của giải thuật là:

Độ phức tạp của chương trình có gọi chương trình con không đệ qui

Giả sử ta có một chương trình gọi các chương trình con theo sơ đồ sau:

Chương trình A gọi hai chương trình con là B và C, chương trình B gọi hai

chương trình con là B1 và B2, chương trình B1 gọi hai chương trình con là B11 và B12 Để tính thời gian thực hiện của A, ta tính theo các bước sau:

-Tính thời gian thực hiện của C, B2, B11 và B12

-Tính thời gian thực hiện của B1

-Tính thời gian thực hiện của B

-Tính thời gian thực hiện của A

Phân tích các chương trình đệ quy

Có ba phương pháp giải phương trình đệ quy:

- Phương pháp truy hồi

Thành lập phương trình đệ quy rồi giải phương trình đệ

quy

Trang 7

- Phương pháp đoán nghiệm.

- Lời giải tổng quát của lớp các phương trình đệ quy

Trang 9

Trình tự thực hiện

1 Tạo phương thức khoi_tao

void khoi_tao(int a[], int n){

}

Dùng hàm không kiểu, đối số là mảng 1 chiều, biến n là số phần

tử trong mảng

2 Mã hóa thân phương thức

for(int i=0;i<n;i++){

printf(“Phan tu thu[ %d]: \n”, i);

scanf(“%d”,&a[i])

;}

Biến chạy i, câu lệnh lặp, hàm xuất printf, hàm nhập scanf

Xuất mảng

Duyệt tất cả các phần tử có được trong mảng một chiều

void khoi_tao(int a[], int n)

{

for(int i=0;i<n;i++)

{

Trang 10

Trình tự thực hiện

1 Tạo phương thức duyệt

mảng xuat. void xuat(int a[],int n)

{}

Dùng hàm không kiểu, đối số là mảng 1 chiều, biến n là số phần

Trang 11

Dùng hàm không kiểu, đối số là mảng 1 chiều, biến n là số phần

tử trong mảng

2 Mã hóa thân phương thức

int x, k;

printf(“Phan tu can chen:\n”);

Xóa một phần tử của mảng

void xoa(int a[], int &n)

{

int k;

Trang 12

Trình tự thực hiện

1 Tạo phương thức xóa

mảng xoa. void xoa(int a[], int &n)

{}

Dùng hàm không kiểu, đối số là mảng 1 chiều, biến n là số phần

Tìm kiếm một phần tử trong mảng (while)

12

Nếu xóa một phần tử tại vị trí thứ k(0 ≤ k < n) thì các phần tử từ a[k+1] đến a[n-1] được dichuyển về trước một vị trí

Tìm xem phần tử x đầu tiên có nằm trong mảng

a kích thước n hay không?

Trang 13

Dùng hàm có kiểu dữ liệu trả

về , đối số là mảng 1 chiều, biến n là số phần

tử trong mảng và giâ trị tìm kiếm x

2 Mã hóa thân phương thức

else

Biến chạy i, câu lệnh lặp while, câu lệnh điều kiện if

Trang 14

Dùng hàm có kiểu dữ liệu trả

về , đối số là mảng 1 chiều, biến n là số phần

tử trong mảng và giâ trị tìm kiếm x

2 Mã hóa thân phương thức

for (int i = 0; i < n; i++)

if (a[i] == x) return i;

Biến chạy i, câu lệnh lặp for, câu lệnh điều kiện if

int TimKiem_for(int a[], int n, int x)

Trang 15

return -1;

Sắp xếp mảng thành tăng dần

Trình tự thực hiện

1 Tạo phương thức SapXep

void SapXep(int a[], int n) {

}

Dùng hàm không

có kiểu dữ liệu trả về , đối số là mảng 1 chiều, biến n là số phần

Trang 16

2 Mã hóa thân phương thức

for (int i = 0; i < n – 1; i++) {

for (int j = i + 1; j < n; j++) {

if (a[i] > a[j]) // “<“ neu sap xep giam

HoanVi(a[i], a[j]);

Biến chạy i, câu lệnh lặp ngoài, câu lệnh lặp lồng,câu lệnh điều kiện if và thủ tục hoán vị

3 Ưu - khuyết điểm của mảng

Ưu điểm :

 Dễ cài đặt và truy xuất các phần tử dữ liệu

 Có khả năng truy xuất ngẫu nhiên

Khuyết điểm:

Trước khi sử dụng cần phải xác định trước số phần tử mảng Không phù hợp

cho các bài toán có số lượng phần tử thay đổi

 Khó khăn trong các thao tác chèn và xóa một

phần tử bất kỳ trong mảng

(*) Cài đặt và chạy chương trình

Trang 17

Bài 3.

DANH SÁCH LIÊN KẾT (LIST)

1. Danh sách liên kết đơn

Trang 18

Cấu trúc dữ liệu (CTDL) của 1 nút

Trình tự thực hiện

1 Tạo cấu trúc Node

struct Node {

};

Dùng cấu trúcstruct

2 Thành phần cấu trúc

int key;

Node *next;

Thành phần dữliệu và thànhphần con trỏ

Trang 19

Trình tự thực hiện

1 Tạo cấu trúc danh sách

{ };

Dùng cấu trúcstruct

2 Thành phần cấu trúc

Node *head, *tail; Dùng 2 thànhphần con trỏ đầu

và cuối

1.2 Các thao tác xử lí cơ bản trên DSLK

Khởi tạo danh sách

Trình tự thực hiện

void Initial( List &l) {

l.head = l.tail = NULL;

Trang 20

{ }

trả về , đối số là một danh sách liên kết

2 Mã hóa thân phương thức

l.head = l.tail = NULL; Dùng con trỏ đầu,con trỏ cuối

Kiểm tra danh sách có rỗng hay không

Trình tự thực hiện

1 Tạo phương thức isEmpty

int isEmpty(List l) {

}

Dùng hàm có kiểu dữ liệu trả

về , đối số là một danh sách liên kết

2 Mã hóa thân phương thức

return (l.head==NULL); Dùng con trỏ đầu.int isEmpty(List l)

{

Trang 21

Thêm 1 nút vào đầu danh sách

void Head_Insert (List &l, int x)

Trang 22

l.head= p;

l.tail= p;

}

Dùng toán tử new, con trỏ đầu, con trỏ cuối, biến con trỏ tạm p

3 Khi danh sách liên kết

không rỗng p->next= l.head;

l.head= p;

Dùng toán tử new, con trỏ đầu, biến con trỏ tạm p

Thêm 1 nút vào cuối danh sách

Trang 23

void Tail_Insert (List &l, int x)

Trang 24

l.head = l.tail= p;

}

Dùng toán tử new, con trỏ đầu, con trỏ cuối, biến con trỏ tạm p

3 Khi danh sách liên kết không rỗng l.tail->next= p;

l.tail= p;

Dùng toán tử new, con trỏ cuối,biến con trỏ tạm p

Thêm một phần tử vào sau một phần tử được trỏ bởi q

Trang 25

Dùng hàm không

có kiểu dữ liệu trả về , đối số là một danh sách liên kết, giá trị chèn, con trỏ phụ

2 Khi danh sách liên kết

rỗng p->key= x;

p->next= NULL;

if(isEmpty(l)) {

l.head= l.tail= p;

}

Dùng toán tử new, con trỏ đầu, con trỏ cuối, biến con trỏ tạm p

3 Khi danh sách liên kết

không rỗng p->next=q->next; Dùng toán tử new, con trỏ cuối,

biến con trỏ tạm

Trang 26

if(q==l.tail) // nut q

la nut taill.tail= p; //cap nhatlai tail

Thêm một phần tử vào sau một phần tử có khóa k

void Insert_After_K (List &l, int k, int x)

{

Node *p;

for( p=l.head; p!= NULL; p=p->next)

Khi DSLK rỗng hay không rỗng

Trang 27

Dùng hàm không

có kiểu dữ liệu trả về , đối số là một danh sách liên kết, giá trị chèn, giá trị phụ k

Tạo danh sách liên kết

void Build_List (List &l)

{

int x;

char tiep;

do

Trang 28

Dùng hàm không

có kiểu dữ liệu trả về , đối số là một danh sách liên kết

printf(“ Muon nhap lieu cho

Dùng chuỗi phụ tiếp, vòng lặp, hàm nhập xuất printf, scanf, hàmtiếp nhận kí tự getch(), thủ tục chèn đầu

- Xây dựng DSLK dựa trên các thao tác chèn: Chèn đầu hoặc chèn cuối hoặc chèn giữa.

- Số lượng phần tử danh sách phụ thuộc vào biến “tiep”.

Kết nối từng node danh sách

Trang 29

danh sach nua khong?\n”); tiep= getch();

} while((tiep==‘Y’)||(tiep==‘y’));

In (duyệt) danh sách (DSLK) ra màn hình

TH: DSLK rỗng

TH: DSLK không rỗng

(Kĩ thuật: Dùng p làm con trỏ chạy lần lượt

void Print( List l) {

if (isEmpty(l)) {

if(isEmpty(l))

printf(“ DSLK rong”);

}

Trang 30

Trình tự thực hiện

TIỆN

1 Tạo phương thức Print

void Print( List l) {

}

Dùng hàm không có kiểu

dữ liệu trả về , đối số là một danh sách liên kết

2 Khi danh sách liên kết

printf(“ DSLK rong”);

Dùng hàm kiểmtra rỗng, lệnh xuất

3 Khi danh sách liên kết

while(p!=NULL) {

printf(“Gia tri khoa: %d\n”, p->key);

p=p->next;

Dùng con trỏ đầu, con trỏ tạm p

Trang 31

- Khi DSLK không rỗng (Trong trường

void Head_Delete(List &l)

Trang 32

1 Tạo phương thức

Head_Delete void Head_Delete(List &l)

{ }

Dùng hàm không

có kiểu dữ liệu trả về , đối số là một danh sách liên kết

2 Khi danh sách liên kết

return;

Dùng hàm kiểm tra rỗng

3 Khi danh sách liên kết

l.head=l.head->next;

p->next=NULL;

if(l.head==NULL)l.tail= NULL;

delete p;

Dùng con trỏ đầu,cuối, con trỏ tạm p

Xóa 1 nút ở cuối danh sách

Trang 33

2 Khi danh sách liên kết

return;

Dùng hàm kiểm tra rỗng

Có 2 trường hợp:

- Khi DSLK rỗng

- Khi DSLK không rỗng (Trong trường

hợp này nếu DSLK chỉ có một nút thì ta xóa riêng)

void Tail_Delete(List &l)

Trang 34

3 Khi danh sách liên kết

delete p;

l.head=l.tail=NULL;

}

Dùng con trỏ đầu,cuối, con trỏ tạm

l.tail=p;

p->next=NULL;

delete q;

Dùng con trỏ cuối, con trỏ tạm

Trang 35

Trình tự thực hiện

TT

BƯỚC

PHƯƠNGTIỆN

1 Tạo phươngthức

Delete_After

void Delete_After(List &l, Node *q)

{ }

Dùng hàm không có kiểu dữ liệu trả về, đối số là một danh

void Delete_After(List &l, Node *q)

Trang 36

kết, con trỏ q.

Dùng hàm kiểm tra rỗng

3 Khi danh

sách liên kết

không rỗng

if(q!=NULL){

p=q->next; // p nut can xoaif(p!=NULL)

Dùng con trỏ cuối, con trỏ tạm p, q, toán tử delete

Xóa 1 nút có khóa k

Trang 37

- Khóa x được tìm thấy tại nút đầu.

- Khóa x được tìm thấy không phải tại nút đầu

void Delete_K(List &l, int x)

{

Node *p=l.head, *q;

while((p!=NULL)&&(p->key!=x)) {

q=p; p=p->next;

}

Trang 38

{ }

một danh sách liên kết

2 Node cần xóa là node

3 Node cần xóa không phải

là node đầu Node *p=l.head, *q;

while((p!=NULL)&&(p->key!=x)) {

q=p; p=p->next;

} if(l.head->key != x ) {

Delete_After(l, q);

}

Dùng con trỏ đầu, con trỏ tạm

p, q, toán tử delete, phương thức xóa sau

Hủy toàn bộ danh sách

Trang 39

Dùng hàm không

có kiểu dữ liệu trả về , đối số là một danh sách liên kết

2 Khi danh sách liên kêt

return;

Dùng hàm kiểm tra rỗng

3 Khi danh sách liên kết

không rỗng while(l.head!=NULL)

{ Head_Delete(l);

}

Dùng con trỏ đầu,phương thức xóa đầu, vòng lặp

Tìm kiếm phần tử trong DSLK (tìm kiếm tuần tự_Linear Search)

void Delete_List (List &l)

(Lần lượt xóa đầu cho đến khi con trỏ đầu NULL)

Trang 40

Trình tự thực hiện

1 Tạo phương thức Search

Node *Search (List l, int x)

{ }

Dùng hàm có kiểu dữ liệu trả

về , đối số là một danh sách liên kết, giá trị tìm kiếm

2 Khi danh sách liên kêt

return NULL;

Dùng hàm kiểm tra rỗng

TH: DSLK rỗng  Không tìm thấy, nên hàm Searchnhận NULL

Trang 41

3 Khi danh sách liên kết

while ((p!=

NULL)&&(p->key!=

x)){

p=p->next;

} return p;

Dùng con trỏ đầu,vòng lặp, con trỏ tạm p

Sắp xếp các phần tử trong DSLK (tăng dần)

Trình tự thực hiện

1 Tạo phương thức Sort

void Sort (List &l) Dùng hàm không có kiểu dữ liệu

void Sort (List &l)

{

Node *p, *q;

if (isEmpty(l))

return ;

for (p=l.head; p!= l.tail; p=p->next)

for(q=p->next; q!= NULL; q=q->next)

TH:DSLK rỗng Có cần sắp xếp không?TH: DSLK không rỗng

(Kĩ thuật: So sánh lần lượt các cặp phần

Trang 42

{ }

liên kết

2 Khi danh sách liên kêt

if (isEmpty(l)) return ;

Dùng hàm kiểm tra rỗng

3 Khi danh sách liên kết

không rỗng for (p=l.head; p!= l.tail;

p=p->next)

for(q=p->next; q!=

NULL; q=q->next){

p, q, vòng lặp, , lệnh rẽ nhánh, phương thức hoánvị

Đếm phần tử có trong danh sách

TH: DSLK rỗng

TH DSLK không rỗng: Dùng vòng lặp để

đếm

Trang 43

Trình tự thực hiện

1 Tạo phương thức Count

int Count (List l){

}

Dùng hàm có kiểu dữ liệu trả

về , đối số là một danh sách liên kết

2 Khi danh sách liên kêt

int dem=0;

if(isEmpty(l))return 0;

Dùng hàm kiểm tra rỗng

3 Khi danh sách liên kết

không rỗng for( p= l.head; p!

=NULL;p=p-> next)

Dùng con trỏ đầu,vòng lặp, con trỏ

int Count (List l)

{

Node *p;

int dem=0;

if(isEmpty(l)) return 0;

Trang 44

return dem;

Cài đặt và chạy chương trình

1.3 Ưu - khuyết điểm của DSLK

Ưu điểm :

- Phù hợp với các bài toán có các phần tử chưa xác định trước

- Dễ dàng trong việc xóa, chèn các phần tử trong DS (Tính linh động của DSLK).

-Cấp phát bộ nhớ động, sử dụng hiệu quả bộ nhớ.

Khuyết điểm:

- Khó cài đặt và truy nhập đến các phần tử trong DS

- Tốc độ truy nhập của danh sách chậm

2 Danh sách liên kết kép (double list)

2.1 Khái niệm:

Mỗi phần tử liên kết với phần tử đứng trước và sau nó trong danh sách

Ngày đăng: 12/11/2018, 11:15

TỪ KHÓA LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w