*Nắm vững khái niệm về kiễu dữ liệu tĩnh và động*Nắm vững cách tổ chức dữ liệu động bằng danh sách liên kết và minh họa được các thao tác xử lý trên danh sách liên kết đơn *Cài đặt minh
Trang 1Chương 3 Cấu trúc dữ liệu động
Trang 2*Nắm vững khái niệm về kiễu dữ liệu tĩnh và động
*Nắm vững cách tổ chức dữ liệu động bằng danh sách liên kết và minh họa được các thao tác xử
lý trên danh sách liên kết đơn
*Cài đặt minh họa được các thao tác của danh sách đơn bằng ngôn ngữ C/ C++
Trang 3*Cho một mảng có N=8 phần tử
*Làm sao để chèn thêm số 6 vào mảng tại vị trí 5
Trang 5*Hãy cài đặt hàm (bằng ngôn ngữ C/C++) chèn một phần tử có giá trị x vào một mảng số nguyên a, kích thước n (có thứ tự tăng dần) sao cho mảng a vẫn có thứ tự tăng dần, theo mẫu hàm như sau:
void ChenX(int a[], int n, int x, int vt);
Trang 6*Làm sao để xóa phần tử 9 ?
Trang 7*Làm sao để xóa phần tử 9 ?
Trang 8*Hãy cài đặt hàm (bằng ngôn ngữ C/C++) xóa phần tử có giá trị x (nếu có) trong mảng số nguyên a, kích thước n (giả sử giá trị các phần
tử trong mảng không trùng nhau), theo mẫu hàm như sau:
void XoaX(int a[], int &n, int x);
Trang 9Độ phức tạp của chèn/ xóa trên mảng 1 chiều là O(n)
Trang 10*Giải quyết vấn đề phức tạp khi chèn/ xóa?
*Giải quyết vấn đề giới hạn kích thước vùng nhớ tối đa?
*Giải quyết vấn đề vùng nhớ không liên tục?
*Giải quyết vấn đề giải phóng vùng nhớ khi không cần dùng đến?
DÙNG CẤU TRÚC DỮ LIỆU ĐỘNG
Trang 11*Biến tĩnh
<kiểu dữ liệu> tên biến;
Vd: int a; float y; char s[20];
Tồn tại trong phạm vi khai báo
Được cấp phát vùng nhớ trong vùng dữ liệu
Kích thước cố định
Trang 12*Biến động
<kiểu dữ liệu> *tên biến;
Vd: int *a; float *y;
Chứa địa chỉ của một đối tượng dữ liệu
Được cấp phát hoặc giải phóng bộ nhớ tùy
thuộc vào người lập trình
Kích thước có thể thay đổi
Trang 14* Giới thiệu cấu trúc “Danh sách liên kết”
1
7 2 6
3 10 8 5 9 4
Các phần tử kết dính với nhau bằng
“sợi dây liên kết”
Trang 16*Một dãy tuần tự các nút (Node)
*Giữa hai nút có con trỏ liên kết
*Các nút không cần phải lưu trữ liên tiếp nhau trong bộ nhớ
*Có thể mở rộng tuỳ ý (chỉ giới hạn bởi dung lượng bộ nhớ)
*Thao tác Chèn/Xóa không cần phải dịch chuyển phần tử mà chỉ cần thay đổi mối liên kết
*Quản lý phần tử đầu tiên bằng con trỏ pHead
*Có thể truy xuất đến các phần tử khác thông qua con trỏ liên kết
Trang 17pHead pTail
List
Trang 18*Quản lý toàn bộ danh sách liên kết thông qua con trỏ đầu pHead
*pHead không phải là 1 nút, nó chỉ là “con trỏ chỉ đến nút” mà thôi
*Ta cũng có thể quản lý danh sách bằng cách sử dụng thêm con trỏ cuối (pTail)
*pTail không phải là 1 nút, nó chỉ là “con trỏ
chỉ đến nút” mà thôi
Trang 20*“Kết nối” lại sợi dây liên kết theo trình tự
pHead pTail
List
Trang 21pHead pTail
List
Trang 22*Danh sách liên kết đơn: Các phần tử kết nối với nhau theo hướng “chiều đi tới”
Trang 23* Danh sách liên kết đôi: Các phần tử kết nối với nhau theo hướng “chiều đi tới và và đi lui”
Trang 24*Danh sách liên kết vòng: Các phần tử kết nối với nhau theo hướng “chiều đi tới” và phần tử cuối cùng có “đường đi vòng trở lại tới” phần
tử đầu danh sách
Trang 26Cấu trúc 1 node
Data pNext
Data : Dữ liệu của node pNext : Con trỏ đến node kế tiếp pHead: Con trỏ đến node đầu pTail: Con trỏ đến node cuối
pHead pTail
List
Trang 27struct tNODE
{
<kiểu dữ liệu> Data ; struct tNODE *pNext ; };
typedef struct tNODE NODE ;
Data
pNext
Trang 28struct tNODE
{
int Data ; struct tNODE *pNext ; };
typedef struct tNODE NODE ;
20 pNext
Trang 29struct tNODE
{
SINHVIEN Data ; struct tNODE *pNext ; };
typedef struct tNODE NODE ;
typedef struct tSinhVien SINHVIEN;
ID, hoten, dtb pNext
Trang 31*Tạo lập danh sách rỗng
*Kiểm tra danh sách rỗng
*Thêm 1 nút vào danh sách
*Xóa 1 nút
*Duyệt danh sách
*Tìm 1 phần tử
*Sắp xếp danh sách
Trang 32Khai báo thư viện hàm1
Khai báo cấu trúc danh sách liên kết2
Khai báo các nguyên mẫu hàm
3
void main()
{
Tạo lập danh sách rỗng Nhập dữ liệu vào danh sách Các thao tác xử lý trên danh sách
Hủy danh sách }
4
Cài đặt các hàm con5
Trang 33void CreateEmptyList(LIST &list)
?pTail
(rỗng)
Trang 34bool IsEmptyList(LIST list)
Trang 36* Nếu danh sách đã có nút
pHead pTail
pNew
Có 2 trường hợp để thêm pNew
1.Thêm pNew vào đầu (AddHead)
2.Thêm pNew vào cuối (AddTail)
Trang 37pHead pTail
pNew
pNew->pNext = list.pHeadlist.pHead = pNew
1 2
1
2
Trang 40Hãy viết hàm thêm phần tử pNew vào đầu danh sách (bằng ngôn ngữ C/C++), theo mẫu sau:
void AddHead(LIST &list, NODE
*pNew)
Trang 41pHead pTail
pNew
list.pTail->pNext = pNewlist.pTail = pNew
1
1
2
2
Trang 43Hãy viết hàm thêm phần tử pNew vào cuối danh sách (bằng ngôn ngữ C/C++),
theo mẫu sau:
void AddTail (LIST &list, NODE
*pNew)
Trang 44Nhập dữ liệu cho node
Tạo con trỏ node
Thêm node vào danh sách
Trang 45Để tạo node mới từ dữ liệu x có sẵn
*Đưa dữ liệu có giá trị x vào phần Data
*Con trỏ pNext trỏ đến NULL
Data
pNew
x pNew->pNext = pNew->Data = xNULL
Trang 46Ví dụ hàm tạo và trả về con trỏ node có chứa giá trị nguyên x bằng ngôn ngữ C++
NODE *CreateNode (int x)
{
NODE *p;
p = new NODE;
if(p == NULL) {
cout<<“Loi cap phat duoc vung nho!";
exit(0);
} p->Data = x;
p->pNext=NULL;
return p;
}
Trang 47Ví dụ hàm nhập dữ liệu cho danh sách số nguyên
và đưa vào đầu danh sách
void Input(LIST &list)
Trang 48*Xóa nút đầu của danh sách Ảnh hưởng pHead
*Xóa nút cuối của danh sách Ảnh hưởng pTail
*Xóa nút giữa
Trang 49*Xóa nút đầu của danh sách
Trang 50Hãy viết hàm xóa nút đầu của danh sách
(bằng ngôn ngữ C/C++), theo mẫu sau: void DeleteHead (LIST &list)
(lưu ý trường hợp danh sách chỉ còn 1
node trước khi xóa)
Trang 51*Xóa nút cuối của danh sách
pHead pTail
Cần xóa
pDel
NODE *pDel = list.pTail
NODE *pPrev = “Tìm node trước pTail”
delete pDel
pPrev
list.pTail = pPrev
pPrev->pNext = NULL
Trang 52Hãy viết hàm tìm và trả về con trỏ node
đứng trước con trỏ node p(bằng ngôn ngữ
C/C++), theo mẫu sau:
NODE *PrevNode (LIST list, NODE
*p)
Trang 53Hãy viết hàm xóa nút cuối của danh sách
(bằng ngôn ngữ C/C++), theo mẫu sau: void DeleteTail (LIST &list)
(lưu ý trường hợp danh sách chỉ còn 1
node trước khi xóa)
Trang 54*Xóa nút giữa của danh sách
pHead pTail
Cần xóa pDel
NODE *pPrev = “Tìm node trước pDel”
delete pDel
pPrev
pPrev->pNext = pDel->pNext
96
Trang 55Hãy viết hàm xóa một node bất kỳ trong
danh sách (bằng ngôn ngữ C/C++), theo mẫu sau:
void DeleteNode (LIST &list, NODE
*pDel)
Trang 56Hãy viết hàm hủy toàn bộ danh sách
(bằng ngôn ngữ C/C++), theo mẫu sau: void DestroyList (LIST &list)