TS. Lê Minh Trung ThS Lương Trần Ngọc Khiết Khoa Công nghệ Thông tin, Đại học Sư phạm TP. HCM

Danh sách (List)

 Sử dụng mảng  Sử dụng con trỏ  Danh sách liên kết đôi

Thiết kế Class List

const int MAX= 20;

template class List { public:

List(void); ~List(void); int GetSize(); //trả về số phần tử của list bool IsEmpty(); //kiểm tra list có rỗng không bool IsFull(); //kiểm tra xem list có đầy không void SetItem(int pos, const T& item); //thiết lập giá trị item cho phần tử thứ pos T GetItem(int pos); //truy cập phần tử có vị trí pos void Insert(const T &item); //thêm vào vị trí đầu tiên void InsertAt(int pos, const T& item); //thêm item vào vị trí pos void Remove(const T& item); //xóa phần tử đầu tiên có giá trị item void RemoveAt(int pos); //xóa phần tử tại vị trí pos int IndexOf(const T& item); //trả về vị trí lần đầu tiên tìm thấy item void Traverse(void (*visit)(T& item)); //duyệt qua các phần tử của list và thực

hiện hàm visit với các phần tử

private:

int count; T data[MAX];

};

template bool List::IsEmpty(){

return count==0;

Một số phương thức

}

template bool List::IsFull() {

template List::List(void) {

return count==MAX;

}

count =0;

template T List::GetItem(int pos) {

}

if((pos<0)||(pos>count-1)){

template void List::SetItem(int pos, const T& item){

throw exception("Index is out

of range");

throw exception("Index is out of range");

}else {

if((pos<0)||(pos>count-1)){

return data[pos];

}else {

}

}

}

data[pos]= item;

}

Thêm vào một danh sách liên tục

z

2

0

1

3

4

5

6

7

8

9

c

a

b

d d

e e

f f

g g

h h

count=9 count=8

InsertAt(3, ‘z’)

Thêm vào danh sách

template void List::InsertAt(int pos, const T& item){

if(IsFull()){

throw exception("List is full");

}else {

if((pos<0)||(pos>count)){

throw exception("Index is out of range");

}else {

for(int i=count -1; i>=pos;i--)data[i+1]=data[i]; data[pos] = item; count ++;

}

}

}

template void List::Insert(const T& item){

InsertAt(0,item);

}

Xóa từ một danh sách liên tục

0

1

2

3

4

5

6

7

8

9

a

b

c

d d

e e

f f

g g

h h

count=7 count=8

RemoveAt(3)

Xóa phần tử từ danh sách

template void List::RemoveAt(int pos){

if(IsEmpty()){

}else {

throw exception("List is empty");

if((pos<0)||(pos>count-1)){

throw exception("Index is out of range");

}else {

for(int i=pos+1; i

}

}

}

Duyệt qua các phần tử

template void List::Traverse(void (*visit)(T& item)){ for(int i=0; i

}

template void Inc(T& item){

Thử nghiệm

item ++;

}

void main(){

template void Print(T& item){ cout << item<<" ";

}

List list; for(int i=5;i>=1;i-=2) list.Insert(i); list.InsertAt(1,2); list.InsertAt(3,4); list.RemoveAt(1); list.Traverse(Inc); list.Traverse(Print); cout<

}

Danh sách liên kết đơn (DSLK đơn)

Thiết kế Node

template struct Node {

T item; Node *next; Node(void); Node(T item, Node* ptr=nullptr);

}; template Node::Node(void) { this->next = nullptr; }

template Node::Node(T item, Node* ptr=nullptr) {

this->item = item; this -> next = ptr;

}

Thiết kế Class List

template class List { public:

List(void); ~List(void); void InsertAt(int pos, const T& item); void Insert(const T& item); void RemoveAt(int pos); int IndexOf(const T& item); void Remove(const T& item); int GetSize() const; void Clear(); //xóa sạch phần tử của list void Traverse(void (*visit)(T& item)) const;

private:

Node* head; Node* SetPosition(int pos); int count;

};

Một số phương thức

template List::List(void) {

head=nullptr; count =0;

}

template int List::GetSize() const{

return count;

}

Giải thuật tìm vị trí trên DSLK đơn

Algorithm Set position

Input: position là vị trí cần tìm Output: con trỏ chỉ đến phần tử tại vị trí cần tìm

1. set q to head 2. for index =0 to position

2.1. advance q to the next element //Thi hành position bước //Trỏ q đến phần tử kế tiếp

3. return q

SetPosition(2)

End Set position

q

head

index=0 index=1 index=2

x y z m

Phương thức SetPostition

template Node* List::SetPosition(int pos) {

Node* q = head; for(int i=1;i<=pos;i++)q = q->next; return q;

}

Thêm vào một DSLK đơn

previous_node following_node

x

y

phần tử tại vị trí position-1

phần tử tại vị trí position

bây giờ, phần tử này có vị trí position+1

a

new_node

bây giờ, phần tử này có vị trí position

Phương thức InsertAt

template void List::InsertAt(int pos, const T& item){

if(pos<0||pos>count){

throw exception("Index is out of range");

}else{

Node* previous, *following, *newNode; if(pos>0){

previous = SetPosition(pos-1); following = previous ->next;

}else following = head; newNode = new(nothrow) Node(item, following); if(newNode==nullptr){

throw exception("Not enough memory");

}else {

if(pos==0)head= newNode; else previous->next = newNode; count++;

}

}

}

Phương thức Insert

template void List::Insert(const T& item){

InsertAt(0,item);

}

Xóa bỏ từ một DSLK đơn

x

y

z

phần tử tại vị trí position-1

previous_node following_node

phần tử tại vị trí position

phần tử tại vị trí position+1

bây giờ, phần tử này có vị trí position

Phương thức RemoveAt

template void List::RemoveAt(int pos){

if(count ==0){

throw exception("List is empty"); return;

} if(pos<0 || pos >count-1){

throw exception("Index is out of range");

}else{

Node* previous, *following; if(pos>0){

previous = SetPosition(pos -1); following = previous -> next; previous -> next = following ->next;

}else {

following = head; head = following ->next;

}

delete following; count --;

}

}

Phương thức Clear và destructor

template void List::Clear(){

while(count>0)RemoveAt(0);

}

template List::~List(void) {

Clear();

}

Phương thức Traverse

template void List::Traverse(void (*visit)(T& item)) const{

Node* q = head; while(q !=nullptr){

(*visit)(q->item); q = q -> next;

}

}

Thử nghiệm

template void Print(T& item){

cout << item << " ";

}

void main(){

List list; list.Insert(1); list.Insert(3); list.Insert(4); list.InsertAt(1,2); list.Traverse(Print); cout<< endl;

}

DSLK kép (Doubly linked list)

Định nghĩa DSLK kép

template class List { public:

// Add specications for methods of the list ADT. // Add methods to replace compiler generated defaults.

protected:

// Data members for the doubly-linked list implementation follow: int count; mutable int current_position; mutable Node *current; // The auxiliary function to locate list positions follows: void SetPosition(int position) const;

};

Các hàm hằng (const) có thể thay đổi giá trị của các biến mutable này

Định nghĩa Node cho DSLK kép

template struct Node {

// data members T item; Node *next; Node *back; // constructors Node( ); Node(T, Node *link_back = NULL, Node *link_next = NULL);

z

};

Tìm vị trí trong DSLK kép

set_position(8) set_position(6)

current

x

y

z

m

current_position

position = 5 position = 6 position = 7 position = 8

Thêm vào trong DSLK kép

phần tử tại vị trí position-1

previous following

x

z

phần tử tại vị trí position

y

new_node

current

phần tử này bây giờ có vị trí là position+1

phần tử này bây giờ có vị trí là position

CÁM ƠN VÌ ĐÃ LẮNG NGHE!