Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 67 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
67
Dung lượng
716,45 KB
Nội dung
Kỹ thuật lập trình Chương 4: Một số cấu trúc liệu giải thuật 1.Đệ qui (4LT – 2BT) SE-SoICT Last update 9-2010 KTLT 4-1.1 Đệ qui 1.1 Khái niệm đệ qui 1.2 Các loại đệ qui 1.3 Mô tả đệ qui cấu trúc liệu 1.4 Mô tả đệ qui giải thuật 1.5 Các dạng đệ qui đơn giản thường gặp Last update 8-2010 SE-SoICT KTLT 4-1.2 Khái niệm Đ/n đệ qui Một mô tả/định nghĩa đối tượng gọi đệ qui mơ tả/định nghĩa ta lại sử dụng đối tượng Tức mơ tả đối tượng qua Mơ tả đệ qui tập sốtựnhiên N : Số1 sốtựnhiên ( -N) Sốtựnhiên sốtựnhiên cộng Mô tả đệ qui cấu trúc ds(list) kiểu T : Cấu trúc rỗng ds kiểu T Ghép nối thành phần kiểu T(nút kiểu T ) với ds kiểu T ta có ds kiểu T Mô tả đệ qui gia phả: Gia phả người bao gồm người gia phả cha gia phả mẹ Last update 8-2010 SE-SoICT KTLT 4-1.3 Ví dụ Định nghĩa khơng đệ qui n!: n! = n * (n-1) * … * Định nghĩa đệ qui: n! = n=0 n * (n-1)! n>0 Mã C++: int factorial(int n) { if (n==0) return 1; else return (n * factorial(n - 1)); } Mô tả đệ qui thủ tục tăng dãy a[m:n] ( dãy a[m], a[m+1], , a[n] ) phương pháp Sort_Merge (SM): SM (a[m:n]) ≡Merge ( SM(a[m : (n+m) div 2]) , SM (a[(n+m) div +1 : n] ) Với : SM (a[x : x]) thao tác rỗng (khơng làm cả) Merge (a[x : y] , a[(y+1) : z]) thủ tục trộn dãy tăng a [x : y] , a[(y+1) : z] để dãy a[x : z] tăng Last update 8-2010 SE-SoICT KTLT 4-1.4 Mô tả đệ qui gồm hai phần Phần neo: trường hợp suy biến (cá biệt) đối tượng Vídụ: sốtựnhiên, cấu trúc rỗng ds kiểu T, ! = , SM (a[x:x]) thao tác rỗng Phần qui nạp: mơ tả đối tượng (giải thuật) thơng qua đối tượng (giải thuật ) cách trực tiếp gián tiếp Vídụ: n! = n * (n –1) ! SM (a[m:n]) ≡Merge (SM (a[m:( m+n) div 2] , SM (a[(m+n) div +1 : n]) ) Đệ qui gồm hai loại: Đệ qui trực tiếp Đệ qui gián tiếp Last update 8-2010 SE-SoICT KTLT 4-1.5 Giải thuật đệ qui Nếu ta có lời giải S cho toán P, ta lại sử dụng lời giải cho tốn P’ giống P kích cỡ nhỏ lời giải S gọi lời giải đệ qui Biểu diễn giải thuật đệ qui P P[ S , P ] Điều kiện dừng Biểu diễn tổng quát P if B P[ S , P ] P P[ S , if B P ] Chương trình đệ qui: Khi ta cài đặt giải thuật đệ qui, ta có chương trình đệ qui (tự gọi lại nó: P =>P’) –Hàm đệ qui –Thủ tục đệ qui Last update 8-2010 SE-SoICT KTLT 4-1.6 Mô tả đệ qui giải thuật Dãy số Fibonaci(FIBO) :{ FIBO (n) } ≡1 ,1 , , , , , 13 , 21 , 34 , 55 , 89 , 144 , 233 , 377 , FIBO(0 ) = FIBO (1 ) = ; FIBO(n ) = FIBO (n -1 ) + FIBO ( n -2 ) ; với n > = Giải thuật đệ qui tính FIBO ( n ) là: FIBO(n) if ((n = ) or ( n = )) return ; else return ( FIBO (n -1) + FIBO (n -2)) ; Last update 8-2010 SE-SoICT KTLT 4-1.7 Các dạng đệ qui đơn giản thường gặp Đệqui tuyến tính: dạng đệqui trực tiếp đơn giản có dạng P { If (B) thực S; else { thực S* ; gọi P } } Với S , S* thao tác không đệqui Vídụ:Hàm FAC(n) tính số hạng n dãy n! Dạng hàm ngôn ngữ mã giả: { Nếu n = FAC = ; /* trường hợp neo*/ Ngược lại FAC = n*FAC(n-1) } Dạng hàm C++ : int FAC( int n ) { if ( n == ) return ; else return ( n * FAC(n-1 )) ; } Last update 8-2010 SE-SoICT KTLT 4-1.8 Thi hành hàm tính giai thừa factorial (3) n=3 factorial (2) … n=2 3*factorial(2) … factorial (1) n=1 2*factorial(1) … factorial (0) 1*factorial(0) n=0 … return 1; 1 Last update 8-2010 SE-SoICT KTLT 4-1.9 Trạng thái hệ thống thi hành hàm tính giai thừa Stack hệ thống factorial(0) factorial(1) factorial(1) factorial(1) factorial(2) factorial(2) factorial(2) factorial(2) factorial(2) factorial(3) factorial(3) factorial(3) factorial(3) factorial(3) factorial(3) factorial(3) t Thời gian hệ thống Gọi hàm Gọi hàm factorial(3) factorial(2) Trả từ Trả từ Trả từ Gọi hàm Gọi hàm hàm hàm hàm factorial(1) factorial(0) factorial(0) factorial(1) factorial(2) Trả từ hàm factorial(3) t Last update 8-2010 SE-SoICT KTLT 4-1.10 A Đệ qui có lệnh gọi trực tiếp •Đệ qui có dạng sau: P(X) ≡ if C(X) D(X) else { A(X) ; P(f(X)) ; B(X) ; } X biến đơn biến véc tơ C(X) biểu thức boolean X A(X) , B(X) , D(X):không đệ qui f(X) hàm X (hàm đơn điệu giảm) Last update 8-2010 SE-SoICT KTLT 4-1.53 Giải thuật thực P(X) với việc sử dụng Stack có dạng : P(X) ≡{ Creat_Stack (S) ; ( tạo stack S ) while(not(C(X)) { A(X) ; Push(S,X) ; ( cất gía trị X vào stack S ) X := f(X) ; } D(X) ; while (not(EmptyS(S))) { POP(S,X) ; ( lấy liệu từ S ) B(X) ; } } Last update 8-2010 SE-SoICT KTLT 4-1.54 •Ví dụ:Thủ tục đệ qui chuyển biểu diễn số từ số thập phân sang nhị phân có dạng : Binary(m) ≡if ( m > ) { Binary( m div ) ; write( m mod ) ; } •Trong trường hợp : X m P(X) Binary(m) A(X) ; D(X) lệnh rỗng B(X) lệnh Write(m mod ) ; C(X) ( m ) { sdu := m mod ; Push(S,sdu) ; m := m div ; } While ( not(EmptyS(S)) { POP(S,sdu) ; Display(sdu) ; } } Last update 8-2010 SE-SoICT KTLT 4-1.56 B Thủ tục đệ qui với hai lần gọi đệ qui –Đệ qui có dạng sau P(X) ≡if C(X) D(X) ; else { A(X) ; P(f(X)) ; B(X) ; P(g(X)) ; } -Thuật toán khử đệ qui tương ứng với thủ tục đệquy P(X) là:{ Creat_Stack (S) : Push (S, (X,1)) ; { while ( not C(X) ) { A(X) ; Push (S, (X,2)) ; X := f(X) ; } D(X) ; POP (S, (X,k)) ; if ( k 1) { B(X) ; X := g(X) ; } } while ( Last update 8-2010 k = ) ; SE-SoICT } KTLT 4-1.57 Khử đệ qui thủ tục Tháp Hà Nội •Dạng đệ qui void THN(n , X , Y, Z ) { if( n > ) { THN ( n -1 , X , Z , Y ) ; Move ( X , Y ) ; THN ( n -1 , Z , Y , X ) ; } } Last update 8-2010 SE-SoICT KTLT 4-1.58 •Giải thuật khơng đệ qui tương đương là: THN (n, X, Y, Z) { Creat_Stack (S) ; Push (S ,(n,X,Y,Z,1)) ; while ( n > ) { Push (S ,(n,X,Y,Z,2)) ; n := n -1 ; Swap (Y,Z ) ; } POP (S,(n,X,Y,Z,k)) ; if ( k ) { Move (X ,Z ) ; n := n -1 ; Swap (X ,Y ) ; } } while ( k = ) ; } Last update 8-2010 SE-SoICT KTLT 4-1.59 Bài tập Liệt kê tập củaa tập 1,2,3,…n, với n nhập từ bàn phím Liệt kê hốn vị Từ COMPUTER ( mở rộng, từ nhập từ bàn phím ) Một nhà thám hiểm đem theo túi với trọng lượng tối đa B Có n đị vật cần mang theo, đị vật có trọng lượng giá trị ci tương ứng.Hãy viết CT tìm cách bỏ vào túi đị vật cho giá trị sử dụng lớn Bài toán Người du lịch : người du lịch muốn thăm thành phố khác Xuất phát thành phố đó, họ muốn qua tất thành phố ( lân) trở lại thành phố ban đầu.Biết chi phi lại từ thành phố I đến J Cij Hãy tìm hành trình với tổng chi phí thấp Liệt kê tất cách xếp N hậu bàn cờ x cho chúng không ăn Last update 8-2010 SE-SoICT KTLT 4-1.60 Bài toán Hậu – Giải thuật Algorithm Solve Input trạng thái bàn cờ Output if trạng thái bàn cờ chứa đủ hậu 1.1 In trạng thái hình else 2.1 for bàn cờ mà cịn an tồn 2.1.1 thêm hậu vào ô 2.1.2 dùng lại giải thuật Solve với trạng thái 2.1.3 bỏ hậu khỏi ô Vét cạn End Solve Last update 8-2010 SE-SoICT KTLT 4-1.61 Bài toán Hậu – Thiết kế phương thức Last update 8-2010 SE-SoICT KTLT 4-1.62 Bài toán Hậu – Thiết kế liệu đơn giản const int max_board = 30; class Queens { public: Queens(int size); bool is_solved( ) const; void print( ) const; bool unguarded(int col) const; void insert(int col); void remove(int col); int board_size; // dimension of board = maximum number of queens private: int count; // current number of queens = first unoccupied row bool queen_square[max_board][max_board]; }; Last update 8-2010 SE-SoICT KTLT 4-1.63 Bài toán Hậu – Mã C++ void Queens :: insert(int col) { queen_square[count++][col] = true; } bool Queens :: unguarded(int col) const { int i; bool ok = true; for (i = 0; ok && i < count; i++) //kiểm tra cột ok = !queen_square[i][col]; //kiểm tra đường chéo lên for (i = 1; ok && count − i >= && col − i >= 0; i++) ok = !queen_square[count − i][col − i]; //kiểm tra đường chéo xuống for (i = 1; ok && count − i >= && col + i < board_size; i++) ok = !queen_square[count − i][col + i]; return ok; } Last update 8-2010 SE-SoICT KTLT 4-1.64 Bài tốn Hậu – Góc nhìn khác Last update 8-2010 SE-SoICT KTLT 4-1.65 Bài toán Hậu – Thiết kế const int max_board = 30; class Queens { public: Queens(int size); bool is_solved( ) const; void print( ) const; bool unguarded(int col) const; void insert(int col); void remove(int col); int board size; private: int count; bool col_free[max board]; bool upward_free[2 * max board − 1]; bool downward_free[2 * max board − 1]; int queen_in_row[max board]; //column number of queen in each row }; Last update 8-2010 SE-SoICT KTLT 4-1.66 Bài toán Hậu – Mã C++ Queens :: Queens(int size) { board size = size; count = 0; for (int i = 0; i < board_size; i++) col_free[i] = true; for (int j = 0; j < (2 * board_size − 1); j++) upward_free[j] = true; for (int k = 0; k < (2 * board_size − 1); k++) downward_free[k] = true; } void Queens :: insert(int col) { queen_in_row[count] = col; col_free[col] = false; upward_free[count + col] = false; downward_free[count − col + board size − 1] = false; count++; } Last update 8-2010 SE-SoICT KTLT 4-1.67 ... tượng Tức mơ tả đối tượng qua Mơ tả đệ qui tập sốtựnhiên N : Số1 sốtựnhiên ( -N) Sốtựnhiên sốtựnhiên cộng Mô tả đệ qui cấu trúc ds(list) kiểu T : Cấu trúc rỗng ds kiểu T Ghép nối thành phần kiểu... bước để tìm giải thuật đệ qui Thơng số hóa tốn Tổng qt hóa tốn cụ thể cần giải thành tốn tổng quát (một toán chứa toán cần giải ) Tìm thơng số cho tốn tổng qt thơng số điều khiển: thơng số mà độ... SE-SoICT KTLT 4-1.5 Giải thuật đệ qui Nếu ta có lời giải S cho toán P, ta lại sử dụng lời giải cho tốn P’ giống P kích cỡ nhỏ lời giải S gọi lời giải đệ qui Biểu diễn giải thuật đệ qui P P[ S