Tải bản đầy đủ - 19 (trang)
S¾p xÕp trong:

S¾p xÕp trong:

Tải bản đầy đủ - 19trang

Phơng pháp chèn. Phơng pháp chọn.
Phơng pháp đổi chổ. Phơng pháp trộn.
- Sắp xếp ngoài hay sắp xếp tập tin. Vận dụng trong trờng hợp ta phải sắp xếp các tập tin chứa nhiều mẫu tin và mỗi
mẫu tin có chiều dài tơng đối lớn do đó ta không thể nạp toàn bộ vào bộ nhớ chính để sắp xếp thứ tự. Vì vậy ta phải có những phơng pháp thích hợp cho việc sắp xếp
tập tin.

2. Sắp xếp trong:


a Khái niệm: Cấu trúc dữ liệu thích hợp cho các phần tử cần sắp xếp thứ tự là Record.
Mỗi phần tử có hai vùng đặc trơng là: Vùng Key để chứa khoá của phần tử và đợc sử dụng trong các giải thuật tìm kiếm, vùng info dùng để chứa đữ liệu các phần tử.
Ta khai báo : Type
Item = Record key : Integer;
Info : Integer; End;
Var A : Array[1..n] of Item;
Khoá của phần tử có thể là chữ hoặc số. Yêu cầu giải thích là dïng Ýt vïng nhí vµ thêi gian thùc hiƯn nhanh.
b Phơng pháp đếm Counting sort Giải thích:
Nội dung của phơng pháp này là đếm các phần tử có khoá nhỏ hơn hay bằng khoá của các phần tử A[i]. Nếu có j phần tử có khoá nhỏ hơn khoá của phần tử
A[i] thì phần tử A[i] sẽ có vị trí theo thø tù j+1 trong d·y ®· cã thø tù. Trong gi¶i thuËt, ta dïng m¶ng Count[i] i = 1, 2, .. n víi Count[i] cho biÕt sè
phÇn tử có khoá nhỏ hơn khoá của phần tử A[i]. Nh vậy Count[i+1] là vị trí của phần tử A[i] trong dãy đã có thứ tự.
Ví dụ: Sắp xếp dãy 2 3 1 5 2 7 6 9 4
i: 1 2 3 4 5 6 7 8 Count: 2 0 4 1 6 5 7 3
Nh vËy phÇn tử có khoá 9 ở vị trí 8 vì Count[9]=7. ThĨ hiƯn b»ng Pascal:
Procedure Count_Sort; Var
Count : Array[1..n] of Integer; A : Array[1..n] of Item;
i,j : Integer; Begin
For i := 1 to n do Count[i] := 0;
2
For i := n downto 2 do For j := i-1 downto 1 do
If A[i].Key A[j].Key Then Count[j] := Count[j] + 1
Else Count[i] := Count[i] + 1; For i := 1 to n do S[Count[i] + 1] := A[i];
For i := 1 to n do A[i] := S[i]; End;
c Phơng pháp chèn Insertion Sort Giải thích:
Nội dung của phơng pháp này là giả sử ta có dãy A[1]..A[i-1] đã có thứ tự, có phải xác định vị trí thích hợp của phần tử A[i] trong dãy A[1]..A[i - 1] bằng phơng
pháp tìm kiếm tuần tự từ A[i - 1] trở về A[1] để tìm ra vị trí thích hợp của A[i]. Ta chèn A[i] vào vị trí này và kết quả là đãy A[1] .. A[i] có thứ tự. Ta áp dụng cách
làm này với i = 2, 3, ..., n. Ví dụ:
Ta phải sắp xếp d·y sè: 39 50 7 37 89 13 1 62
i=2 39 50 7 37 89 13 1 62 i=3 39 50 7 37 89 13 1 62
i=4 7 39 50 37 89 13 1 62 i=5 7 37 39 50 89 13 1 62
i=6 7 37 39 50 89 13 1 62 i=7 7 13 37 39 50 89 1 62
i=8 1 7 13 37 39 50 89 62 1 7 13 37 39 50 89 62
ThĨ hiƯn b»ng Pascal: Procedure Insertion_Sort;
Var x : Item;
i,j : Integer; Begin
For i := 2 to n do Begin
x := A[i]; A[0] := x;
j := j - 1; While x.Key A[j].Key do
Begin A[j+1] := A[j];
j := j - 1; End;
A[j+1] := x; End;
End; d Phơng pháp chọn Selection Sort
Giải thích:
3
Nội dung của phơng pháp này là ở bớc thứ i i = 1, 2, 3, ..., n-1 ta lùa chän phÇn tư nhỏ nhất trong dãy A[i]..A[n] rồi đổi chổ phần tử này với phần tử A[i]. Cuối
cùng ta sẽ có dãy A[1]..A[n] có thứ tự. Ví dụ:
Ta phải sắp xếp dãy sè : 39 50 7 37 89 13 1 62
i=1 39 50 7 37 89 13 1 62 i=2 1 50 7 37 89 13 39 62
i=3 1 7 50 37 89 13 39 62 i=4 1 7 13 37 89 50 39 62
i=5 1 7 13 37 89 50 39 62 i=6 1 7 13 37 50 50 39 62
i=7 1 7 13 37 39 50 89 62 1 7 13 37 39 50 89 62
ThĨ hiƯn b»ng Pascal: Procedure Selection_Sort;
Var x : Item;
i,j ,k : Integer; min : Integer;
Begin For i := 2 to n-1 do
Begin min := A[i].Key;
k := i; For i := 1 to n-1 do
For j := i+1 to n do If A[j].Key min Then
Begin min := A[j].Key;
k := j; End;
x := A[k]; A[k] := A[i];
A[i] := x; End;
End; e Phơng pháp đổi chỗ:
Có rất nhiều phơng pháp sắp xếp dựa trên việc đổi chỗ giữa 2 phần tử của dãy. Sau đây chúng ta xét các phơng ph¸p:
- Bubble Sort. - Shake Sort.
- Sell Sort. - Quick Sort.
Bubble Sort: Giải thích:
4
Nội dung của phơng pháp này là dut c¸c d·y A[1], ..., A[n]. NÕu A[i].Key A[i+1].Key i = 1, 2, 3, ..., n-10 thì ta đổi chỗ A[i].Key với phần tử A[i+1].Key.
Lập lại quá trình duyệt dãy này cho đến khi không còn việc đổi chổ của hai phần tử.
Chú ý rằng bất cứ lúc nào phần tử nhỏ nhất cũng gặp trớc tiên. Nó nh những bột khí nhẹ sẽ nổi lên trên khi đun nớc. Sau đó ở thứ hai phần tử nhỏ thứ 2 sẽ đợc đặ
vào đúng một vị trí. Vì vậy sắp xếp nổi bột thao tác nh một kiểu sắp xếp chọn, mặc dù nó không làm nhiều việc hơn để đa từng phần tử vào đúng vị trí.
Ví dụ: Ta phải sắp xếp dãy số:
39 50 7 37 89 13 1 62 Bíc 0 1 2 3 4 5 6 7
50 1 1 1 1 13 1 62 39 39 7 7 7 7 7 7
7 50 39 13 13 13 13 13 37 7 50 39 37 37 37 37
89 37 13 50 39 39 39 39 13 89 37 37 50 50 50 50
1 13 89 62 62 62 62 62 62 62 62 89 89 89 89 89
ThĨ hiƯn b»ng Pascal: Procedure Bubble_Sort;
Var x : Item;
i,j : Integer; Begin
For i := 2 to n do For j := n downto i do
If A[j-1].Key A[j].Key Then Begin
x := A[j-1]; A[j-1] := A[j];
A[j-1] := x; End;
End;
C¶i tiÕn: Ta nhËn thấy rằng nếu ở một lần duyệt dãy nào đó mà không co s xẩy ra sự đổi
chổ giữa hai phần tử thì dãy dang sắp đã có thứ tự và giải thuật kết thúc. Ta có thể cài đặt cờ để ghi nhận điều này và có chơng trình sau:
Procedure Bubble_Sort2; Var
x : Item; i : Integer;
flag : Boolean; Begin
flag := true;
5
While flag do Begin
flag := False; For i := 1 to n-1 do
If A[i].Key A[i+1].Key Then Begin
x := A[i]; A[i] := A[i+1];
A[i+1] := x; End;
End; End;
f Shake Sort: Giải thích:
Phơng pháp này là một cải tiến của phơng pháp Bubble Sort theo hớng Không những phần tử nhẹ nổi lên trên mà cả phần tử nặng cũng xuống dới giống nh khi
ta rungrung một cái nồi và thuật toán sắp xếp phải đợc điều khiển cả hai quá trình nổi lên và chìm xuống này một cách tự giác. Muốn vậy ta phải ghi nhớ
lần đổi chổ cuối cùng khi duyệt dãy từ trên lên và khi duyệt từ trên xuoóng để quyết định chu trình kế tiếp sẽ duyệt từ đâu đến đâu.
Ví dụ: Sắp xếp dãy sè:
39 50 7 37 89 13 1 62 d = 2 3 3 4 4
c = 8 8 7 7 4 39 1 1 1 1
50 39 39 7 7 7 50 7 39 13
37 7 37 13 37 89 37 50 37 39
13 89 13 50 50 1 13 62 62 62
62 62 89 89 89 ThĨ hiƯn b»ng Pascal:
Procedure Shake_Sort; Var
x : Item; i,k,d,c : Integer;
Begin d := 2;
c := n; k := n;
Repeat For i := c downto d do
If A[i-1].Key A[i].Key Then Begin
6
x := A[i-1]; A[i-1] := A[i];
A[i-1] := x; k := i;
End; d := d + 1;
For i := d to c do If A[i-1].Key A[i].Key Then
Begin x := A[i-1];
A[i-1] := A[i]; A[i-1] := x;
k := i; End;
c := k-1; Until dc;
End;
g. Shell Sort: Giải thích:
Các phơng pháp sắp xếp dã trình bày ở trên nói chung đều di chuyển mỗi phần tử đi một vị trí trong mỗi bớc. Phơng pháp Shell Sort dựa trên ý tởng chính là hoán
các phần tử ở xa nhau. Để làm đợc việc đó ta cần phải sắp các tập tin để nó có tính chất là việc lấy mọi phần tử thứ h bắt đầu từ vị trí bất kì nào cũng đều cho ra tập
tin đã sắp. Một tập tin nh vậy đợc gọi là sắp theo độ dài bớc h. Một cách nói khác, một tập tin dợc sắp theo độ dài bớc h là tập tin đợc sắp độc lập với nhau, đan xen
vào nhau. Bằng cách sắp xếp theo độ dài bớc h ứng với vài giá trị h khá lớn, chúng ta có thể di chuyển các phần tử ở những khoảng cách xa nhau trong mảng và vì
vậy dễ dàng hơn để sắp xếp độ dài bớc h các giá tri nhỏ hơn. Dùng thủ tục cho bất kì một dãy các giá trị của h tận cùng là 1 sẽ cho ra một tập tin đã sắp xong: Dó
chính là Shell Sort. Ví dụ:
Ta phải sắp xếp dãy số: 39 50 7 39 89 13 1 62
Bíc 1: 4-Sort 39 50 7 39 89 13 1 62
39 13 1 37 89 50 7 62 Bíc 2: 2-Sort
39 13 1 37 89 50 7 62 1 13 7 37 39 50 89 62
Bíc 3: 1-Sort 1 13 7 37 39 50 89 62
1 7 13 37 39 50 89 62
ThĨ hiƯn b»ng Pascal: Chó ý:
7
- Ta dïng d·y phơ chøa dé tăng h[i], ..., h[t] để điều khiển quá trình sắp xếp thứ tự với h[t]=1. Việc chộn các độ tăng thích hợp sẽ làm giảm thời gian sắp thứ tự.
- Dặt h1 = h[1] ta phải khai báo dãy a nh sau: A : Array[1..n] of Item;
các phần tử A[i] i=0 là các lính canh. Sau đây ta chọn: h[1] = 9, h[2] = 5, h[3] = 3, h[4] = 1
Procedure Shell_Sort; Const
t = 4; Var
x : Item; i,j,k,s,m: Integer;
h : Array[1..t] of Integer; Begin
h[1] = 9; h[2] = 5;
h[3] = 3; h[4] = 1;
For m := 1 to t do Begin
k := h[m]; s := -k;
For i := k+1 to n do Begin
x := A[i]; j := i - k;
If s = 0 Then s:=-k; s := s + 1;
A[s] := x; While x.KeyA[j].Key do
Begin A[j+k] :=A[j];
j := j - k; End;
A[j+k] := x; End;
End; End;
h. Quick Sort: Giải thích:
Nội dung của phơng pháp này là chọn phần tử x ở giữa của dãy làm chuẩn để so sánh. Ta phân hoạch dãy này thành 3 d·y con liªn tiÕp nhau:
- D·y con thø nhÊt gồm phần tử có khoá nhỏ hơn x.key. - Dãy con thứ hai gồm các phần tử có khoá bằng x.key.
- Dãy con thứ ba gồm các phần tử có khoá lớn hơn x.key. Sau đó áp dụng giải thuật phân hoạch này cho dãy con thứ nhất nhất và dãy con
thứ ba, nếu các dãy con có nhiều hơn một phần tử Đệ qui.
8
Cụ thể là xét một doạn của dãy từ thành phần L đến thành phần thứ R. - Lấy giá trị của thành phần thứ L+R Div 2 gán vào biến X.
- Cho i ban đầu là L. - Cho j ban đầu là R.
- Lập lại. Chừng nào còn A[i] X thì tăng i.
Chừng nào còn A[j] X thì giảm j. i=j thì
+ Hoán vị A[i] và A[j] + Tăng i
+ Giảm j Cho đến khi ij
+ Sắp xếp đoạn từ A[L] đến A[j] + Sắp xếp đoạn từ A[i] đến A[R]
Ví dụ: S¾p xÕp d·y sè:
39 50 7 37 89 13 1 62 X = 37
Sau 2 lần đổi chổ ta đợc d·y: 1 13 7 37 89 50 39 62
Xö lý d·y con: 1 13 7
Ta đợc: 1 7 13
Sö lý d·y con: 89 50 39 62
Ta đợc: 39 50 89 62
39 50 62 89 Vậy dãy đã sắp xÕp lµ:
1 7 13 39 50 62 89 Thể hiện bằng Pascal:
Để đơn giản ta viết thủ tục sắp một mảng số nguyên ®ỵc trun tham biÕn. Procedure Quick_SortVar A : Array[1..n] of Integer;
Procedure SortL,R : Integer; Var
i,j,Tg,X : Integer; Begin
X := A[L+R Div 2]; i := L;
j := R; Repeat
While A[i] X do Inci; While A[j] X do Decj;
If i = j Then Begin
9
Tg := A[i]; A[i] := A[j];
A[j] := Tg; Inci;
Decj; End;
Until ij; If L j Then SortL,j;
If i R Then Sorti,R; End;
Begin Sort1,n;
End; i. Ph¬ng pháp trọn Merging Sort
Giải thích: Nội dung của phơng pháp này là chia dãy số cần sắp thành các dãy con đã có thứ
tựgoi là các Run và có số phần tử là luỹ thừa 2 sau đó tìm cách trộn dần chúng với nhau thành các Run có thứ tự chiều dài tăng dần cho đến khi chỉ còn một Run
thì quá trình sắp xếp kết thúc. Ta có giải thuật sau đây để trộn 2 Run x và y cùng thứ tự có chiều dài lần lợt là m
vµ n thµnh mét run z cã chiỊu dµi lµ m + n. Procedure Merge;
Var i,j,k : Integer;
Begin i := 1;
j := 1; k := 1;
While i = m and j = n do Begin
If X[i] Y[j] Then Begin
Z[k] := X[j]; i := i + 1;
End Else
Begin Z[k] := Y[j]
j := j + 1; End;
k := k + 1; End;
While i=m do Begin
Z[k] := X[j]; k := k + 1;
i := i + 1;
10
End; While j=n do
Begin Z[k] := X[j];
k := k + 1; j := j + 1;
End; End;
Cụ thể là nếu ta phải sắp xếp dãy: A[1], A[2], ...,A[n]. Ta phải sử dụng 2n phần tử đợc chia thành 2 vùng. Vùng 1 gồm các phần tử
A[1] .. A[n], vùng 2 gồm các phần tử A[n+1] .. A[2n]. Ta trộn các Run từ vùng này và phân phối vào vùng kia. Khi trộn và phân phối, ta trộn các Run ngợc chiều
nhau của vùng trộn và phân phối luân phiên vào 2 đầu của vùng phân phối bớc kế tiếp dễ trộn hơn. Quá trình sắp xếp sẽ kết thúc nếu vùng phân phối chỉ còn một
Run. Khi kết thúc, nếu vùng phân phối gồm các phần tử A[n+1] .. A[2n] thì ta chép dãy A[n+1] .. A[2n] vµo d·y A[1] .. A[n]
ThĨ hiƯn b»ng Pascal Procedure mergesort l , r : integer ;
Var i , j , k , m: integer; Begin
If r-l0 then Begin
m := r+l div 2; mergesort l,m; mergesort m+1,r;
for i:=m downto l do b [i] := a [i]; for j:=m+1 to r do b [r+m+1-j] := a [j];
for k := l to r do if b[i] b [j] then
begin a [k] := b[i]; i:=i+1; end else begin a [k] := b[j]; j:=j-1; end;
end; End;
End; II. Hỡnh hc:
- Điểm là đối tợng cơ sở trong hình học. Mỗi điểm mà chúng ta xét sau đây đợc biểu diễn bằng một cặp số nguyên- toạ độ điểm đó trong hệ trục Descart thờng
dùng. - Một đoạn thẳng là một cặp điểm đợc nối với nhau bởi 1 phần của đờng thẳng.
- Một đa giác là một danh sách các điểm, với hai điểm cạnh nhau đợc nối bởi một đờng thẳng và điểm đầu nối với điểm cuối tạo thành một hình đóng.
Thông thờng chúng ta dùng một mảng để biểu diễn một đa giác, dï r»ng trong mét sè trêng hỵp ta cã thĨ dùng danh sách liên kết hay các kiểu khác. Hầu hết
trong các chơng trình chúng ta dùng kiểu sau đây: Type point = record x , y : integer; end;
line = record p1 , p2 : pointer; end; Var polygon : array [0 .. nmax] of point;
11
Chó ý r»ng c¸c điểm đợc biểu diễn trên toạ độ nguyên, cũng có thể dùng số thực nhng dùng tọa độ nguyên thì thuật toán sẽ đơn giản hơn nhiều và phép tính thực
hiện nhanh hơn đáng kể. Nhiều đối tợng hình học phức tạp sẽ đợc biểu diễn dựa trên các phần tử cơ sở
này. 1Giao các đoạn thẳng:
Trong bài học sơ cấp đầu tiên, chúng ta sẽ xét xem 2 đoạn thẳng có giao nhau hay không. Một phơng pháp dễ hiểu để giải quyết bài toán này là tìm giao điểm
của các đờng thẳng xác định bởi các đoạn thẳng ®ã råi kiĨm tra xem nã cã n»m gi÷a hai điểm đầu của hai đoạn thẳng đó hay không. Một cách dễ dàng khác là
xem thử xem đờng đi từ ®iÓm thø nhÊt sang ®iÓm thø 2 råi sang ®iÓm thứ 3 theo chiều kim đồng hồ hay ngợc chiều kim ®ång hå:
Function ccw p0 , p1 , p2 : pointer : integer; Var dx1 , dx2 , dy1 , dy2 : integer;
Begin dx1:=p1.x; dy1:=p1.y-p0.y;
dx2:=p2.x; dy2:=p2.y-p0.y; If dx1dy2dy1dx2 then ccw:=1;
If dx1dy2dy1dx2 then ccw:=1; If dx1dy2=dy1dx2 then
Begin If dx1dx20 or dy1dy20 then ccw:=-1 else
If dx1dx1+dy1dy1 = dx2dx2+dy2dy2 then ccw := 0 else ccw := 1;
End; End;
Để hiểu đợc chơng trình hoạt động nh thế nào, đầu tiên ta giả sử tất cả các giá trị dx1 , dx2 , dy1 , dy2 đều dơng. Sau đó nhận xét rằng độ dốc của đờng nối p0 với
p1 là dy1 dx1, của ®êng nèi p0 víi p2 lµ dy2 dx2. Do ®ã, nÕu ®é dèc cđa ®êng thø hai lín h¬n ®êng thø nhÊt th× ®êng ®i tõ p0 sang p1 , p2 là ngợc chiều kim
đồng hồ và ngợc lại. So sánh độ dốc hơi bất tiện vì đờng có th theo phơng thẳng đứng dx1 hay dx2 = 0 , chóng ta tÝnh tÝch dx1 dx2 để tránh trờng hợp này. Do
đó độ dốc không cần phải dơng mới đúng. Hàm ccw trả lại giá trị 0 cho trờng hợp p2 ở giữa p0 và p1, bằng -1 nếu p0 ở giữa p2 và p1 và nếu p1 ở giữa p0 và p2 thì
chúng ta gán ccw = 1. Chóng ta cã thĨ dïng trùc tiÕp ccw để cài đặt hàm intersect xét giao nhau . Nếu
cả hai đầu của một đoạn thẳng ở hai bên đoạn kia, nghĩa là có giá trị ccw khác nhau th× chóng giao nhau:
Function intersect l1 , l2 : line : boolean; Begin
intersect:= ccwl1.p1,l1.p2,l2.p1 ccwl1.p1,l1.p2,l2 .p2 = 0
and ccwl1.p1,l1.p2,l2 .p1 ccwl1.p1,l1.p2,l2 .p2 = 0;
End;
12
Giải pháp này có vẽ đã dùng một số lợng lớn tính toán để giải quyết một bài toán đơn giản. Ngời đọc hãy mạnh dạn thử tìm một phơng pháp đơn giảm hơn nhng chú
ý phải đầy đủ các trờng hợp. 2 Đờng khép kín đơn:
Để thấy đợc đặc điểm riêng của bài toán ứng với tập hợp các điểm, chúng ta xét bài toán tìm một đờng đi, qua một tập hợp n điểm xác định, qua tất cả các điểm,
không giao nhau và cuối cùng trở về điểm bắt đầu. Đờng đi nh trên gọi là đờng khép kín đơn.
Để giái quyết bài toán này ta phải chọn một điểm làm điểm gốc. Sau đó tính góc tạo bằng cách vẽ một đờng từ mỗi điểm trong tập hợp đến gốc vẽ ra theo ph-
ơng ngang. Sau đó, sắp thứ tự các điểm theo thứ tự tăng dần của góc tơng ứng, cuối cùng nối các điểm cạnh nhau lại.
Gọi dx , dy là khoảng cách từ điểm gốc đến một điểm khác theo trục hoành và tung thì góc cần tính trong giải thuật này là cotan dy dx. Nhng hàm này có vẽ
chậm, vì vậy ta có thể thay bằng một hàm khác tơng tự nhng dễ tính hơn, đó là dy dy + dx . Chơng trình sau trả lại giá trị từ 0 đến 360, không phải là góc tạo
bởi p1 và p2 so víi ph¬ng ngang nhng cã cïng thc tÝnh nh gãc ®ã. Function theta p1 , p2 : pointer : real;
Var dx , dy , ax , ay : integer; Begin
dx:=p2.x - p1.x; ax:= absdx; dy:=p2.y - p1.y; ay:= absdy;
If dx=0 and dy=0 then t:=0 else t:=dyax+ay;
If dx 0 then t:=2-t else If dy 0 then t:=4+t;
theta := t90; End;
3 Điểm nằm trong đa giác: Tiếp theo, chúng ta sẽ xét một bài toán rất tự nhiên: cho một điểm và một đa giác
biểu diễn bằng một mảng các điểm, xác định xem điểm này nằm trong hay ngoài đa giác. Một giải pháp dễ hiểu để giải bài toán này là vẽ một đọan thẳng dài bắt
đầu từ điểm đó theo một hớng bất kỳ và đếm số lợng đoạn thẳng tạo đợc do nó cắt qua đa giác. Nếu là số lẽ, điểm đó nằm trong đa giác và ngợc lại. điều này dễ thấy
nếu chúng ta theo dõi những gì xãy ra khi đi từ một điểm nằm ngoài đa giác. Tuy nhiên, không phải chỉ nh thế, bởi vì một số giao điểm có thể trùng với đa
giác, hoặc đoạn thẳng dùng để kiểm tra trùng với một cạnh của đa giác. Nhu cầu xử lý các tình huống khi các đỉnh cảu đa giác rơi trên đoạn thẳng kiểm
tra buộc chúng ta phải làm nhiều hơn là chỉ đếm số giao điểm của các cạnh đa giác với đoạn thẳng kiểm tra. Thực chất, chúng ta muốn đi vòng quanh đa giác,
tăng một biến đếm khi nào ta di từ một bên của đoạn thẳng kiểm tra sang một bên khác. Một cách để thực hiện là đơn giản bỏ qua các điểm rơi trên đoạn thẳng kiểm
tra, nh trong chơng trình sau đây: Function inside t:point:boolean;
Var count,i,j:integer; lt,lp:line;
13
Begin count:=0; j:=0; p[0]:=p[N]; p[N+1]:=p[1];
lt.p1:=t; lt.p2:=t; lt.p2.x:=maxint; For i:=1 to N do
Begin lp.p1 := p [i]; lp.p2 := p [i];
If not intersect lp,lt then Begin
lp . p2 := p [j]; j := i; If intersect lp,lt then count := count + 1;
End; End;
inside := count mod 2 = 1; End;
Chơng trình này dùng đờng thẳng kiểm tra theo phơng ngang để dễ tính toán. Biến j đợc dùng để lu trữ chỉ số của điểm cuối cùng của đa giác mà không nằm
trên đoạn kiển tra. Chơng trình giả sử rằng p [ 1 ] là điểm có tọa độ x nhỏ nhất trong số tất cả các điểm có tọa độ y nhỏ nhất, vì vậy nếu p [ 1 ] nằm trên đoạn
kiểm tra thì p [ 0 ] không thể. Cùng một đa giác có thể biểu diễn bằng N mảng khác nhau, nhng điều này cho thÊy ¸p dơng mét quy lt chn cho p [ 1 ] đôi khi
lại tiện lợi. Nếu điểm kết tiếp trên đa giác mà không nằm trên đoạn kiĨm tra, ë cïng mét phÝa nh ®iĨm thø j đối với đoạn kiểm tra thì chúng ta không cần phải
tăng biến đếm giao điểm count . Ngợc lại, chúng ta có đợc một giao điểm. Nếu đa giác chỉ có 3 hay 4 cạnh, thờng gặp trong nhiều ứng dụng thì một chơng
trình phức tạp nh vậy sẽ không đợc sử dụng, một thủ tục đơn giản đặt cơ sở trên việc gọi ccw sẽ thích hợp hơn. Một trờng hợp đặc biệt quan trọng khác lá đối với
đa giác lồi, đợc xét trong chơng kế, nó có đặc điểm là không có đoạn kiểm tra nào có hơn 2 giao điểm với đa giác. Trong trờng hợp này, một thủ tục nh tìm nhị phân
có thể dùng để xác định trong O log N bớc để biết đợc điểm có ở bên trong hay không.

III. Cặp ghép:


1. Giíi thiƯu chung:


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

S¾p xÕp trong:

Tải bản đầy đủ ngay(19 tr)

×