1. 程式人生 > >程式設計思想之遞迴

程式設計思想之遞迴

我之前寫過關於遞迴演算法的博文,但作為程式設計思想系列的文章不得不再對它進行進一步深入的剖析。因為它是一種簡單、常用又重要的一種程式設計思想。

什麼叫遞迴?

舉一個通俗的例子:

有一個8倆重的蘋果要你切成重量相等的若干份,每一份的重量不能大於1倆。你肯定會想到這樣做:

1.第一刀先把一個蘋果切成重量均等的2份A1和A2;

2.再把其中的一份A1切成重量均等的兩份A11和A12, 把A2切成均等的兩份A21和A22;

3.把A11切成均等的兩份……

4.直到每一小份都小於等於1倆為止。

以上的例子就是遞迴一個模型,把一個大的事物化成若干個小的事物,每一次使用的方法都相同。

更為專業的定義:

程式自身呼叫自身的程式設計技巧稱為

遞迴( recursion遞迴有直接遞迴和間接遞迴

•直接遞迴:函式在執行過程中呼叫本身。

•間接遞迴:函式在執行過程中呼叫其它函式再經過這些函式呼叫本身。

遞迴有四個特性:

1.必須有可最終達到的終止條件,否則程式將陷入無窮迴圈;

2.子問題在規模上比原問題小,或更接近終止條件;

3.子問題可通過再次遞迴呼叫求解或因滿足終止條件而直接求解;

4.子問題的解應能組合為整個問題的解。

上面的例子中也滿足以上的四點性質:

(1).終止條件是每一份的重量不能大於1倆;(2).每一次切的大小都比上一次小;(3).每一次切的方式都相同,所以子問題可遞迴呼叫;(4).最終切成的每一小份也就是要求的解。

對上面例子的實現:

public static void sliceApple(float weight, int times){
		if (weight <= 1) {
			//System.out.println("weight:" + weight);
		} else {
			float w = weight / 2;
			System.out.println("第" + times + "次等分的重量為:" + w + "   " + w);
			times += 1;
			sliceApple(w, times);
			sliceApple(w, times);
		}
	}

	public static void main(String args[]) {
		sliceApple(8, 1);
	}

結果:

1次等分的重量為:4.0   4.0

2次等分的重量為:2.0   2.0

3次等分的重量為:1.0   1.0

3次等分的重量為:1.0   1.0

2次等分的重量為:2.0   2.0

3次等分的重量為:1.0   1.0

3次等分的重量為:1.0   1.0


遞迴能做什麼?

將大問題分解成小問題,將複雜的問題簡單化;

使程式更易於理解,增強可讀性;

你會怎樣使用遞迴?

分析問題,看看問題是否屬於遞迴模型,能否用遞迴模型解決。一個問題能否用遞迴模型就看它是否滿足遞迴的四個特性。

遞迴在呼叫的時候要儲存呼叫點的資訊,因此會有呼叫開銷。在對效率有較高要求的時候,如果能用迴圈解決問題最好不要用遞迴,因為迴圈沒有呼叫開銷,效率會更高。

關於遞迴的更多應用可閱讀之前寫的一篇文章:遞迴演算法

相關推薦

程式設計思想

我之前寫過關於遞迴演算法的博文,但作為程式設計思想系列的文章不得不再對它進行進一步深入的剖析。因為它是一種簡單、常用又重要的一種程式設計思想。什麼叫遞迴?舉一個通俗的例子:有一個8倆重的蘋果要你切成重量

C++ 二叉樹程式設計實戰遍歷

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> //二叉樹節點 typedef struct BINAR

Java設計思想繼承

一個軟體實體如類、模組和函式應該對擴充套件開放,對修改關閉。 Softeware entities like classes,modules and functions should be open for extension but closed for modifications. 開閉原則的含義

Linux高階程式設計基礎——檔案系統程式設計遍歷/home目錄

檔案系統程式設計之遞迴遍歷/home目錄 /編寫程式完成以下功能: 1.遞迴遍歷/home目錄,打印出所有檔案和子目錄名稱及節點號。 2.判斷檔案型別,如果是子目錄,繼續進行遞迴遍歷,直到遍歷完所有子目錄為止。/ #include <stdio.h> #include &

採用分而治思想結合對陣列進行排序

最近在學動態規劃中, 不斷地提到分而治之思想和遞迴!  就想到能不能採用分而治之思想結合遞迴對陣列進行排序,   代替以前的氣泡排序和選擇排序呢?然後自己想著想著, 還真實現了! 程式碼如下: /** * 從小到大進行排序 指導思想: 分而治之+遞迴 */

C語言程式設計求階乘

題目: 利用遞迴方法實現一個函式,該函式能夠實現n的階乘,即 n! = n*(n-1)*…*3*2*1; #include <stdio.h> int factorial(int n) { if(n == 1) //結束遞迴判斷條件 { retur

python入門

表現形式:   函式體裡包含執行本身 def f1(): r = f1() f1()   例項:   斐波那契數   (a1+a2=a3   a2+a3=a4   a3+a4=a5   ......) def f1(a1,a2):

自學C理解

一、 理解概念   C語言允許一個函式呼叫自身,這種過程被稱為遞迴(Recursion)。程式使用遞迴處理特殊的問題,如階乘、 Ackermann函式,反序等等。實際上,如果不考慮執行時記憶體的開消,任何使用賦值語句、if-else和while結構的函 數都可以用遞迴方式重寫。

二叉樹遍歷演算法

作者:石鍋拌飯  原文連結 二叉樹的遍歷演算法有多種,典型的有先序遍歷、中序遍歷、後序遍歷以及層序遍歷。而且這些遍歷的遞迴演算法較為簡單,程式碼很少,容易實現,本文就是彙總二叉樹遍歷的遞迴演算法,非遞迴演算法將在下一篇文章中進行總結。本文中用到的二叉樹例項如下:

python函式

遞迴:自己呼叫自己 無限遞迴:和死迴圈不一樣 避免無限遞迴---遞迴收斂條件 遞迴應用於難題---思想(思路) 遞迴:效率低,佔資源 能用遞迴的一定能用迴圈 解決階乘:(把大問題拆分成小問題)解決大問題的思路和小問題思路完全一樣,則可以是用遞迴的思想 def jc(n):  

python函式,二分查詢

遞迴函式 遞迴函式一直都是我們所覺得難理解的以一種方式,但其實,也很好理解的,遞迴函式就是自己呼叫自己。就是在重複的做同一件事情。只是有的時候,也最好不要使用遞迴函式,因為你的函式一旦呼叫,就要開闢新的記憶體空間。不利於程式的執行。python對你記憶體一個保護機制,預設只能遞迴到998

php演算法排序

<?php function quickSort($arr) { if(count($arr) > 1) { $k=$arr[0]; $x=array(); $y=array(); $_size=count($arr);

左神第八課演算法

題目一 求n! 簡單得不想說 題目二 漢諾塔問題 古代有一個梵塔,塔內有三個座A、B、C,A座上有64個盤子,盤子大小不等,大的在下,小的在上(如圖)。有一個和尚想把這64個盤子從A座移到C座,但每次只能允許移動一個盤子,並且在移動過程中,3個座上的盤子始終

資料結構與演算法

1、背景 現在很多App都有這個功能。使用者A來推薦使用者B來註冊,使用者B又推薦了使用者C來註冊,我們可以說,使用者C的“最終推薦人”為使用者A,使用者B的"最終推薦按人”也為使用者A,而使用者A沒有"最終推薦人"。 一般來說,我們會通過資料庫來記錄這種推薦關係。在資料庫表中,我們可以

10-Python函式

Python函式之遞迴     主要內容:遞迴知識、遞迴例項、總結三部分 一.遞迴知識 遞迴函式就是函式自己內部呼叫自己。注意兩個知識點: 遞迴:定義函式時候,函式本身自己內部呼叫自己。 巢狀:定義函式時候,函式內部重新定義新

Python3&資料結構

#遞迴 def fact(x): if x == 1: return 1 else: return x * fact(x - 1) #tail recursion(尾遞迴) def tail_recusion(x,total=1): if

執行時型別資訊(RTTI)列印類資訊

深度優先 public class ClassPrint { private static void printSupers(Class<?> clazz) { String name = clazz.getCanonicalName(); System.out.p

12.scrapy框架解析和post請求

今日概要 遞迴爬取解析多頁頁面資料 scrapy核心元件工作流程 scrapy的post請求傳送 今日詳情 1.遞迴爬取解析多頁頁面資料 - 需求:將糗事百科所有頁碼的作者和段子內容資料進行爬取切持久化儲存 - 需求分析:每一個頁面對應一個url,則scrapy工程需要對每一個頁碼

python演算法演算法

# -*- coding: utf-8 -*- import numpy as np # 遞迴演算法 i = 0 def my_Recursion(list, n): global i try: if list[i] == n:

程式設計思想多執行緒與多程序系列(上)

什麼是執行緒 什麼是執行緒?執行緒與程序與有什麼關係?這是一個非常抽象的問題,也是一個特別廣的話題,涉及到非常多的知識。我不能確保能把它講的話,也不能確保講的內容全部都正確。即使這樣,我也希望儘可能地把他講通俗一點,講的明白一點,因為這是個一直困擾我很久的,撲朔迷離的知識領