Professional Documents
Culture Documents
Chương 4 - LinkedLists
Chương 4 - LinkedLists
6
CHƯƠNG 4
DANH SÁCH LIÊN KẾT 10
15
7 9
5 3 2 1
1 2 3 4 5 6 7 8
Biên soạn: ThS.Phạm Văn Đăng
Email: pvdang@ntt.edu.vn ? Làm sao để chèn thêm số 6 vào vị trí 5 của mảng
Mục tiêu
Vấn đề kiểu dữ liệu tĩnh
Nắm vững khái niệm về kiểu dữ liệu tĩnh
và động 6
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
? Giả sử cần thêm tiếp 1 phần tử
15
10 9
5 7
thao tác xử lý trên danh sách liên kết đơn 3 2 1
1 2 3 4 5 6 7 8 9
Cài đặt minh họa được các thao tác của
danh sách đơn bằng ngôn ngữ Java Bổ sung thêm
2 4
Bài tập Vấn đề kiểu dữ liệu tĩnh
5 7
9 11
13 15
start end
LinkedLists
14 16
Thao tác xóa node khỏi DSLK
Cấu tạo của nút
Cần xóa
Tạo lập bằng cách cấp phát bộ nhớ động
Mỗi nút có 2 thông tin:
Dữ liệu (data)
Nodes liên kết đến phần tử kế tiếp trong
danh sách (Next pointer link): link
Nếu không chỉ đến phần tử nào thì Nodes
Node
link = null
data
start end
link
17
LinkedLists 19
start end
LinkedLists
18 20
So sánh Mảng và DSLK
Các loại hình DSLK
Mảng Danh sách liên kết
DSLK đô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” Số phần tử thay đổi tùy
Kích thước cố định
ý
Các phần tử lưu trữ tuần Các phần tử liên kết với
tự (địa chỉ tăng dần) nhau bằng Nodes liên
trong bộ nhớ kết
Phải dịch chuyển các Chỉ cần thay đổi Nodes
phần tử khi Thêm/Xóa liên kết khi Thêm/Xóa
Truy xuất ngẫu nhiên Truy xuất tuần tự
21
23
DSLK đơn
Các loại hình DSLK
Danh sách liên kết vòng: Các phần tử kết nối link
data
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 Cấu trúc 1 node
Khai báo cấu trúc node lưu số nguyên Khai báo cấu trúc DSLK đơn
link LinkedLists
20
start end
public class Nodes
{ public class LinkedLists
protected int data; {
protected Nodes link; protected Nodes start, end;
constructors and methods… protected int size;
} constructors and methods…
26 } 28
Khai báo cấu trúc DSLK đơn Các thao tác trên DSLK đơn
Lớp Nodes:
Khai báo biến chứa dữ liệu của Nodes
LinkedLists Khai báo biến link đến Nodes kế
Hàm tạo Nodes không tham số
start end Hàm tạo Nodes có 2 tham số
public class Nodes public class LinkedLists
Hàm đặt liên kết đến Nodes kế
{ { Hàm gán giá trị cho Nodes hiện hành
protected int data; protected Nodes start, end;
protected Nodes link; protected int size;
Hàm trả về link đến Nodes kế
constructors and methods… constructors and methods… Hàm trả về dữ liệu của Nodes hiện hành
} }
31
29
Khai báo cấu trúc DSLK đơn Các thao tác trên DSLK đơn
Lớp LinkedLists:
Khai báo Nodes start chỉ đến Nodes đầu DSLK
Khai báo Nodes end chỉ đến Nodes cuối DSLK
LinkedLists Khai báo biến cho biết kích thước của DSLK
Hàm tạo danh sách liên kết rỗng
Hàm kiểm tra DSLK rỗng
start end
Hàm lấy kích thước DSLK
public class Nodes public class BTList Hàm chèn 1 phần tử vào đầu DSLK
{ … { Hàm chèn 1 phần tử vào cuối DSLK
public static void main(…) Hàm duyệt DSLK
}
{ Hàm chèn 1 phần tử tại vị trí Pos trong DSLK
public class LinkedLists …
{ … Hàm xóa 1 phần tử tại vị trí Pos trong DSLK
}
} }
32
30
Các thao tác trên DSLK đơn
Hàm kiểm tra DSLK rỗng
Lớp BTList:
Gọi các hàm tạo ở lớp Nodes và LinkiedLists LinkedLists
start end
Gọi các hàm ở lớp Nodes và LinkiedLists
Danh sách rỗng
LinkedLists ? ? LinkedLists
start end start end LinkedLists 30
Trước khi tạo lập Sau khi tạo lập start end
end = p p
public LinkedLists()
{
start = end = null;
size = 0;
} 34 36
Chèn một phần tử vào DSLK TH chèn một nút vào đầu danh sách
TH danh sách đã có phần tử
LinkedLists 30 25
start end
LinkedLists 30 25
start end
p
Vẽ lại
Có 2 trường hợp để chèn p
1.Chèn p vào đầu (insertAtStart)
2.Chèn p vào cuối (insertAtEnd) LinkedLists 25 30
start end
37 39
TH chèn một nút vào đầu danh sách TH chèn một nút vào đầu danh sách
2
1
2 LinkedLists 30 25
1 start end
p
LinkedLists 30 25
start end
p
1 p.setLink(start)
2 start = p
38 40
TH chèn một nút vào đầu danh sách TH chèn một nút vào đầu danh sách
1
Hãy viết hàm thêm phần tử p vào
LinkedLists 30 25 đầu danh sách (bằng ngôn ngữ Java),
start end theo mẫu sau:
p public void insertAtStart(int val)
2
1 start = p
2 p.setLink(start)
41 43
TH chèn một nút vào đầu danh sách TH chèn một nút vào cuối danh sách
25 30 42 1 end.setLink(p)
start end
LinkedLists p 2 end = p
42 44
TH chèn một nút vào cuối danh sách TH chèn một nút tại vị trí Pos trong DSLK
30 25 42
start end
LinkedLists p
45 47
TH chèn một nút vào cuối danh sách TH chèn một nút tại vị trí Pos trong DSLK
public void insertAtPos(int val , int pos) {
Nodes nptr = new Nodes(val, null);
Nodes ptr = start;
Hãy viết hàm thêm phần tử p vào pos = pos - 1;
if(pos==0) { nptr.setLink(start); start = nptr;}
cuối danh sách (bằng ngôn ngữ Java), else
for (int i = 1; i < size; i++)
theo mẫu sau: {
public void insertAtEnd(int val) if (i == pos)
{
Nodes tmp = ptr.getLink();
ptr.setLink(nptr);
nptr.setLink(tmp);
break;
}
ptr = ptr.getLink();
}
size++;
46 48
}
TH xóa một nút tại vị trí Pos trong DSLK TH xóa một nút tại vị trí Pos trong DSLK
Nodes ptr = start; //xóa tại vị trí Pos
pos = pos - 1;
for (int i = 1; i < size - 1; i++){
if (i == pos){
Nodes tmp = ptr.getLink();
tmp = tmp.getLink();
TH3 ptr.setLink(tmp);
break;
}
ptr = ptr.getLink();
}
size-- ;
}
49 51
TH xóa một nút tại vị trí Pos trong DSLK Yêu cầu:
public void deleteAtPos(int pos) { Sinh viên vẽ hình cho trường hợp xóa
if (pos == 1) { //xóa tại vị trí start
Nodes tmp = start; ở đầu, ở cuối.
start = start.getLink();
TH1 tmp.setLink(null);
size--;
return ;
}
if (pos == size) { //xóa tại vị trí end
Nodes s = start;
Nodes t = start;
while (s != end) {
t = s;
s = s.getLink();
TH2 }
end = t;
end.setLink(null);
size --;
return; 50 52
}
Nhập dữ liệu vào danh sách
Nhập dữ liệu vào danh sách
Hàm tạo Nodes có 2 tham số
public Nodes(int d, Nodes n)
{
Nhập kích thước DSLK data = d;
link = n;
}
53 55
Bài tập 2
Xuất dslk
Cài đặt các hàm sau trên DSLK đơn số nguyên:
p 1. Đếm số lượng node trong DSLK
2. Tìm node có giá trị lớn nhất
3. Tìm node có giá trị x
4. In những node có giá trị chẵn
5. Tính giá trị trung bình cộng các node lẻ
6. Tìm node có giá trị âm nhỏ nhất
start end 7. Tìm node có giá trị dương lớn nhất
LinkedLists
8. Sắp xếp danh sách tăng dần
58 60
Đoạn chương trình mẫu: class Nodes Đoạn chương trình mẫu: class LinkedLists
61 63
Đoạn chương trình mẫu: class Nodes Đoạn chương trình mẫu: class LinkedLists
62 64
Đoạn chương trình mẫu: class LinkedLists Đoạn chương trình mẫu: class LinkedLists
65 67
Đoạn chương trình mẫu: class LinkedLists Đoạn chương trình mẫu: class BTList
66 68
Đoạn chương trình mẫu: class BTList
Bài tập 3
Sử dụng DSLK đơn để quản lý thông tin SV gồm: Masv,
Hoten, Ngaysinh, Gioitinh, DTB,…
1. Xây dựng cấu trúc lớp SINHVIEN
2. Xây dựng cấu trúc lớp Nodes
3. Xây dựng cấu trúc LinkedList
4. Nhập danh sách sinh viên
5. Xuất danh sách sinh viên
6. Tìm sinh viên theo mã số sinh viên
7. Tìm sinh viên có DTB lớn nhất
8. Tìm sinh viên có DTB nhỏ nhất
9. Sắp xếp danh sách sinh viên giảm dần theo DTB
69 71
Đoạn chương trình mẫu: class BTList DANH SÁCH LIÊN KẾT ĐÔI
Doubly Linked List
Đặc điểm:
DSLK có 2 liên kết, một chỉ đến phần tử đứng trước và
một chỉ đến phần tử đứng sau.
Ưu điểm:
DSLK đôi có thể di chuyển theo cả hai hướng tiến và lùi.
Thao tác xóa, chèn trong DSLK đôi là hiệu quả hơn.
70 72
DANH SÁCH LIÊN KẾT ĐÔI Tổ chức các lớp cho DSLK đôi
Doubly Linked List
Lớp Node:
Khai báo biến chứa dữ liệu
1. Xây dựng lớp Node
Khai báo Node liên kết sau, trước 2. Xây dựng lớp LinkedList
Hàm tạo DSLK rỗng 3. Xây dựng lớp BTDList
Hàm tạo DSLK gồm data, liên kết sau, trước
Hàm tạo liên kết đến Node kế (sau)
Hàm tạo liên kết đến Node trước
Hàm lấy liên kết đến Node kế (sau)
Hàm lấy liên kết đến Node trước
Hàm gán dữ liệu cho data
Hàm lấy dữ liệu từ data
73 75
DANH SÁCH LIÊN KẾT ĐÔI Đoạn chương trình mẫu: class Node
Doubly Linked List /* Khai báo Class Node */
class Node
Lớp LinkedList: {
protected int data; //Khai báo phần dữ liệu
Khai báo biến chứa dữ liệu protected Node next, prev; //Khai báo phần liên kết sau, trước
Khai báo Node liên kết sau, trước
/* hàm Constructor */
Hàm tạo DSLK rỗng public Node()
Hàm tạo DSLK gồm data, liên kết sau, trước {
next = null;
Hàm tạo liên kết đến Node kế (sau) prev = null;
Hàm tạo liên kết đến Node trước data = 0;
}
Hàm lấy liên kết đến Node kế (sau) /* hàm Constructor */
Hàm lấy liên kết đến Node trước public Node(int d, Node n, Node p)
{
Hàm gán dữ liệu cho data data = d;
next = n;
Hàm lấy dữ liệu từ data prev = p;
74 } 76
Đoạn chương trình mẫu: class Node Đoạn chương trình mẫu: class LinkedList
/* Function to set link to next node */ /* Class linkedList */
public void setLinkNext(Node n) class linkedList
{ {
next = n; protected Node start; //Chỉ đến phần tử đầu của DSLK
} protected Node end ; //Chỉ đến phần tử cuối của DSLK
/* Function to set link to previous node */ public int size; //Cho biết kích thước của DSLK
public void setLinkPrev(Node p) public linkedList() /* hàm khởi tạo DSLK rỗng */
{ {
prev = p; start = null;
} end = null;
/* Funtion to get link to next node */ size = 0;
public Node getLinkNext() }
{ /* Function to check if list is empty */
return next; public boolean isEmpty()
} {
/* Function to get link to previous node */ return start == null;
public Node getLinkPrev() }
{ public int getSize() /* Function to get size of list */
return prev; {
} return size;
77 79
}
Đoạn chương trình mẫu: class Node Đoạn chương trình mẫu: class LinkedList
/* Function to set data to node */ /* Function to insert element at begining */
public void setData(int d) public void insertAtStart(int val)
{ {
data = d; Node nptr = new Node(val, null, null);
} if(start == null)
/* Function to get data from node */ {
public int getData() start = nptr;
{ end = start;
return data; }
} else
} {
start.setLinkPrev(nptr);
nptr.setLinkNext(start);
start = nptr;
}
size++;
}
78 80
Đoạn chương trình mẫu: class LinkedList Đoạn chương trình mẫu: class LinkedList
/* Function to insert element at end */ /* Function to delete node at position */
public void insertAtEnd(int val) public void deleteAtPos(int pos)
{ {
Node nptr = new Node(val, null, null); if (pos == 1) {
if(start == null) if (size == 1) {
{ start = null;
start = nptr; end = null;
end = start; size = 0;
} return;
else }
{ start = start.getLinkNext();
nptr.setLinkPrev(end); start.setLinkPrev(null);
end.setLinkNext(nptr); size--;
end = nptr; return ;
} }
size++; if (pos == size){
} end = end.getLinkPrev();
end.setLinkNext(null);
size-- ;
}
81 83
Đoạn chương trình mẫu: class LinkedList Đoạn chương trình mẫu: class LinkedList
/* Function to insert element at position */ Node ptr = start.getLinkNext();
public void insertAtPos(int val , int pos) for (int i = 2; i <= size; i++) {
{ if (i == pos) {
Node nptr = new Node(val, null, null); Node p = ptr.getLinkPrev();
if (pos == 1) { Node n = ptr.getLinkNext();
insertAtStart(val);
return; p.setLinkNext(n);
} n.setLinkPrev(p);
Node ptr = start; size-- ;
for (int i = 2; i <= size; i++) { return;
if (i == pos) { }
Node tmp = ptr.getLinkNext(); ptr = ptr.getLinkNext();
ptr.setLinkNext(nptr); }
nptr.setLinkPrev(ptr); }
nptr.setLinkNext(tmp);
tmp.setLinkPrev(nptr);
}
ptr = ptr.getLinkNext();
}
size++ ; 82 84
}
Đoạn chương trình mẫu: class LinkedList
/* Function to display status of list */
public void display() {
System.out.print("\nDoubly Linked List = ");
if (size == 0) {
System.out.print("Danh sách liên kết rỗng!\n");
return;
}
if (start.getLinkNext() == null) {
System.out.println(start.getData() );
return;
}
Node ptr = start;
System.out.print(start.getData()+ " <-> ");
ptr = start.getLinkNext();
while (ptr.getLinkNext() != null) {
System.out.print(ptr.getData()+ " <-> ");
ptr = ptr.getLinkNext();
}
System.out.print(ptr.getData()+ "\n");
}
85
}