Cài đặt danh sách bởi mảng hay còn gọi là CTDL danh sách đặc, hoặc CTDL danh sách kế tiếp, gọi tắt là: Danh sách đặc, hoặc danh sách kế tiếp, nó thuộc loại cấu trúc dữ liệu tĩnh
a) Mô tả cài đặt
Giá sử N là số phân tử tối đa trong danh sách, với cách cài đặt này ta phải ước lượng số phần tử tối đa của danh sách để khai báo số phần tử của mảng cho thích hợp. Giả sử
Item là kiểu dữ liệu của các phần tử trong danh sách. Khi đó ta sẽ biểu diễn danh sách như sau:
Dùng một mảng để lưu giữ các phần tử của danh (giả sử mảng Elements).
Count là một biến đếm đếm số lượng phần tử hiện có trong danh sách
Như vậy ta có thể định nghĩa danh sách như một cấu trúc bản ghi gồm 2 trường:
Elements: Chứa các phần tử trong danh sách
Count: Đếm số phần tử hiện có trong danh sách (chiều dài danh sách) Mảng chứa các phần tư trong danh sách có dạng:
chỉ số mảng 1 2 … count … n
Nội dung Phần tử 1 Phần tử 2 … Phần tử cuối rỗng rỗng
b) Dạng biểu diễn
#include<stdio.h>
#include<conio.h>
#define N 100
typedef int item;// dinh nghia kieu item
// dinh nghia danh sach chua so nguyen
typedef struct List
{
item elems[N];
int size; } List;
c) Cài đặt các phép toán cơ bản của danh sách 1- Khởi tạo danh sách rỗng
Danh sách rỗng là một danh sách không chứa bất kỳ một phần tử nào (hay độ dài danh sách bằng 0). Theo cách khai báo trên, trường count chỉ vị trí của phần tử cuối cùng trong danh sách và đó cũng độ dài hiện tại của danh sách, vì vậy để khởi tạo danh sách rỗng ta chỉ việc gán giá trị trường count này bằng 0.
// phep toan khoi tao danh sach void Init(List *L)
{
L->size=0; }
2- Kiểm tra danh sách rỗng
Danh sách rỗng là một danh sách mà độ dài của nó bằng 0.
// phep toan kiem tra ds rong int IsEmpty(struct List L) {
if(L.size==0) return 1;
else return 0;
}
3- Thêm một phần tử vào danh sách
Xét danh sách L, một giá trị cần thêm x và một vị trí p bất kỳ trong danh sách. Chèn x vào vị trí p trong danh sách L. Khi chèn x vào vị trí p của danh sách L thì sẽ xuất hiện các khả năng sau:
Mảng đầy tức là mọi phần tử của mảng đều chứa phần tử của danh sách, tức là phần tử cuối cùng của danh sách nằm n mảng. Nói cách khác, độ dài của danh sách bằng chỉ số tối đa của mảng; khi đó không còn chỗ cho phần tử mới, vì vậy việc them là không thể thực hiện được, chương trình báo lỗi. Ngược lại, nếu mảng chưa đầy ta tiếp tục xét vị trí p, nếu p không hợp lệ (p>count+1 hoặc p<1) thì chương trình báo lỗi; vì vị trí thêm p<1 thì khi đó p không phải là một vị trí phần tử trong danh sách. Nếu vị trí p>L.count+1 thì khi thêm sẽ làm cho danh sách L không còn là một danh sách đặc nữa. Nếu vị trí p hợp lệ thì ta tiến hành thêm theo các bước sau:
- Dời các phần tử từ vị trí cuối danh sách đến vị trí p sang phải 1 ô nhớ. - Đưa phần tử mới vào vị trí p.
- Tăng độ dài danh sách lên 1 đơn vị.
Giải thuật thêm:
//Pheps toan them mot phan tu x, vao ds L, tai vi tri p, quy uoc p tinh tu 1
void Insert(struct List *L, int p, item x) {
if ((IsFull(*L)==0) &&(k>=1)&&(p<=L->size+1))
{
L->size ++;
// dan mang
for (int i=L->size-1;i>=p;i--) L->elems[i]=L->elems[i-1];
// tai k chen x
L->elems[p-1]=x; }
}
4 - Xóa phần tử ra khỏi danh sách
Xét danh sách L, hãy xoá phần tử ở vị trí p ra khỏi danh sách. Để xoá phần tử ở vị trí p ra khỏi danh sách L ta làm công việc ngược lại với thêm một phần tử: Trước tiên ta kiểm tra vị trí phần tử cần xóa xem có hợp lệ hay không. Nếu p>L.count hoặc p<1 thì đây không phải là vị trí của phần tử trong danh sách. Ngược lại, vị trí đã hợp lệ thì ta phải dời các phần tử từ vị trí p+1 đến cuối danh sách sang trái một ô nhớ để đè lên phần tử cần xóa và độ dài danh sách giảm đi 1 phần tử.
Giải thuật xoá
// xoa 1 phan tu o vi tri p trong ds L, luu ptu xoa vao bien x void Delete(struct List *L, int p, item *x)
{
if ((IsEmpty(*L)==0)&&(p>=1)&&(p<=L->size))
{
*x=L->elems[p-1];
//don mang
L->elems[i]=L->elems[i+1];
L->size--;
} }
5 - Định vị một phần tử trong danh sách
Để định vị vị trí phần tử đầu tiên có nội dung x trong danh sách L, ta có thể áp dung phương pháp tìm kiếm tuần tự như sau:
Ta dò tìm từ đầu danh sách:
o Nếu tìm thấy x thì vị trí của phần tử tìm thấy được trả về,
o Nếu không tìm thấy thì hàm trả về vị trí sau vị trí của phần tử cuối cùng trong danh sách, tức là ENDLIST(L). Giả sử ta cho ENDLIST(L) := L.count+1
Trong trường hợp có nhiều phần tử cùng giá trị x trong danh sách thì vị trí của phần tử được tìm thấy đầu tiên trả về.
6- Các phép toán khác cũng dễ dàng cài đặt xem như bài dành cho bạn đọc