Tải bản đầy đủ (.docx) (50 trang)

Cấu trúc dữ liệu mảng

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (190.06 KB, 50 trang )

1

Chương 2: Cấu trúc dữ liệu mảng

2 .1 Định nghĩa và khái niệm về cấu trúc dữ
liệu mảng
Mảng là một loại cấu trúc dữ liệu rất thường gặp trong
các bài toán thực tế. Chẳng hạn trong biểu 1 dưới đây ta
có số liệu về tình hình sử dụng nguyên vật liệu trong
một doanh nghiệp.
Biểu 1: Thống kê mức sử dụng nguyên vật liệu
Thép
Dầu
Tôn
1

PX 1
50
30
20

PX 2
50
25
50

PX 3
20
50
40
1




2

Điện
Than

2,5
15

2,5
20

2,5
15

(Đơn vị tính: Sắt, thép, tôn: tấn
Đi ện : nghìn kw/h
Dầu : kg)
Biểu này có năm dòng và 4 cột chứa 15 số liệu
khác nhau về mức độ sử dụng nguyên vật liệu của mỗi
phân xưởng. Ta nói rằng đây là một mảng gồm 5 dòng
và 4 cột.
Định nghĩa
Mảng ( Array ) là một tập hợp có thứ tự bao
gồm một số lượng cố định các phần tử,được truy
cập với cùng một tên.
Trong ví dụ trên đây, biểu thống kê sử dụng
nguyên vật liệu là một mảng hai chiều.
Chúng ta xét thêm ví dụ sau đây. Cho số liệu về

năng suất lao động của 10 doanh nghiệp (Đơn v ị tính:
Triệu đồng)
149 NS [1]
234 NS [2]
423 NS [3]
207 NS [4]
201 NS [5]
2

2


3

203 NS [6]
205 NS [7]
210 NS [8]
215 NS [9]
245 NS [10]
Ta có năng suất lao động NS [1. . 10] là m ột m ảng
một chiều gồm 10 thành phần. Mảng một chiều còn gọi
là một véc tơ
M ỗi m ảng đ ược xác đ ịnh b ởi
tên và số lượng các thành phần của nó. Chẳng h ạn ,
mảng năng suất lao động có mô tả NS [1..10]. Chúng ta
dễ dàng truy nhập các thành phần của mảng bằng cách
dùng tên mảng và chỉ số đi kèm với nó tức là dùng biến
mang chỉ số .Ví dụ biến mang chỉ số NS [2] xác định
năng suất của doanh nghiệp thứ 2
2.2 Cấu trúc dữ liệu mảng một chiều

Trước hết chúng ta xem xét cấu trúc dữ liệu mảng
một chiều. Cấu trúc dữ liệu loại này thường gặp rất
nhiều trong hoạt động kinh tế . Chẳng hạn năng suất lao
động của 10 doanh nghiệp là một mảng một chiều , một
dãy số thống kê gồm 20 giá trị về doanh số bán lẻ của
20 trung tâm thương mại trong năm 1998, số tiền đ ầu
tư vào một công trình xây dựng của 15 nhà đầu t ư n ước
ngoài cũng đều là các mảng một chiều.Trong các ví dụ
trên đây ta có các mảng một chiều . Mảng NS[1..10] biểu
3

3


4

diễn năng suất lao động của các doanh nghiệp. Mảng
DOANHSO [1.. 20] biểu diễn mức doanh số bán lẻ của
20 trung tâm thương mại .Mảng DAUTU[1..15] bi ểu
diễn mức đầu tư của 15 nhà đầu tư vào một công trình
xây dựng.
2.2.1 Phương pháp lưu trữ mảng
một chiều
Chúng ta xem xét vấn đề cấu trúc lưu tr ữ (Storage
Structure ) của mảng một chiều.

4

4



5

Địa chỉ

Vùng nhớ

Phần tử mảng

Base (A)+0
← A[1]
Base (A)+1
← A[2]
Base (A)+2
← A[3]
Base (A)+3
← A[4]
Base (A)+4
← A[5]
................
........................

Giả sử ta có mô tả :
Var
A : array[1..20] of real;
Khai báo này chỉ thị cho chương trình dịch để ra
một vùng bộ nhớ liên tục đủ lớn để chứa các phần tử
của mảng. Địa chỉ của ô nhớ đầu tiên dùng để chứa các
phần tử đó được gọi là địa chỉ cơ sở ( Base address) của
mảng, ký hiệu là Base(A).Địa chỉ của bất cứ phần tử nào

cũng được tính dựa vào địa chỉ cơ sở này.
5

5


6

Chúng ta xét một ví dụ khác. Cho mảng B v ới mô
tả: Var B: array[-3..3] of real; giả sử mỗi phần tử được
lưu trữ trong hai từ máy.
Địa chỉ

Vựng nhớ

Phần tử

mảng

Base (B)+0
← B[-3]
Base (B)+1
Base (B)+2
← B[-2]
Base (B)+3
Base (B)+4
Base (B)+5
...........
Base (B)+6
Base(B)+7

Base(B)+8
11001010111001
Base (B)+9

Trong trường hợp tổng quát, mảng một chiều
(véc tơ C) có n phần tử là C 1, C2,... Cn . Giả sử mỗi
phần tử chiếm L từ máy thì mảng này được lưu trữ
trong L *N từ máy liên tiếp nhau theo mô hình sau đây:

6

6


7

§ Þa chØ

Base (C)+0
Base (C)+1
Base (C)+2
Base (C)+3
Base (C)+4
...........
Base(C)+7
Base(C)+8
Base (C)+9
Base (C)+10
Base (C)+11
...............

Base (C)+( N-1)

Vï ng nhí

PhÇn tö m¶ng

← C[1]

11001010111001
1010111010101
← C[N]

Địa chỉ Ci được tính như sau: ĐC (Ci) = Base(C) + L * (i-1)
Trong đó Base(C) là địa chỉ cơ sở;
F (i) = L * (i-1) gọi là hàm địa chỉ.
Ví dụ Xét cấu trúc lưu trữ của mảng năng suất lao
động của 15 doanh nghiệp; Giả sử năng suất lao động
của mỗi doanh nghiệp chứa trong1 từ máy.Ta có hình
ảnh của cấu trúc lưu trữ trong bộ nhớ như sau:

7

7


8

§ Þa chØ

Base (NS)+0

Base (NS)+1
Base (NS)+2
Base (NS)+3
Base (NS)+4
Base (NS)+5
Base (NS)+6
Base(NS)+7
Base(NS)+8
Base (NS)+9
Base (NS)+10
Base (NS)+11
Base(NS)+12
Base (NS)+13
Base (NS)+14

Vï ng nhí

m¶ng NSLD

← NS[1]

...........
11001010111001

11100111010100 ← NS[15]

Trong cấu trúc lưu trữ này chúng ta luôn luôn xác
định được một cách nhanh chóng địa chỉ của mỗi thành
phần của mảng một chiều.
2.2.2 phép toán với mảng một chiều

Các phép toán thông dụng đối với mảng một chiều
gồm :
CREATE
Tạo lập mảng một chiều
8

8


9

SORTING
Sắp xếp mảng một chiều
SEACHING Tìm kiếm trong mảng một chiều
CALCULATE Tính toán với mảng một chiều.
Trong các giải thuật với mảng một chiều dưới
đây, biến Vector có mô tả như sau:
Var
Vector : array [ 1. . n] of real;
2.2. 3 Giải thuật tạo lập mảng một chiều.
Cho mảng một chiều A=(a i ) i=1,2....n
Giải thuật tạo lập mảng.như sau:
Procedure CreateVector ( a: Vector ; var n :
interger );
Var
i: integer;
begin
For i: = 1 to n do
Begin
write(' a[' ,i,'] =' );

readln(a[i]);
end;
end;
Giải thuật này nạp lần lượt từng thành phần của
mảng một chiều khi ta gõ từ bàn phím và lưư trữ trong
9

9


10

bộ nhớ dưới dạng một véc tơ lưu trữ kế tiếp gồm n
phần tử.
2.2.4 Giải thuật sắp xếp mảng một chiều
Trong thực tế thường xuất hiện nhu cầu sắp xếp
các thành phần của mảng một chiều theo một trình t ự
xác định tiện lợi cho việc nghiên cứu đánh giá một hiện
tượng , một quá trình kinh tế - kỹ thuật nào đó. Chẳng
hạn, chúng ta cần sắp xếp mảng năng suất lao động của
10 doanh nghiệp theo trình tự giảm dần để có một cái
nhìn tổng quát về kết quả hoạt động của các doanh
nghiệp.Hoặc sắp sếp vốn đầu tư của 15 nhà đầu tư theo
chiều tăng dần giúp ta đánh giá dễ dàng qui mô đầu t ư v
v...
Bây giờ ta xét giải thuật sắp xếp .Cho mảng một
chiều a(n) gồm n phần tử. Giải thuật sắp xếp mảng một
chiều này theo chiều tăng dần biểu diễn như sau.
Procedure SortVector (a : Vector; Var n : integer);
Var

J, I: integer;
tg: real;
begin
For i : = 1 to n-1 do
For j:= I+1 to n do
10

10


11

if a[i] >a[ j] then
begin
tg: = a[i];
a[i]: =a[j];
a[ j] : = tg
(* Đ ổi ch ỗ a[i] và a[j] *)
end;

end;

Nhận xét
Trong trường hợp sắp xếp giảm dần ta chỉ cần có
một thay đổi nhỏ trong giải thuật bằng cách thay điều
kiện kiểm tra a[i]>a[j bằng điều kiện a[i]quan về sắp xếp và các giải thuật sắp xếp khác nhau sẽ
được nghiên cứu kỹ hơn trong chương 6 .
2.2.5 Giải thuật tìm kiếm trong mảng một chiều
Vấn đề tìm kiếm cũng thường xuất hiện khi giải

quyết các bài toán trong hoạt động kinh tế . Chẳng hạn,
trong số các nhà đầu tư nước ngoài, yêu cầu tìm kiếm và
in ra họ tên nhà đầu tư có số tiền đầu tư ban đầu là 120
triệu đôla , hoặc tìm kiếm và in ra tên của các doanh
nghiệp có giá trị tổng sản lượng bằng giá trị tổng sản
lượng động trung bình v v.
11

11


12

Bây giờ chúng ta xét giải thuật tìm kiếm . Cho
mảng một chiều A gồm n phần tử . Giải thuật tìm kiếm
một phần tử của mảng có giá trị bằng một đại lượng T
cho trước được biểu diễn như sau:
Function SeachingVector (a : Vector ; Var n: integer ) :
real;
Var
I : Integer;
T : real;
begin

end;

For i : = 1 to n do
if a[i] = T then
seachingVector : = a[i];
else

Writeln(‘ Không có’)

2.2.6 Giải thuật tính toán trong mảng một chiều
Các vấn đề tính toán trong mảng một chiều luôn
luôn xuất hiện khi chúng ta muốn xác định các chỉ tiêu
thống kê đặc trưng của mảng.Chẳng hạn, đối với m ảng
các nguồn vốn đầu tư vào một công trình người ta muốn
xác định vốn đầu tư trung bình của các nguồn vốn đầu
12

12


13

tư, mức độ chênh lệch của các mức đâu tư so với giá trị
trung bình v v..
Các tiêu thức thống kê thông dụng nhất là:
- Giá trị trung bình;
- Phương sai;
- Độ lệch chuẩn
Sau đây là giải thuật:
Procedure CalculateVector (a : Vector; Var n : integer);
Var
i: integer;
tbinh,phsai,dolech: real; (* Trung bình,phương
sai, độ lệch chuẩn*)
Begin
tbinh: = 0;
For i : = 1 to n do

tbinh: = tbinh + a[i];
tbinh: = tbinh/n;
phsai: = 0;
For i : = 1 to n do
phsai: = phsai+sqr(a[i]-tbinh);
phsai: = phsai /n;
dolech: =sqrt(phsai);
end;
13

13


14

Bây giờ chúng ta xem xét việc ứng dụng cấu trúc d ữ
liệu kiểu mảng một chiều để giải quyết các bài toán
thực tế .
Bài toán 1
Vốn đầu tư của n nhà đầu tư nước ngoài vào công trình
xây dựng nhà máy thuỷ điện là mảng một chiều,thành
phần của nó là các số dương. Lập giải thuật xác định
xem có bao nhiêu mức vốn đầu tư và trong mỗi m ức có
bao nhiêu nhà đầu tư ?
Ta có chương trình sau đây :
Program Dautu ;
Uses crt;
Type
VT=array[1..100] of integer;
var

c,a,b:vt;
k,tt,tg,dem,muc,n,m,i,j :integer;
begin
ClrScr;
Write('Nhap so luong phan tu cua vecto n: ');readln(n);
for i:=1 to n do
begin
write('a[',i,'] ='); readln(a[i]);
14

14


15

end;
ClrScr;
for i:=1 to n-1 do
for j:=i+1 to n do
if a[i]>a[j] then
begin
tg:=a[i]; a[i]:=a[j]; a[j]:=tg
end;
writeln('Gia tri cua mang 1 chieu');
for i:=1 to n do
write(a[i],' ');
i:=1;
k:=1;
while i<=n do
begin

tt:=a[i];
for j:=i to n do
begin
If a[j]=tt then
Begin
b[k]:=b[k]+1;
end
end;
i:=i+b[k];
k:=k+1;
end;
15

15


16

muc:=0;
for i:=1 to n do
begin
if b[i]<>0 then muc:=muc+1;
end;
writeln(' ');
writeln('Tong so co ',muc,' muc von dau tu');
for i:=1 to muc do
begin
writeln('Muc ',i,' co ',b[i],' nha dau tu');
end;
Readln

end.
2.3

Cấu trúc dữ liệu mảng hai chiều ( Ma trận)

Xét mảng hai chiều trong trường hợp tổng quát
có n dòng và m cột.Loại cấu trúc dữ liệu này rất th ường
gặp trong kinh tế. Chẳng hạn như bảng tổng hợp kinh
doanh trong một trung tâm thương mại đã bán ra m mặt
hàng cho n khách hàng là một mảng hai chiều . Bảng
thống kê các định mức tiêu thụ n loại nguyên vật liệu để
chế tạo ra m loại sản phẩm trong một phân xưởng cũng
là loại cấu trúc dữ liệu mảng hai chiều.
2.3.1 Cấu trúc lưu trữ mảng hai chiều
16

16


17

Cho mảng hai chiều( hay một ma trận) sau đây A sau
đây :
A=(A i j) i=1,2,3.....n
j=1,2,3,....m
Có hai phương pháp lưu trữ mảng hai chiều:
1 - Lưu trữ theo dòng(như trong BASIC, PASCAL)
2 - Lưu trữ theo cột. ( như trong FORTRAN )
Đối với trường hợp lưu trữ theo cột, các phần t ử
của mảng sẽ được lưu trữ liên tiếp bắt đầu từ cột th ứ

nhất sau đó sang cột thứ hai, cột th ứ ba vv,, cho đến hết
cột cuối cùng của mảng .
Cho mảng hai chiều với mô tả:
Var
M: array[1..3,1..4] of integer;

M=

17

12 13 45

67

45 78

23

11

10

8

23

43

17



18

Nếu một số nguyên được lưu trữ trong một từ
máy thì khai báo này chỉ thị cho chương trình dịch đ ể ra
12 từ máy liên tiếp nhau để chứa các phần t ử của mảng
M
§ Þa chØ

Base (M)+0
Base (M)+1
Base (M)+2
Base (M)+3
Base (M)+4
Base (M)+5
Base (M)+6
Base(M)+7
Base(M)+8
Base (M)+9
Base (M)+10
Base (M)+11

Vï ng nhí

m¶ng M

12
13
45
67


← M[1,1]
← M[1,2]
← M[1,3]
← M[1,4]

.............

................
................

23

← M[3,3]
← M[3,4]

Trong cấu trúc lưu trữ theo dòng trước hết người
ta lần lượt lưu trữ các thành phần của dòng thứ nhất ,
tiếp đó là các thành phần của dòng thứ hai, dòng th ứ 3
vv.. cho đến dòng cuối cùng . Trong trường h ợp l ưu tr ữ
theo dòng công thức tính địa chỉ của phần tử ai j như
sau:
18

18


19

ĐC (Aij) = Base(A[i,j]) +(i-1) *m+(j-1)

Trong trường hợp lưu trữ theo cột ,cấu trúc trong
bộ nhớ sẽ như sau:

§ Þa chØ

Base (M)+0
Base (M)+1
Base (M)+2
Base (M)+3
Base (M)+4
Base (M)+5
Base (M)+6
Base(M)+7
Base(M)+8
Base (M)+9
Base (M)+10
Base (M)+11

Vï ng nhí

m¶ng M

12
45
22

← M[1,1]
← M[2,1]
← M[3,1]


.............

................
................

23

← M[4,2]
← M[4,3]

Trong trường hợp lưu trữ theo cột,địa chỉ phân tử
thuộc dòng I và cột J được xác định theo công thức:
ĐC (Aij) = Base(A[i,j]) + (j-1) * n + (i-1)
19

19


20

Ví dụ cho mảng A = a[3,4], mỗi phần tử chiếm 1
từ máy. Tính địa chỉ của phần tử a23?
Phương pháp lưu trữ theo cột:
Trong trường hợp này n = 3 ; m = 4
Đc (A23) =Base (A) +(3-1)*3+(2-1) = Base (A) + 7
Lưu trữ theo dòng:
Công thức tính địa chỉ như sau:
ĐC (A23) = Base (A)+ (2-1)*3 + (3-1)=Base(A) +5
2.3.2 Các phép toán với mảng hai chiều
Các phép toán thông dụng với mảng hai chiều là:

1 - Tạo lập mảng hai chiều
2 - Tìm kiếm một phần tử của mảng hai chiều
3 - Cộng hai hoặc nhiều mảng hai chiều với nhau
4 - Nhân mảng hai chiều với mảng một chiều
5 - Nhân mảng hai chiều với mảng hai chiều
Trong các giải thuật với mảng hai chiều dưới
đây,biến Matrix được mô tả như sau:
Var
mt : array [ 1 . . n , 1 . . m] of real;
2.3.3 Giải thuật tạo lập mảng hai chiều
Cho mảng hai chiều A=(Ai j) i=1,2,3...n
j=1,2,3...m
20

20


21

Giải thuật tạo lập mảng hai chiều như sau:
Procedure CreateMatrix (a : Matrix; Var n ,m: integer );
Var
i,j: integer;
begin
for i: =1 to n do
for j: = 1 to m do
begin
write ('a [ ' ,I,’ , ’ , j,' ] = ');
read(a[i,j]
end;

end;
Giải thuật này tạo lập một mảng hai chiều bằng
cách sử dụng phương pháp lưu trữ theo dòng. Trong quá
trình này sẽ lần lượt nạp các thành phần của mảng bắt
đầu từ dòng thứ nhất,sau đó sang dòng th ứ hai v.v... cho
đến dòng cuối cùng để tạo thành một Storage Structure
chứa các thành phần của mảng hai chiều.
2.3.4 Giải thuật tìm kiếm
Cho mảng hai chiều A=(a i j) i=1,2,3,...n
j=1,2,3....m

21

21


22

Giải thuật tìm kiếm một phần tử của mảng có giá trị
bằng một đại lượng L cho trước được biểu diễn nh ư
sau :
Function SeachingMatrix (a : Matrix; Var n,m : integer)
: real;
Var
i,j:integer;
L : real;
begin
For i: =1 to n do
For j: = 1 to m do
if a[i,j] = L then

seachingMatrix: = a[i,j];
else
writeln(' Không có');
end;
2. 3.5 Giải thuật nhân mảng hai chiều với một véctơ
Bài toán nhân mảng hai chiều với một véc tơ có
rất nhiều ứng dụng trong thực tế nhất là trong kinh tế.
Chẳng hạn, chúng ta xét bài toán lập bảng tổng hợp kinh
doanh của một trung tâm thương mại điệnvà điện tử
gồm 5 cửa hàng và đã bán ra 10 loại hàng hoá khác
22

22


23

nhau.Biết số lượng mỗi loại hàng mà từng cửa hàng đã
bán và đơn giá của mỗi mặt hàng . Trong trường h ợp
này bảng số liệu về số lượng các mặt hàng ( có 10
loại ) đã bán trong 5 cửa hàng là một mảng hai chiều
kích thước 5x10 ,còn đơn giá từng mặt hàng là một véctơ
gồm 10 thành phần( Mỗi loại hàng có một giá bán cố
định). Thực hiện nhân ma trận với véctơ chúng ta sẽ
tính toán được được doanh số của mỗi cửa hàng .
Số liệu của bài toán kinh tế này được biểu diễn
trong cấu trúc mảng hai chiều như sau:
Biểu 1: Thống kê số lượng các loại hàng đã bán
trong từng cửa hàng ( CH ) của Trung tâm
thương mại


CH1
CH2
CH3
CH4
CH5

Loại hàng Loại hoàng ... Loại
1
2
hàng10
1200
2300
1200
1340
2400
1320
1450
2500
1450
1345
2600
1245
1280
2300
1240

Biểu 2 Giá bán lẻ các loại hàng
( Đơn vị : Nghìn đồng)
Loại hàng

Giá
Loại hàng 1
100
23

23


24

Loại hàng 2
Loại hàng 3
. .

.

. .
. .
Loại hàng 10

150
235
.

.

. . .
150

. .


Kết quả tính toán sẽ được biểu diễn dưới dạng biểu 3
sau đây:
Biểu 3 : Tính toán doanh số bán lẻ trong 5 cửa
hàng của một Công ty thương mại
Tên cửa hàng
CH1
............
CH5
Tổng cộng:

Tiền bán hàng

Bây giờ chúng ta xét bài toán dưới dạng tổng quát
Cho mảng hai chiều A=(aij) và véc tơ B=(bj) i=1,2,...n
j=1...m
Lập giải thuật nhân mảng hai chiều A với véc t ơ
B. Mỗi thành phần của mảng kết quả ( là mảng một
chiều) Ci được xác định theo công thức:
m
24

24


25

Ci = ∑ aij * bj
j=1


i = 1,2 ...n

Giải thuật biểu diễn như sau:
Procedure MultiMatrix (a : Matrix;b,c : Vector; var n,m
:integer );
Var
i,j: integer;
begin
For i : = 1 to n do
For j : = 1 to m do
Begin
write(' a [' ,i, ‘,’,j, ' ] = ');
readln(a[i,j])
end;
For j : =1 to m do
Begin
write(' b[ ',j,' ] = ');
readln(b[j])
end;
For i: = 1 to n do
begin
c[i]: = 0;
For j: = 1 to m do
c[i] : = c[i] + a[i,j] * b[j];
25

25



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×