Tải bản đầy đủ (.ppt) (37 trang)

hoa cuong có thì sử dụng – thích thì lao vào

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 (156.76 KB, 37 trang )

<span class='text_page_counter'>(1)</span><div class='page_container' data-page=1>

1


</div>
<span class='text_page_counter'>(2)</span><div class='page_container' data-page=2>

1. Phương pháp chèn (Insertion sort)



Nội dung phương pháp:


• Xét dãy a<sub>1</sub>, …., ai-1 có thứ tự, tìm vị trí thích hợp


của ai trong dãy trên để chèn vào sao cho ta


được dãy a1, …., ai có thứ tự.


• Thực hiện với i = 2, ….., n ta được dãy a1, ….,


</div>
<span class='text_page_counter'>(3)</span><div class='page_container' data-page=3>

3


Ví dụ



1 2 3 4 5 6 7 8


7 1 6 9 3 5 4 8


1 7 6


1 6 7 9


1 6 7 9 3


1 3 6 7 9 5


1 3 5 6 7 9



</div>
<span class='text_page_counter'>(4)</span><div class='page_container' data-page=4>

Giải thuật chèn



• <sub>Thực hiện với i=2 , …, n:</sub>
1. x = ai


2. j = i-1


3. Khi (j>0) Λ (x<aj)


3. 1 a<sub>j+1</sub>=a<sub>j</sub>
3. 2 j = j-1


</div>
<span class='text_page_counter'>(5)</span><div class='page_container' data-page=5>

5


Độ phức tạp



• Số phép gán:


• Số phép so sánh:


</div>
<span class='text_page_counter'>(6)</span><div class='page_container' data-page=6>

Cài đặt



<i><b>void insertionsort(elem a[], int n, int (*comp)(elem, elem))</b></i>
<i><b>{</b></i>


<i><b>int i, j, sz=sizeof(elem);</b></i>
<i><b>elem x;</b></i>


<i><b>for (i=1; i<n; i++)</b></i>


<i><b>{</b></i>


<i><b>memcpy(&x, &a[i], sz);</b></i>
<i><b>j = i-1;</b></i>


<i><b>while (j>=0 && comp(x, a[j])<0)</b></i>
<i><b>{</b></i>


<i><b>memcpy(&a[j+1], &a[j], sz);</b></i>
<i><b>j--;</b></i>


<i><b>}</b></i>


</div>
<span class='text_page_counter'>(7)</span><div class='page_container' data-page=7>

7


2. Phương pháp chọn (Selection sort)



Nội dung phương pháp:


• Chọn phần tử nhỏ nhất trong dãy a<sub>i</sub>, …., an là ak


• Hốn đổi phần tử ai với ak.


Thực hiện với i = 1, ….., n-1 ta được dãy a1, ….,


</div>
<span class='text_page_counter'>(8)</span><div class='page_container' data-page=8>

Ví dụ



1 2 3 4 5 6 7 8


7 1 6 9 3 5 4 8



1 7 6 9 3 5 4 8


1 3 6 9 7 5 4 8


1 3 4 9 7 5 6 8


1 3 4 5 7 9 6 8


1 3 4 5 6 9 7 8


</div>
<span class='text_page_counter'>(9)</span><div class='page_container' data-page=9>

9


Giải thuật chọn



• <sub>Với i=1 , …, n-1, thực hiện:</sub>
1. k=i


2. x = a<sub>k</sub>


3. Với j = i+1, …, n, thực hiện:


Nếu x>aj


– k=j


– x=ak


</div>
<span class='text_page_counter'>(10)</span><div class='page_container' data-page=10>

Độ phức tạp




• Số phép gán:


• Số phép so sánh:


</div>
<span class='text_page_counter'>(11)</span><div class='page_container' data-page=11>

11


Cài đặt



<i><b>void selectionsort(elem a[], int n, int (*comp)(elem, elem))</b></i>
<i><b>{ int i, j, k, sz=sizeof(elem);</b></i>


<i><b>elem x;</b></i>


<i><b>for (i=0; i<n-1; i++)</b></i>
<i><b>{</b></i>


<i><b>k = i;</b></i>


<i><b>memcpy(&x, &a[k], sz);</b></i>
<i><b>for (j=i+1; j<n; j++)</b></i>


<i><b>if (comp(x, a[j])>0)</b></i>
<i><b>{</b></i>


<i><b>k = j;</b></i>


<i><b>memcpy(&x, &a[k], sz);</b></i>
<i><b>}</b></i>


<i><b>memcpy(&a[k], &a[i], sz);</b></i>


<i><b>memcpy(&a[i], &x, sz);</b></i>
<i><b>}</b></i>


</div>
<span class='text_page_counter'>(12)</span><div class='page_container' data-page=12>

Cài đặt



<i><b>void selectionsort(elem a[], int n, int (*comp)(elem, elem))</b></i>
<i><b>{ int i, j, k, sz=sizeof(elem);</b></i>


<i><b>elem x;</b></i>


<i><b>for (i=0; i<n-1; i++)</b></i>
<i><b>{</b></i>


<i><b>k = i;</b></i>


<i><b>for (j=i+1; j<n; j++)</b></i>


<i><b>if (comp(a[k], a[j])>0)</b></i>
<i><b>k = j;</b></i>


<i><b>memcpy(&x, &a[k], sz);</b></i>
<i><b>memcpy(&a[k], &a[i], sz);</b></i>
<i><b>memcpy(&a[i], &x, sz);</b></i>
<i><b>}</b></i>


</div>
<span class='text_page_counter'>(13)</span><div class='page_container' data-page=13>

13


3. Phương pháp đổi chổ



Nội dung phương pháp:



Duyệt qua dãy, nếu 2 phần tử kề nhau không
thứ tự thì hốn đổi


Thực hiện cho đến khi dãy có thứ tự
Thuật giải nổi bọt (Bubble sort)


</div>
<span class='text_page_counter'>(14)</span><div class='page_container' data-page=14>

Thuật giải (C)



for (i=1; i<n; i++)


for (j=n-1; j>=i; j--)
if (a[j]<a[j-1])


swap(a[j], a[j-1]);


</div>
<span class='text_page_counter'>(15)</span><div class='page_container' data-page=15>

15


Sap thu tu - phuong phap noi bot



void bubblesort(elem a[], int n, int (*comp)(elem, elem))
{


int i, j, sz=sizeof(elem);
elem x;


for (i=1; i<n; i++)
for (j=n-1; j>=i; j--)


if (comp(a[j], a[j-1])<0)


{


memcpy(&x, &a[j], sz);


memcpy(&a[j], &a[j-1], sz);
memcpy(&a[j-1], &x, sz);
}


</div>
<span class='text_page_counter'>(16)</span><div class='page_container' data-page=16>

Thuật giải BS có sử dụng cờ(C)



i=1;
do {


OK = 1;


for (j=n-1; j>=i; j--)
if (a[j]<a[j-1])
{


swap(a[j], a[j-1]);
OK = 0;


</div>
<span class='text_page_counter'>(17)</span><div class='page_container' data-page=17>

17


Thuật giải Sàng (Shaker sort)



Nội dung phương pháp:


Thực hiện lặp 2 quá trình liên tiếp:
Duyệt từ phải qua trái: Nổi bọt



Duyệt từ trái qua phải: Lắng đọng


Mỗi q trình ghi nhận vị trí hóa đổi sau cùng
làm điểm xuất phát cho quá trình tiếp theo


</div>
<span class='text_page_counter'>(18)</span><div class='page_container' data-page=18>

Thuật giải Shaker sort(C)



l = 1;


r = k = n-1;
do {


for (j=r; j>=l; j--)
if (a[j]<a[j-1])
{


swap(a[j], a[j-1]);
k = j;


}


l = k+1;


for (j=l; j>=r; j++)
if (a[j]<a[j-1])
{


swap(a[j], a[j-1]);
k = j;



}
r = k-1;


</div>
<span class='text_page_counter'>(19)</span><div class='page_container' data-page=19>

19


</div>
<span class='text_page_counter'>(20)</span><div class='page_container' data-page=20>

1. Giải thuật “vun đống” (Heap sort)



<i>Cải tiến từ phương pháp chọn</i>
Định nghĩa:


• Heap: Là cấu trúc cây nhị phân đầy đủ theo
nghĩa: các nút được bố trí tuần tự từ mức thấp
đến mức cao, từ trái qua phải


</div>
<span class='text_page_counter'>(21)</span><div class='page_container' data-page=21>

21


Giải thuật “vun đống” (Heap sort)



• Heap max (min): Là cấu trúc heap thỏa điều
kiện : mọi nút đều có khóa lớn (nhỏ) hơn 2 con
Ví dụ:


9


6
8


7 0 3



5


2
1


</div>
<span class='text_page_counter'>(22)</span><div class='page_container' data-page=22>

Tổ chức heap từ dãy



• Với dãy a1, a2, ….. an ta tổ chức thành cấu trúc


heap như sau:


ai có 2 con là a2i và a2i+1


Vẽ lại


a<sub>1</sub> a<sub>2</sub> a<sub>3</sub> a<sub>4</sub> a<sub>5</sub> a<sub>6</sub> a<sub>7</sub>


a<sub>1</sub>


a<sub>2</sub> a3


a<sub>6</sub>
a<sub>5</sub>


</div>
<span class='text_page_counter'>(23)</span><div class='page_container' data-page=23>

23


Khởi tạo heap max ban đầu



• Ta có ai với i=n/2+1, … n là các nút lá trên cây



nên hiển nhiên thỏa mãn tính chất heap max


• Để khởi tạo heap max ban đầu ta tìm cách <i><b>biến </b></i>
<i><b>đổi a</b><b>i</b></i> (với i=n/2, …, 1) thành heap max khi ai+1,


…, <i><b>a</b><b><sub>n</sub></b></i> thỏa heap max


a<sub>1</sub>


a<sub>2</sub> a3


a<sub>6</sub>
a<sub>5</sub>


a<sub>4</sub> a<sub>7</sub>


a<sub>10</sub>
a<sub>9</sub>


</div>
<span class='text_page_counter'>(24)</span><div class='page_container' data-page=24>

Sắp thứ tự



• Khi i=1 ta có dãy thỏa mãn tính chất heap max,
nghĩa là a1 là phần tử lớn nhất


• Để sắp thứ tự, phần tử lớn nhất phải nằm cuối
nên ta hoán đổi phần tử a1 với an


<i><b>• Biến đổi</b></i> a<i><b><sub>1</sub></b></i> thành heap max khi a<sub>2</sub>, …, <i><b>a</b><b><sub>n-1</sub></b></i> thỏa
heap max



</div>
<span class='text_page_counter'>(25)</span><div class='page_container' data-page=25>

25


Giải thuật biến đổi heap max (q, r)



4


9 7


1
8


6 0


3
2


5


9


8 7


1
4


6 0


3
2



5


</div>
<span class='text_page_counter'>(26)</span><div class='page_container' data-page=26>

9


8 7


1
4


6 0


3
2


5


3


8 7


1
4


6 0


9
2


5



</div>
<span class='text_page_counter'>(27)</span><div class='page_container' data-page=27>

27


8


6 7


1
4


5 0


9
2


3


2


6 7


1
4


5 0


9
8


</div>
<span class='text_page_counter'>(28)</span><div class='page_container' data-page=28>

2



6 7


1
4


5 0


9
8


3


2


7


6 2


1
4


5 0


9
8


</div>
<span class='text_page_counter'>(29)</span><div class='page_container' data-page=29>

29


• Tiếp tục thực hiện cho đến khi dãy có thứ tự



3


6 2


1
4


5 0


9
8


</div>
<span class='text_page_counter'>(30)</span><div class='page_container' data-page=30>

Giải thuật biến đổi heap max (q, r)



1. Khởi tạo
– x = a<sub>q</sub>
– i=q
– j=2i


– cont=true


2. Khi (j<=r) Λ cont, thực hiện:


2.1 Nếu (j<r) Λ (aj<aj+1) thì j=j+1


2.2 Nếu x<a<sub>j</sub> thì
– a<sub>i</sub> = a<sub>j</sub>
– i=j


– j=2i


2.3 Ngược lại


</div>
<span class='text_page_counter'>(31)</span><div class='page_container' data-page=31>

31


Sắp thứ tự



1. Khởi tạo heap max ban đầu
Với i=n/2, …, 1. Thực hiện:


Biến đổi heap max(i, n)
2. Sắp thứ tự


– i=n
– Lặp


• Hốn đổi a1 với ai


• i = i-1


</div>
<span class='text_page_counter'>(32)</span><div class='page_container' data-page=32>

<i><b>void sift(elem a[ ], int q, int r, int (*comp)(elem, elem))</b></i>
<i><b>{</b></i>


<i><b>elem x;</b></i>


<i><b>int i, j, cont =1, sz = sizeof(elem);</b></i>
<i><b>i = q;</b></i>


<i><b>j = 2*i+1;</b></i> <i><b>//lưu ý</b></i>
<i><b>memcpy(&x, &a[i], sz);</b></i>



<i><b>while (j<=r && cont)</b></i>
<i><b>{</b></i>


<i><b>if (j<r && comp(a[j], a[j+1])<0) j++;</b></i>
<i><b>if (comp(x, a[j]) <0)</b></i>


<i><b>{</b></i>


<i><b>memcpy(&a[i], &a[j], sz);</b></i>
<i><b>i = j;</b></i>


<i><b>j = 2*i+1;</b></i> <i><b>//lưu ý</b></i>
<i><b>}</b></i>


<i><b>else</b></i>


</div>
<span class='text_page_counter'>(33)</span><div class='page_container' data-page=33>

33

<b>Hàm Heapsort</b>



<i><b>void heapsort(elem a[ ], int n, int (*comp)(elem, elem))</b></i>
<i><b>{</b></i>


<i><b>int i, sz = sizeof(elem);</b></i>
<i><b>elem x;</b></i>


<i><b>for (i=n/2-1; i>=0; i--)</b></i> <i><b>//lưu ý n/2-1 và 0</b></i>


<i><b>sift(a, i, n-1, comp);</b></i>
<i><b>i = n-1;</b></i>



<i><b>do {</b></i>


<i><b>memcpy(&x, &a[0], sz);</b></i> <i><b>//lưu ý a[0]</b></i>


<i><b>memcpy(&a[0], &a[i], sz);</b></i>
<i><b>memcpy(&a[i], &x, sz);</b></i>
<i><b>i--;</b></i>


<i><b>sift(a, 0, i, comp);</b></i> <i><b>//0</b></i>


</div>
<span class='text_page_counter'>(34)</span><div class='page_container' data-page=34>

2. Giải thuật Quick sort



• Cải tiến từ phương pháp đổi chổ
• Dựa trên phép phân hoạch:


• Chọn giá trị phân hoạch x thỏa:


Min { ai } ≤ x ≤ Max { ai }


– Dị tìm từ trái (l) qua phải phần tử ai ≥ x


– Dị tìm từ phải (r) qua trái phần tử aj ≤ x


– Nếu i < j thì hốn đổi ai với aj


• Tiếp tục thực hiện cho đến khi i>j


Kết quả dãy sẽ bị phân hoạch thành 2 dãy:
<i>Dãy từ l đến j mang giá trị ≤ x</i>



<i>Dãy từ i đến r mang giá trị ≥ x</i>


</div>
<span class='text_page_counter'>(35)</span><div class='page_container' data-page=35>

35


<i><b>void sort(elem a[ ], int l, int r, int (*comp)(elem, elem))</b></i>
<i><b>{</b></i>


<i><b>static elem x, t;</b></i>


<i><b>int i, j, sz = sizeof(elem);</b></i>
<i><b>i = l;</b></i>


<i><b>j = r;</b></i>


<i><b>memcpy(&x, &a[(l+r)/2], sz);</b></i>
<i><b>do {</b></i>


<i><b>while (comp(a[i], x)<0) i++;</b></i>
<i><b>while (comp(a[j], x)>0) j--;</b></i>
<i><b>if (i<=j)</b></i>


<i><b>{</b></i>


<i><b>memcpy(&t, &a[i], sz);</b></i>
<i><b>memcpy(&a[i], &a[j], sz);</b></i>
<i><b>memcpy(&a[j], &t, sz);</b></i>
<i><b>i++;</b></i>


<i><b>j--;</b></i>
<i><b>}</b></i>



<i><b>} while (i<=j);</b></i>


</div>
<span class='text_page_counter'>(36)</span><div class='page_container' data-page=36>

<i><b>void qsort(elem a[ ], int n, int (*comp)(elem, elem))</b></i>
<i><b>{</b></i>


</div>
<span class='text_page_counter'>(37)</span><div class='page_container' data-page=37>

37


Bài tập



• Viết


– Quick sort 1 lời gọi đệ quy
– Quick sort không đệ quy


– Chương trình nhập 1 dãy số ngun, đưa:


• Lẻ về đầu dãy và sắp thứ tự tăng


</div>

<!--links-->

×