資料結構與C++程式設計進階 遞迴(Recursion) 講師:林業峻 CSIE, NTU 6/ 17, 2010.

Slides:



Advertisements
Similar presentations
While 迴圈 - 不知重複執行次數
Advertisements

河內塔(Hanoi)問題.
第四章:长期股权投资 长期股权投资效果 1、控制:50%以上 有权决定对方财务和经营.
親愛的老師您好 感謝您選用本書作為授課教材,博碩文化準備本書精選簡報檔,特別摘錄重點提供給您授課專用。 說明: 博碩文化:
计算学科的基本问题 本章首先介绍一个对问题进行抽象的典型实例——哥尼斯堡七桥问题。然后,通过“梵天塔”问题和“停机问题”分别介绍学科中的可计算问题和不可计算问题。从“梵天塔”问题再引出算法复杂性中的难解性问题、P类问题和NP类问题,证比求易算法,P=NP是否成立的问题。
“八皇后”问题 崔萌萌 吕金华.
第一章 C语言概述 计算机公共教学部.
XX信托 ·天鑫 9号集合资金信托计划 扬州广陵
三角形的邊角關係 大綱:三角形邊的不等關係 三角形邊角關係 樞紐定理 背景知識:不等式 顧震宇 台灣數位學習科技股份有限公司.
第4章 选择结构程序设计 在现实生活中,需要进行判断和选择的情况是很多的 如果你在家,我去拜访你 如果考试不及格,要补考
C语言程序设计 第十二章 位运算.
第一章 程序设计入门.
第5章 函数与模块化设计 学习目的与要求: 掌握函数的定义及调用方法 理解并掌握参数的传递方法 理解函数的嵌套与递归调用
高级语言程序设计 主讲人:陈玉华.
循环结构又称为重复结构:用来处理需要重复处理的问题,它是程序中一种很重要的结构。
物件導向程式設計 (Object-Oriented rogramming)
函數(一) 自訂函數、遞迴函數 綠園.
C++Primer 3rd edition 中文版 Chap 5
第3章 顺序结构程序设计 本章要点: 格式化输出函数──printf() 格式输入函数——scanf() 字符输出函数——putchar()
排序 Sorting.
快速排序法 (Quick Sort).
Chap 10 函数与程序结构 10.1 函数的组织 10.2 递归函数 10.3 宏定义 10.4 编译预处理.
C程序设计.
If … else 選擇結構 P27.
搜尋資料結構 Search Structures.
STRUCTURE 授課:ANT 日期:2010/5/12.
第七章 函数 目录 有参的加法函数的开发 函数定义的一般形式 函数参数和函数的值 函数的调用
Function.
第八章 函数.
第5章 堆疊(Stacks) 5-1 堆疊的基礎 5-2 堆疊的表示法 5-3 堆疊的應用 - 運算式的計算與轉換
作弊是否很有诱惑性? 上堂课已经讲了 作业不一定在两个小时里都能完成 答疑没有一个人? 作弊是有记录的 心理系很多同学集体作弊,让人震惊
C语言 程序设计基础与试验 刘新国、2012年秋.
計數式重複敘述 for 迴圈 P
C Programming in Action
东北林业大学 陈宇 ACM程序设计 东北林业大学 陈宇
PHP+MySQL互動式網頁程式設計班 期末考 講師:林業峻 CSIE, NTU 7 / 11, 2010.
第1章 概述 本章要点: C语言程序结构和特点 C语言程序的基本符号与关键字 C语言程序的编辑及运行 学习方法建议:
第五章 递归与广义表 递归的概念 递归过程与递归工作栈 递归与回溯 广义表.
第1讲 C语言基础 要求: (1) C程序的组成 (2) C语言的标识符是如何定义的。 (3) C语言有哪些基本数据类型?各种基本数
C语言大学实用教程 第5章 函数与程序结构 西南财经大学经济信息工程学院 刘家芬
資料結構與C++程式設計進階 排序與搜尋 講師:林業峻 CSIE, NTU 6/ 14, 2010.
資料結構與C++程式設計進階 實作練習 講師:林業峻 CSIE, NTU 6/ 24, 2010.
计算机问题求解 – 论题1-4 - 基本的算法结构 2018年10月09日.
第一章 程序设计和C语言 主讲人:高晓娟 计算机学院.
Chap 5 函数 5.1 计算圆柱体积 5.2 使用函数编写程序 5.3 变量与函数.
7.1 C程序的结构 7.2 作用域和作用域规则 7.3 存储属性和生存期 7.4 变量的初始化
C程序设计.
第5章 函 数.
C语言程序设计 李祥 QQ:
第二章 类型、对象、运算符和表达式.
第2章 数据类型与表达式 学习目的与要求: 掌握C 语言的基本数据类型及使用方法 掌握C程序中常用的运算符和表达式 了解数据类型的转换.
累堆排序法 (Heap Sort).
C/C++基礎程式設計班 C++: 物件的使用、參考、重載函式 講師:林業峻 CSIE, NTU 3/28, 2015.
問題解決與流程圖 高慧君 台北市立南港高中 2006年12月22日.
北一女中 資訊選手培訓營 遞迴、河內塔與merge sort Nan.
第五章 逻辑运算和判断选取控制 §5.1 关系运算符和关系表达式
第七章  数 组.
程式設計--linear search 通訊一甲 B 楊穎穆.
遞迴 Recursion.
結構、檔案處理(Structure, File)
第十二章 位运算.
C/C++基礎程式設計班 字元與字串 講師:林業峻 CSIE, NTU 3/14, 2015.
§12-5 同方向同频率两个简谐振动的合成 一. 同方向同频率的简谐振动的合成 1. 分振动 : 2. 合振动 : 解析法
資料結構 老師:李崇明 助教:楊斯竣.
C/C++基礎程式設計班 C語言入門、變數、基本處理與輸入輸出 講師:林業峻 CSIE, NTU 3/7, 2015.
Advanced Competitive Programming
C/C++基礎程式設計班 陣列 講師:林業峻 CSIE, NTU 3/14, 2015.
Chap 10 函数与程序结构 10.1 圆形体积计算器 10.2 汉诺塔问题 10.3 长度单位转换 10.4 大程序构成.
C语言基本语句 判断循环.
第三章 流程控制 程序的运行流程 选择结构语句 循环结构语句 主讲:李祥 时间:2015年10月.
Presentation transcript:

資料結構與C++程式設計進階 遞迴(Recursion) 講師:林業峻 CSIE, NTU 6/ 17, 2010

大綱 基本遞迴觀念 進階遞迴應用 分治法 (Divide and Conquer) 作業 河內塔遊戲 (Hanoi Tower) 快速排序法 (Quick Sort) 作業

遞迴 什麼是遞迴(Recursion)? 範例 思考: 在函式(function)之中會需要呼叫到自己函式的程式寫法 寫一個void print(int n)函式 列出整數1~n 思考: 要印n前先印n-1 要印n-1前先印n-2 … 要印2前先印1 #include <stdio.h> void print(int n) { if(n<=1) // 遞迴終止條件 printf("%d\n", n); return; } else print(n-1); // 遞迴部分(呼叫自己) int main() print(10); // 印出1~10 return 0;

實例與應用 遞迴的特性 使用遞迴設計程式的步驟 呼叫與被呼叫的函式具有一個固定的關係,以下列的total函 式為例(傳入n印出1加到n的總和): 使用遞迴設計程式的步驟 (1) 了解問題是否適合用遞迴的特性來解題 (2) 決定遞迴結束條件 (3) 決定遞迴執行部份 int total(int n) { if (n <=1) // 遞迴終止條件 return 1; else return (n+total(n-1)); // 遞迴部分(呼叫下一層的函式) }

範例:total 呼叫 return 6 印出6 呼叫 return 3 呼叫 return 1 int main() { printf(“%d\n”, total(3)); return 0; } int total(int d) // d =3 { if (d <=1) // 遞迴終止條件 return 1; else return (d+ total(d-1) ); } 呼叫 return 6 印出6 int total(int d) // d =2 { if (d <=1) // 遞迴終止條件 return 1; else return (d+ total(d-1)) ; } 呼叫 return 3 int total(int d) // d =1 { if (d <=1) // 遞迴終止條件 return 1; else return (d+ total(d-1) ); } 呼叫 return 1

費伯那西數列 – 使用for迴圈 費伯那西數列(每個數字為前兩個數字的和): 範例程式(迴圈寫法):印出第N個費伯那西數字 0, 1, 1, 2, 3, 5, 8, 13, 21…… F(n) = F(n-1) + F(n-2) 範例程式(迴圈寫法):印出第N個費伯那西數字 int Fib(int n) { int a1, a2=0, a3=1, i; if(n<=1) return 0; else if(n==2) return 1; for(i=3; i<=n; i++) { a1=a2; a2=a3; a3=a1+a2; } return a3;

費伯那西數列 – 遞迴 思考: 我們得到: [迴圈 / 遞迴]費伯那西數列的比較 要算F(n)前先算F(n-1)+F(n-2) int Fib(int n) { if(n==1) return 0; else if(n==2) return 1; else return Fib(n-1)+Fib(n-2); } 思考: 要算F(n)前先算F(n-1)+F(n-2) 要算F(n-1)前先算F(n-2)+F(n-3) … 要印F(3)前先算F(2)+F(1) 我們得到: Fib(1) = 0, Fib(2) = 1, Fib(3) = 1, Fib(4) = 2, Fib(5) = 3 … [迴圈 / 遞迴]費伯那西數列的比較 迴圈寫法 遞迴寫法 程式行數 較長 較短 執行效率 較快 較慢

練習 寫一個遞迴函式, 可印出n~1 寫一個遞迴函式, 將一個鏈結串列從尾印到頭

大綱 基本遞迴觀念 進階遞迴應用 分治法 (Divide and Conquer) 作業 河內塔遊戲 (Hanoi Tower) 快速排序法 (Quick Sort) 作業

河內塔(Hanoi Tower) 河內塔問題:在A、B、C三個塔上有數個圓盤, 請求出將圓盤從A塔全數搬移到C塔的順序,且大 的圓盤不可以疊到小圓盤上。 B C 3 2 1 A 1 2 3 A B C B C 3 2 1 A B C 3 2 1 A B C 3 2 1 A B C 3 2 A 1 B C 3 2 1 A B C 3 2 1 A

河內塔(Hanoi Tower) 題目:印出河內塔中,編號1~n的圓盤從A塔到C 塔的搬動過程。 目標: 步驟: 2 3 A B C

河內塔範例程式碼 範例程式碼 功能:印出河內塔中,編號1~n的圓盤從A塔到C塔的搬動過 程。 void hanoi (int n, char from, char mid, char to) { // 在搬動第n個圓盤時 if(n==0) return ; // 先將第n-1個圓盤搬到”中間塔” hanoi(n-1,from, to, mid); // 將自己搬到”目標塔” printf("圓盤%2d從 %c塔 -> %c塔\n",n,from,to); // 再將第n-1個圓盤從”中間塔”搬回來 hanoi(n-1,mid, from, to); }

練習 請利用河內塔程式碼,讓使用者輸入「圓盤總數n 」,計算各圓盤被搬動多少次(圓盤最多不超過 100個)? (chap04_ex1.c)

大綱 基本遞迴觀念 進階遞迴應用 分治法 (Divide and Conquer) 作業 河內塔遊戲 (Hanoi Tower) 快速排序法 (Quick Sort) 作業

分治法(Divide and Conquer) 分而治之、各個擊破 是一種利用遞迴特性解題的技巧。將一個大問題,切割成許 多小問題;將這些小問題解決之後,原本的大問題也就解決 了。 實例: 排序 (分類再分類, 直到無法再分為止!) 小 中 大 中 小 大 小 中 大

快速排序法(Quick Sort) 快速排序法 步驟說明(由小排到大) 是一種運用”切割並各個擊破”的方式,將一群資料切割成 兩個部分做排序。 步驟說明(由小排到大) (1) 在一群資料中訂出一個基準值 (2) 比基準值大的集中在右邊、比基準值小的集中在左邊 (a) 在這群資料中由左至右,找一個比基準值大的資料 (b) 在這群資料中由右至左,找一個比基準值小的資料 (c) 交換(a)、(b)中的資料,但如果(a)、(b)的搜尋相遇就停止 (3) 最後將基準值放在兩者之間,得到兩群子資料A、B。 (4) 對每群子資料做一樣的操作。

快速排序法(Quick Sort) 要決 小 中 大 中 小 大 中 小 大 小 中 大 小 中 大 小 中 大 小 中 大 分組再分組 (先分小的那組) 直到不能分 結束 小 中 大 中 小 大 中 小 大 小 中 大 小 中 大 小 中 大 小 中 大

快速排序法(Quick Sort) 範例圖示

快速排序法圖例(由小排到大) 第一步: 訂出基準值 5 1 6 4 8 7 5 pivot a b 第二步: 3) 交換兩者 *)若a,b交錯則跳到第3步 5 1 4 6 6 4 8 7 5 pivot 交換 b a 第三步: 將資料分為兩群,基準值放在中間 5 4 1 4 5 6 8 7 5 pivot 交換 第四步: 將左右兩區資料個別再做”快速排序” 1 6 8 7 4 5

快速排序法程式碼 (chap04_ex2.c) void QuickSort(int *numbers, int low, int high) // Quick Sort 由小排到大 { int a, b, pivot; a = low+1; // a從左邊開始找 b = high; // b從右邊開始找 pivot = numbers[low]; // 基準值預設為第一個 while(1) while(numbers[a] < pivot) // a向右找,找到比基準值大的才停下來 a++; while(numbers[b] > pivot) // b向左找,找到比基準值小的才停下來 b--; if(a < b) swap(&numbers[a], &numbers[b]); else break; } numbers[low] = numbers[b]; // 把基準值擺到中間 numbers[b] = pivot; // 把數列切成兩半 if((b-1) > low) QuickSort(numbers, low, b-1); // 小的那一半繼續做QuickSort if((b+1) < high) QuickSort(numbers, b+1, high); // 大的那一半繼續做QuickSort

大綱 基本遞迴觀念 進階遞迴應用 分治法 (Divide and Conquer) 作業 河內塔遊戲 (Hanoi Tower) 快速排序法 (Quick Sort) 作業

河內塔遊戲 2.0 寫一個河內塔遊戲程式碼,讓使用者輸入「圓盤 總數」,列出所有搬動過程並顯示三塔之情況 範例: http://www.csie.ntu.edu.tw/~d95027/train/download/HanoiTower2.exe B C 3 2 1 A 1 2 3 A B C B C 3 2 1 A B C 3 2 1 A B C 3 2 1 A B C 3 2 A 1 B C 3 2 1 A B C 3 2 1 A

繳交 使用FTP上傳 請使用FileZilla上傳作業至指定FTP主機 繳交期限:2010. 6/24(四) 主機: 使用者名稱: 密碼: 連接埠: 將程式存到自己學號之資料夾 (請自行新增) 檔名: ca1871XX_hw2_##.c XX為學號, ##為版本編號 Ex: ca187100_hw2_01.c (ca187100號同學 作業2 第1版) 請使用FileZilla上傳作業至指定FTP主機 繳交期限:2010. 6/24(四) 公佈解答後,不再收作業