Tải bản đầy đủ (.pdf) (117 trang)

Chapter 1 algorithm and algorithm complexity

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 (1.26 MB, 117 trang )

<span class="text_page_counter">Trang 1</span><div class="page_container" data-page="1">

Advanced algorithms

</div><span class="text_page_counter">Trang 2</span><div class="page_container" data-page="2">

Chapter 1.

Algorithm and algorithm complexity

</div><span class="text_page_counter">Trang 3</span><div class="page_container" data-page="3">

Algorithm and algorithm complexity

Problem (in informatics)

</div><span class="text_page_counter">Trang 4</span><div class="page_container" data-page="4">

BÀI TỐN

• Trong phạm vi tin học, ta xem bài toán là một cơng việc nào đó mà ta muốn máy tính thực hiện.

• Khi dùng máy tính giải bài tốn, ta cần quan tâm trước hết đến hai yếu tố: đưa vào máy tính thơng tin gì (Input) và cần lấy ra thơng tin gì (Output) ?

• Do đó, để phát biểu một bài tốn tacần phải trình bày rõ Input và Outputcủa bài tốn đó và mối quan hệ giữaInput và Output.

</div><span class="text_page_counter">Trang 5</span><div class="page_container" data-page="5">

Ví dụ

<i>• Giải phương trình dạng ax</i>

<small>2</small>

<i>+ bx + c = 0</i>

<i>• Tìm tất cả phương án để đặt n quân hậu trên bàn cờ n  n</i>

<i>• Cho dãy n số, tìm dãy con tăng dài nhất (dãy con này không</i>

nhất thiết chứa các phần tử liên tiếp nhau)

• Tìm một số ngun tố lớn (từ hàng nghìn đến hàng triệu chữ số)

• Tính 2

<small>1000</small>

</div><span class="text_page_counter">Trang 6</span><div class="page_container" data-page="6">

THUẬT TỐN

Thuật tốnđể giải một bài toán là một dãy hữu hạn các thao tác được sắp xếp theo một trình tự xác định sao cho sau khi thực hiện dãy thao tác ấy, từ Input của bài toán, ta nhận được Output của bài toán.

<small>Although there is no universally agreed-on wording to describe this notion, there is general agreement about what the concept </small>

</div><span class="text_page_counter">Trang 7</span><div class="page_container" data-page="7">

<i>• Đầu ra (Output): Với mỗi tập các dữ liệu đầu vào, thuật </i>

toán đưa ra các dữ liệu tương ứng với lời giải của bài tốn.

<i>• Chính xác (Precision): Các bước của thuật tốn được mơ </i>

tả chính xác.

<i>• Hữu hạn (Finiteness): Thuật toán cần phải đưa được đầu </i>

ra sau một số hữu hạn (có thể rất lớn) bước với mọi đầu vào.

<i>• Đơn trị (Uniqueness): Các kết quả trung gian của từng </i>

bước thực hiện thuật toán được xác định một cách đơn trị và chỉ phụ thuộc vào đầu vào và các kết quả của các bước trước.

<i>• Tổng qt (Generality): Thuật tốn có thể áp dụng để giải </i>

</div><span class="text_page_counter">Trang 8</span><div class="page_container" data-page="8">

Ngôn ngữ biểu diễn thuật tốn

• Ngơn ngữ sơ đồ khối • Ngơn ngữ mã giả

• Ngơn ngữ lập trình• Ngơn ngữ tự nhiên

</div><span class="text_page_counter">Trang 9</span><div class="page_container" data-page="9">

của thuật toán là đánh giá lượng tài nguyên các loại mà thuật toán địi hỏi sử dụng. Có hai loại tài ngun quan trọng: Thời gian

<i>(thời gian tính ) và bộ nhớ.</i>

<i>• Khi nói đến độ phức tạp là ý nóiđến độ phức tạp thời gian tính.</i>

</div><span class="text_page_counter">Trang 10</span><div class="page_container" data-page="10">

Kích thước dữ liệu đầu vào của bài toán

Ta gọi kích thước dữ liệu đầu vào (hay độ dài dữ liệu vào) của bài tốn là số bít cần thiết để biểu diễn nó.

Ta sẽ tìm cách đánh giá thời gian tính của thuật tốn bởi một hàm của độ dài dữ liệu vào.

Thời gian tính của thuật tốn phụ thuộcvào dữ liệu vào.

</div><span class="text_page_counter">Trang 11</span><div class="page_container" data-page="11">

Phép toán cơ bản

Ta gọi phép toán cơ bản là phép toán có thể thực hiện với thời gian bị chặn bởi một hằng số khơng phụ thuộc vào kích thước dữ liệu.

Phép toán so sánh, phép gán

Phép toán cơ bản: Đo thời gian tính bằng đơn vị đo nào ?

Số lượng phép tốn mà ta cần máy tínhthực hiện.

</div><span class="text_page_counter">Trang 12</span><div class="page_container" data-page="12">

Các loại thời gian tính

Để tính tốn thời gian tính của thuật tốn ta

<i>sẽ đếm số phép tốn cơ bản mà nó phải</i>

thực hiện.

<small>• Thời gian tối thiểu cần thiết để thực hiệnthuật toán với mọi bộ dữ liệu đầu vào kích</small>

<i><small>thước n. Thời gian như vậy sẽ được gọi là thời</small></i>

<small>gian tính tốt nhất của thuật tốn với đầu vào</small>

<i><small>kích thước n.</small></i>

<small>• Thời gian nhiều nhất cần thiết để thực hiệnthuật toán với mọi bộ dữ liệu đầu vào kích</small>

<i><small>thước n. Thời gian như vậy sẽ được gọi là thời</small></i>

<small>gian tính kém nhất của thuật tốn với đầu vào</small>

<i><small>kích thước n.</small></i>

<small>• Thời gian trung bình cần thiết để thực hiệnthuật toán trên tập hữu hạn các đầu vào kích</small>

<i><small>thước n. Thời gian như vậy sẽ được gọi là thời</small></i>

</div><span class="text_page_counter">Trang 14</span><div class="page_container" data-page="14">

<i>• Ta nói g(n) là cận trên tiệm cận của</i>

<i>f(n) và viết f(n)  O(g(n)) hoặc f(n)</i>

<i>=O(g(n)).</i>

</div><span class="text_page_counter">Trang 17</span><div class="page_container" data-page="17">

Cách nói về thời gian tính

<i>• Câu nói “thời gian tính là O(f(n))” hiểu là:</i>

đánh giá trong tình huống kém nhất là

<i>O(f(n)). Thường nói: “Đánh giá thời gian</i>

tính trong tình huống kém nhất là

<i>O(f(n))”; nghĩa là thời gian tính trong tình</i>

huống tồi nhất được xác định bởi một

<i>hàm nào đó g(n)  O(f(n)).</i>

• Câu nói “thời gian tính là<i>(f(n))” hiểu là:</i>

đánh giá trong tình huống tốt nhất là

<i>(f(n)). Thường nói: “Đánh giá thời gian</i>

tính trong tình huống tốt nhất là

<i>(f(n))”; nghĩa là thời gian tính trong tình</i>

huống tốt nhất được xác định bởi một

<i>hàm nào đó g(n) </i><i>(f(n)).</i>

</div><span class="text_page_counter">Trang 18</span><div class="page_container" data-page="18">

<i><small>Thuật tốn có đánh giá thời gian tính là O(nk</small></i><small>) được gọi làthuật tốn thời gian tính đa thức (hay vắn tắt: thuật toán đathức). Các thuật toán đa thức được coi là thuật tốn hiệuquả. Các thuật tốn với thời gian tính hàm mũ là không hiệu</small>

</div><span class="text_page_counter">Trang 19</span><div class="page_container" data-page="19">

Cận trên và cận dưới

<i>• Cận trên (Upper bound): Cho bài tốn P,ta nói cận trên cho thời gian tính của P làO(g(n)) nếu để giải P tồn tại thuật toángiải với thời gian tính là O(g(n)).</i>

<i>• Cận dưới (Lower bound): Cho bài tốn P,ta nói cận dưới cho thời gian tính của P</i>

là<i>(g(n)) nếu mọi thuật tốn giải P đều</i>

có thời gian tính là<i>(g(n)).</i>

<i>• Ta nói thời gian tính của P là (g(n)) nếuP có cận trên là O(g(n)) và cận dưới là</i>

<i>(g(n)).</i>

</div><span class="text_page_counter">Trang 20</span><div class="page_container" data-page="20">

Bài toán dễ

giải – khó giải-khơng giải

• Bài tốn dễ giải • Bài tốn khó giải

• Bài tốn khơng giải được

</div><span class="text_page_counter">Trang 21</span><div class="page_container" data-page="21">

Bài tốn dễ giải

• Một bài tốn được gọi là dễ giải nếu như nó có thể giải được bởi thuật toán đa thức Ví dụ:

<small>✓ bài tốn tìm dãy con liên tiếp có tổng lớn nhất, </small>

<i><small>✓ sắp xếp dãy n số,…</small></i>

</div><span class="text_page_counter">Trang 22</span><div class="page_container" data-page="22">

Bài tốn khó giải

<small>• Một bài tốn được gọi là khó giải nếu như nó khơng thể giải được bởi thuật toán đa thức</small>

<small> Ví dụ:</small>

<i><small>✓ bài tốn liệt kê các hoán vị của n số,</small></i>

<i><small>✓ bài toán liệt kê các dãy nhị phân chiều dài n. </small></i>

<small>• Một dạng bài tốn nữa cũng được xem là khó giải: Đó là những bài toán cho đến hiện tại vẫn chưa tìm được thuật tốn đa thức để giải.</small>

<small> Ví dụ:</small>

<small>✓ bài tốn cái túi, </small>

<small>✓ bài toán người đi du lịch,…</small>

<small>❖ Tham khảo “Bài toán tổ hợp” ở các trang tiếp theo.</small>

</div><span class="text_page_counter">Trang 23</span><div class="page_container" data-page="23">

Bài tốn khơng giải được

• Một bài tốn được gọi là không giải được nếu như không tồn tại thuật tốn để giải Ví dụ:

<small>✓ bài tốn về tính dừng, </small>

<small>✓ bài tốn về nghiệm nguyên của đa thức,…</small>

</div><span class="text_page_counter">Trang 24</span><div class="page_container" data-page="24">

Đánh giá độ phức tạp của thuật toán bằng một số quy tắc

• Để xác định độ phức tạp tính tốn của một thuật tốn bất kỳ có thể dẫn tới những bài tốn phức tạp.

• Tuy nhiên trong thực tế, đối với một số thuật toán ta cũng có thể phân tích được bằng một số quy tắc sau:

✓ Quy tắc cộng✓ Quy tắc nhân

</div><span class="text_page_counter">Trang 25</span><div class="page_container" data-page="25">

•Quy tắc cộng

<i>Giả sử T</i>

<sub>1</sub>

<i>(n) và T</i>

<sub>2</sub>

<i>(n) là thời gian thực hiện của hai đoạn chương trình P</i>

<sub>1</sub>

<i> và P</i>

<sub>2</sub>

<i>T</i>

<sub>1</sub>

<i>(n)=O(f(n)); T</i>

<sub>2</sub>

<i>(n)=O(g(n)) thì thời gian thực hiện P</i>

<sub>1</sub>

<i> rồi P</i>

<sub>2</sub>

<i> tiếp theo sẽ là T</i>

<sub>1</sub>

<i>(n)+ </i>

<i>T</i>

<sub>2</sub>

<i>(n)=O(max(f(n),g(n))</i>

</div><span class="text_page_counter">Trang 26</span><div class="page_container" data-page="26">

for (i=1;i<=n;i++) <cơng việc>

Ví dụ: Hãy đánh giá độ phức tạp của đoạn lệnh sau

</div><span class="text_page_counter">Trang 27</span><div class="page_container" data-page="27">

•Quy tắc nhân

<i>Giả sử T</i>

<sub>1</sub>

<i>(n) và T</i>

<sub>2</sub>

<i>(n) là thời gian thực hiện của hai đoạn chương trình P</i>

<sub>1</sub>

<i> và P</i>

<sub>2</sub>

<i>T</i>

<sub>1</sub>

<i>(n)=O(f(n)); T</i>

<sub>2</sub>

<i>(n)=O(g(n)) thì thời gian thực hiện P</i>

<sub>1</sub>

<i> và P</i>

<sub>2</sub>

lồng nhau sẽ là

<i>T</i>

<sub>1</sub>

<i>(n)×T</i>

<sub>2</sub>

<i>(n)=O(max(f(n) ×g(n)).</i>

</div><span class="text_page_counter">Trang 29</span><div class="page_container" data-page="29">

THUẬT TỐN ĐỆ QUI

• Thuật tốn đệ quy là thuật tốn tự gọi đến chính nó với kích thước dữ liệu đầu vào nhỏ hơn để dần đi đến kết thúc thuật tốn.

• Việc phát triển thuật toán đệ quy là thuận tiện khi cần xử lý với các đối tượng được định nghĩa đệ quy (biểu thức quy nạp, cây có gốc,…).

</div><span class="text_page_counter">Trang 30</span><div class="page_container" data-page="30">

Sơ đồ thuật tốn đệ qui

<i>void Reccursive(Input){</i>

<i>if (kích thước của Input là nhỏ nhất)Thực hiện Bước cơ sở;</i>

<i>else {</i>

<i><small>RecAlg (Input với kích thước nhỏ hơn); /* Bước đệ quy */</small></i>

<i><small>/*Có thể có thêm những lệnh gọi đệ quy */</small></i>

<i><small>Tổ hợp lời giải của các bài toán con để thu được Lờigiải;</small></i>

<i><small>return Lờigiải;</small></i>

<i>}</i>

</div><span class="text_page_counter">Trang 31</span><div class="page_container" data-page="31">

Ví dụ

Tìm số hạng thứ n của dãy Fibonacci

</div><span class="text_page_counter">Trang 32</span><div class="page_container" data-page="32">

Đệ quy có nhớ

• Ta sẽ dùng biến ghi nhớ lại thông tin về lời giải của các bài toán con ngay sau lần đầu tiên nó được giải.

• Điều đó cho phép rút ngắn thời gian tính của thuật tốn, bởi vì, mỗi khi cần đến có thể tra cứu mà khơng phải giải lại những bài toán con đã được giải trước đó.

</div><span class="text_page_counter">Trang 34</span><div class="page_container" data-page="34">

Ví dụ 1

liên tiếp là dãy mà thành phần của nó là các

<i>thành phần liên tiếp nhau trong {a}, ta gọi</i>

tổng của dãy con là tổng tất cả các thành

</div><span class="text_page_counter">Trang 35</span><div class="page_container" data-page="35">

Thuật tốn 1

• Xét tất cả các cặp số

<i>nguyên L và U thỏa mãn1  L  U  n;</i>

• Đối với mỗi cặp như vậy ta tính tổng của dãy con

</div><span class="text_page_counter">Trang 37</span><div class="page_container" data-page="37">

Thuật tốn 3

<small>• Tổng lớn nhất trong dãy con</small>

<i><small>a[1..i] là tổng lớn nhất trong dãy</small></i>

<i><small>con a[1..i-1] (gọi là maxsofar)</small></i>

<small>hoặc tổng lớn nhất trong tất cảcác tổng của các dãy con kết</small>

<i><small>thúc tại i (gọi là maxendinghere).</small></i>

<small>• Chúng ta có nhận xét rằng: Dãy</small>

<i><small>con lớn nhất kết thúc tại i là dãycon lớn nhất kết thúc tại vị trí i-1được bổ sung thêm phần tử a[i]</small></i>

<small>ở cuối hoặc là dãy con rỗngtrong trường hợp tổng của dãycon nhận được là số âm. Ta cóthuật tốn như sau:</small>

<i><small>void algorithm3(int a[], int n)</small></i>

</div><span class="text_page_counter">Trang 38</span><div class="page_container" data-page="38">

Ví dụ 2

chuyển k phần tử đầu dãy về cuối dãy. Yêu cầu không dùng mảng trung gian.

</div><span class="text_page_counter">Trang 39</span><div class="page_container" data-page="39">

Thuật toán 1

Để dịch chuyển một phần tử đầu dãy về cuối dãy, ta thực hiện 3 bước sau: Chuyển một phần tử đầu dãy vào biến tạm; dịch chuyển tất cả các phần tử của dãy về bên trái một vị trí; gán phần tử cuối dãy bằng giá trị của biến tạm. Dễ thấy độ phức tạp của công đoạn

<i>gồm 3 bước trên là O(n); do vậy đểdịch chuyển k phần tử đầu dãy về cuối</i>

</div><span class="text_page_counter">Trang 40</span><div class="page_container" data-page="40">

Thuật toán 2

Sử dụng thuật toán chia để trị để giải bài toán trên với độ phức

<i>tạp O(n).</i>

<i><small>✓ Đảođoạn(1,k);✓ Đảođoạn (k+1,n);✓ Đảođoạn (1,n);</small></i>

<i><small>Việc Đảođoạn (u,v) là đơn giản; được thực hiện bằng thời gian O(n) như sau: </small></i>

<i><small>void sequence_reverse(int a[], int u, int v){</small></i>

<i><small>while (u<v)</small></i>

<i><small>swap(a[u++], a[v--]);// hàm hoán đổi giá trị 2 biến</small></i>

<i><small>Thuật tốn giải bài tốn này có độ phức tạp O(n).</small></i>

<i><small>void solve(int a[], int n, int k){</small></i>

<i><small>sequence_reverse(a,1,k);sequence_reverse(a,k+1,n);sequence_reverse(a,1,n);</small></i>

</div><span class="text_page_counter">Trang 41</span><div class="page_container" data-page="41">

Ví dụ 3

Cho dãy n số nguyên a<sub>1</sub>,a<sub>2</sub>,….a<sub>n</sub> (n ≤ 10<small>6</small>).

Hãy tìm 3 số sao cho tích của chúng là lớn nhất (xuất tích lớn nhất tìm

</div><span class="text_page_counter">Trang 42</span><div class="page_container" data-page="42">

<i><small>for (int i=1;i<=n-2;i++)for (int j=i+1;j<=n-1;j++)</small></i>

</div><span class="text_page_counter">Trang 44</span><div class="page_container" data-page="44">

Thuật tốn 3

<small>• Tìm 3 số lớn nhất max1, max2, max3• Tìm 2 số nhỏ nhất min1,min2</small>

<small>• Đặt p= max1 * max2 * max3; q= max1 * min1 * min2• So sánh p,q để tìm ra kết quả</small>

</div><span class="text_page_counter">Trang 45</span><div class="page_container" data-page="45">

BÀI TẬP

</div><span class="text_page_counter">Trang 46</span><div class="page_container" data-page="46">

Trình bày thuật tốn và đánh giá độ phức tạp của các thuật toán giải các bài toán sau

Bài tập 1

<small>.</small>

<i>Cho dãy gồm n số nguyên a</i><sub>1</sub><i>,a</i><sub>2</sub><i>,…,a<sub>n </sub></i>(<i>n  10</i><small>6</small>).

Tìm một dãy con liên tiếp tăng dài nhất. Xuất chiều dài của dãy tìm

</div><span class="text_page_counter">Trang 47</span><div class="page_container" data-page="47">

Bài tập 2.

trên có bao nhiêu số có giá trị đơi một khác nhau ?

</div><span class="text_page_counter">Trang 48</span><div class="page_container" data-page="48">

Bài tập 3.

<i>Cho số nguyên dương p, ước số nguyên dương không kể chính nó gọi là ướcsố thực sự của p. Ví dụ 10 có 3 ước số thực sự là 1,2 và 5.</i>

<i>Hãy đếm xem có bao nhiêu cặp số nguyên dương p,q với 1<p,q < M (với</i>

<i>M<=10</i><small>6</small><i>) sao cho tổng các ước số thực sự của p bằng q và tổng các ước sốthực sự của q bằng p.</i>

</div><span class="text_page_counter">Trang 49</span><div class="page_container" data-page="49">

Bài tập 4.

</div><span class="text_page_counter">Trang 50</span><div class="page_container" data-page="50">

Special sorting algorithms

</div><span class="text_page_counter">Trang 51</span><div class="page_container" data-page="51">

• Running time analysis for

uncomparison sorting algorithms • Conclusion

• Exercise

</div><span class="text_page_counter">Trang 52</span><div class="page_container" data-page="52">

GIỚI THIỆU BÀI TOÁN SẮP XẾP

</div><span class="text_page_counter">Trang 53</span><div class="page_container" data-page="53">

nguyên, số thực, xâu ký tự hoặc là các đối tượng dữ liệu khác;

• Khóa sắp xếp là bộ phận của bảnghi; khóa xác định thứ tự sắp xếpcủa bản ghi trong họ các bản ghi;

</div><span class="text_page_counter">Trang 55</span><div class="page_container" data-page="55">

Ứng dụng của bài tốn sắp

• Quản trị cơ sở dữ liệu, • Trong các máy tìm kiếm,

• Sắp xếp là một cơng đoạn quan trọng hỗ trợ giải quyết một vấn đề tin học hiệu quả,…

</div><span class="text_page_counter">Trang 56</span><div class="page_container" data-page="56">

Sắp xếp nội

(internal sort)

• Các thuật tốn sắp xếp địi hỏi tồnbộ dữ liệu cần sắp xếp được đưa vàobộ nhớ trong của máy tính.

</div><span class="text_page_counter">Trang 57</span><div class="page_container" data-page="57">

Thuật tốn sắp xếp dựa vào phép so sánh

Các thuật toán sắp xếp mà việc xác định thứ tự của các phần tử dựa vào phép so sánh được gọi là các thuật toán sắp xếp dựa vào

</div><span class="text_page_counter">Trang 58</span><div class="page_container" data-page="58">

<i>nhất tìm được là O(n log n);</i>

• Đây là thời gian tính tốt nhất củadạng thuật toán này và về mặt lýthuyết là khơng thể cải thiện hơnđược nữa.

</div><span class="text_page_counter">Trang 59</span><div class="page_container" data-page="59">

• Các thuật toán sắp xếp mà việc xác

định thứ tự của các phần tử không dựavào phép so sánh được gọi là các thuậttốn sắp xếp khơng dựa vào phép so

</div><span class="text_page_counter">Trang 61</span><div class="page_container" data-page="61">

có cùng giá trị vẫn giữ nguyên thứ tự tương đối của chúng như trước khi sắp xếp.

• Tính tại chỗ (in place): Nếu khơng gian bộnhớ phụ mà thuật tốn địi hỏi là O(1),nghĩa là bị chặn bởi hằng số không phụthuộc vào độ dài của dãy cần sắp xếp.

</div><span class="text_page_counter">Trang 62</span><div class="page_container" data-page="62">

Đặc trưng

của các thuật tốn sắp xếp (…)

• Thời gian tính của các thuật tốn sắp xếp có phụ thuộc vào kiểu dữ liệu/miền giá trị của các phần tử cần sắp xếp;

<i>• Những thuật tốn dù có cùng cỡ O lớn </i>

nhưng thời gian tính trung bình trên các bộ dữ liệu thì có thể khác nhau;

• Khi các thuật tốn sắp xếp có cùng cỡ thời gian tính thì chúng ta cần cân nhắc các đặc trưng cịn lại;

</div><span class="text_page_counter">Trang 63</span><div class="page_container" data-page="63">

PHÂN TÍCH THỜI GIAN TÍNH

MỘT SỐ THUẬT TỐN SẮP XẾP CĨ DỰA VÀO PHÉP SO SÁNH

</div><span class="text_page_counter">Trang 64</span><div class="page_container" data-page="64">

• Trình bày ý tưởng/minh họa bằng ví dụ ?

• Trong trường hợp trung bình, thuật tốn

</div><span class="text_page_counter">Trang 65</span><div class="page_container" data-page="65">

<small>void Interchangesort(int a[], int n){</small>

<small>for (int i=0; i<n-1;i++)for (int j=i+1;j<n ;j++)</small>

<small>if (a[i]>a[j])</small>

<small>exch(a[i],a[j]);}</small>

Ý tưởng chính của thuật tốn:

Xuất phát từ đầu dãy, tìm tất cả nghịch thế chứa phần tử này, triệt tiêu chúng bằng cách đổi chỗ phần tử này với phần tử tương ứng trong cặp nghịch thế. Lặp lại quá trình trên với các phần tử tiếp theo trong dãy.

</div><span class="text_page_counter">Trang 66</span><div class="page_container" data-page="66">

void exch(int &x, int &y)

</div><span class="text_page_counter">Trang 67</span><div class="page_container" data-page="67">

Thuật toán sắp xếp nổi bọt (bubble sort)

• Trình bày ý tưởng/minh họa bằng ví dụ ? • Trong trường hợp trung bình, thuật tốn

</div><span class="text_page_counter">Trang 68</span><div class="page_container" data-page="68">

<small>void Bubblesort(int a[],int n){</small>

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

<small>if (a[j]<a[j-1])exch(a[j],a[j-1]);</small>

Ý tưởng chính của thuật tốn:

Xuất phát từ cuối dãy (hoặc đầu dãy), đổi chỗ bất kỳ hai phần tử kế cận nào ngược thứ tự để đưa phần tử nhỏ nhất (hoặc lớn nhất) trong các cặp phần tử đó về vị trí đúng là đầu (cuối) dãy hiện hành, kế tiếp không xét đến nó nữa ở bước tiếp theo, do vậy ở lần xử lý thứ i sẽ có vị trí đầu dãy là i. Lặp lại quá trình trên cho đến khi khơng cịn cặp phần tử nào để xét.

</div><span class="text_page_counter">Trang 69</span><div class="page_container" data-page="69">

Thuật tốn

sắp xếp chọn (selection

• Trình bày ý tưởng/minh họa bằng ví dụ ? • Trong trường hợp trung bình, thuật tốn

• Thuật tốn Selection sort có độ phức tạp thời gian tuyến tính đối với các mẫu tin có kích thước lớn và khóa của các mẫu tin có kích thước nhỏ;

</div><span class="text_page_counter">Trang 70</span><div class="page_container" data-page="70">

<small>void Selectionsort(int a[],int n)</small>

<small>exch(a[min], a[i]);// nghia la a</small><sub>i</sub> <small>la phan tu nho nhat o buoc chon thu i}</small>

Ý tưởng chính của thuật tốn:

<i>Chọn phần tử nhỏ nhất trong n phần tử </i>

khởi tạo, đưa phần tử này về vị trí đúng là đầu dãy hiện hành; sau đó khơng quan tâm đến nó nữa, xem dãy hiện hành mới chỉ còn n-1 phần tử của dãy ban đầu, bắt đầu từ vị trí thứ hai; lặp lại quá trình trên cho dãy hiện hành... cho đến khi dãy hiện hành chỉ còn một phần tử.

</div><span class="text_page_counter">Trang 71</span><div class="page_container" data-page="71">

Thuật toán

sắp xếp chèn (insertion

• Trình bày ý tưởng/minh họa bằng ví dụ ? • Trong trường hợp trung bình, thuật tốn

• Thuật tốn Insertion sort có độ phức tạp thời gian tuyến tính đối với các tập tin hầu như đã được sắp xếp.

</div><span class="text_page_counter">Trang 72</span><div class="page_container" data-page="72">

<small>void Insertionsort(int a[], int n)</small>

<small>Ý tưởng chính của thuật tốn:</small>

<small>Dãy đầu tiên chỉ có một thứ tự a</small><sub>0</sub><small> là dãy đã được sắp. Ta từng bước mở rộng dãy được sắp bằng cách lần lượt thêm phần tử a</small><sub>i</sub><i><small> (i=1..n-1) vào. Khi chèn a</small></i><sub>i</sub><small> vào dãy đã được sắp thì ta tiến hành các công đoạn </small>

<small>chèn. Thứ hai tìm vị trí pos thích hợp </small>

<i><small>trong đoạn a</small><sub>0</sub><small> đến a</small><sub>i-1</sub></i><small> để chèn a</small><sub>i</sub><small> vào. Thứ </small>

<i><small>ba là chèn x vào vị trí pos.</small></i>

</div><span class="text_page_counter">Trang 73</span><div class="page_container" data-page="73">

Thuật tốn

sắp xếp shell (shell sort)

• Thuật tốn Shell sort do Donald L.Shell đề xuất vào năm 1959;

• Thuật tốn Shell sort là sự mở rộngcủa thuật toán Insertion sort: Trongkhi thuật toán Insertion sort chỉ đổichỗ các phần tử kề nhau thì thuậttoán Shell sort nhắm tới việc đổichỗ các phần tử ở xa nhau.

</div><span class="text_page_counter">Trang 74</span><div class="page_container" data-page="74">

Thuật toán

sắp xếp shell (shell sort)

• Shell sort là thuật toán sắp xếp được lựa chọn cho nhiều ứng dụng thực tế vì thời gian tính của nó gần tương đương với các thuật toán sắp xếp tốt nhất hiện biết với các tập tin có kích thước vừa phải (chẳng hạn

</div><span class="text_page_counter">Trang 75</span><div class="page_container" data-page="75">

void Shellsort (int a[], int n) {

int h = 1;

while (h < n/3) h = 3*h + 1; // 1, 4, 13, 40, 121, 364, 1093, ... while (h >= 1)

{ // h-sort the array.

for (int i = h; i < n; i++)

{ // Insert a[i] among a[i-h], a[i-2*h], a[i-3*h]... . for (int j = i; j >= h && a[j]<a[j-h]; j -= h)

</div>

×