信息與計(jì)算科學(xué)論文_第1頁
信息與計(jì)算科學(xué)論文_第2頁
信息與計(jì)算科學(xué)論文_第3頁
信息與計(jì)算科學(xué)論文_第4頁
信息與計(jì)算科學(xué)論文_第5頁
已閱讀5頁,還剩22頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

學(xué)號: 2006011269 哈爾濱師范大學(xué) 學(xué)士學(xué)位論文 題 目 算法設(shè)計(jì)中的遞歸與非遞歸轉(zhuǎn)換 學(xué) 生 孫慶雨 指導(dǎo)教師 欒叢海 講師 年 級 2006 級 專 業(yè) 信息與計(jì)算科學(xué) 系 別 信息科學(xué)系 學(xué) 院 數(shù)學(xué)科學(xué)學(xué)院 哈 爾 濱 師 范 大 學(xué) 學(xué)士學(xué)位論文開題報告 論文題目 算法設(shè)計(jì)中的遞歸與非遞歸轉(zhuǎn)換 學(xué)生姓名 孫慶雨 指導(dǎo)教師 欒叢海 講師 年 級 2006 級 專 業(yè) 信息與計(jì)算科學(xué) 2009 年 11 月 課題來源: 自選題目 課題研究的目的和意義: 1.并不是每一門語言都支持遞歸的 . 2.有助于理解遞歸的本質(zhì) . 3.有助于理解棧 、 樹等數(shù)據(jù)結(jié)構(gòu) . 國內(nèi)外同類課題研究現(xiàn)狀及發(fā)展趨勢: 近年來 ,計(jì)算機(jī)科學(xué)技術(shù)與計(jì)算機(jī)應(yīng)用以驚人的速度發(fā)展 。 它已滲透到了人類生活的每一角 落 .現(xiàn)代社會的各個領(lǐng)域無一例外地廣泛使用著電子計(jì)算機(jī) .計(jì)算機(jī)知識已成為當(dāng)代人類文化不可缺少的重要組成部分 .研究與使用算法設(shè)計(jì)已成為必然 . 在計(jì)算機(jī)編寫程序中 ,遞歸算法對解決一大類問題是十分有效的 ,它往往使算法的描述簡潔而且易于理解 . 課題研究的主要內(nèi)容和方法,研究過程中的主要問題和解決辦法: 主要內(nèi)容:算法設(shè)計(jì)中的遞歸和非遞歸轉(zhuǎn)換 主要方法:用棧來解決算法設(shè)計(jì)中的遞歸和非遞歸轉(zhuǎn)換 主要問題: 實(shí)現(xiàn)算法設(shè)計(jì)中的遞歸和非遞歸轉(zhuǎn)換 解決方法:利用循環(huán),遞歸調(diào)用樹,棧實(shí)現(xiàn)算法設(shè)計(jì)中的遞歸和非遞歸轉(zhuǎn)換 課題研究起止時間和進(jìn)度安排: 2009 年 12 月 2 日 2010 年 2 月 9 日 課題資料搜集整理 2010 年 2 月 9 日 2010 年 4 月 6 日 材料分析、撰 寫論文 2010 年 4 月 20 日 完成論文撰寫、成稿 課題研究所需主要設(shè)備、儀器及藥品: 計(jì)算機(jī) 外出調(diào)研主要單位,訪問學(xué)者姓名: 指導(dǎo)教師審查意見: 指導(dǎo)教師 (簽字) 年 月 教研室(研究室)評審意見: _教研室(研究室)主任 (簽字) 年 月 系(部)主任審查意見: _系(部)主任 (簽字) 年 月 學(xué) 士 學(xué) 位 論 文 題 目 算法設(shè)計(jì)中的遞歸與非遞歸轉(zhuǎn)換 學(xué) 生 孫慶雨 指導(dǎo)教師 欒叢海 講師 年 級 2006 級 專 業(yè) 信息與計(jì)算科學(xué) 系 別 信息科學(xué)系 學(xué) 院 數(shù)學(xué)科學(xué)學(xué)院 哈爾濱師范大學(xué) 2010 年 5 月 算法設(shè)計(jì)中的遞歸和非遞歸轉(zhuǎn)換 孫慶雨 摘要 : 算法設(shè)計(jì)中的遞歸和非遞歸轉(zhuǎn)換是學(xué)習(xí)算法設(shè)計(jì)的基礎(chǔ), 熟練地運(yùn)用遞歸與非遞歸轉(zhuǎn) 換是算法設(shè)計(jì)的基礎(chǔ),在這篇論文中我就介紹幾種算法設(shè)計(jì)中的遞歸與非遞歸的轉(zhuǎn)換方法 .讓大家可以更好的實(shí)現(xiàn)算法設(shè)計(jì)中的遞歸和非遞歸轉(zhuǎn)換。 關(guān)鍵詞 : 算法設(shè)計(jì) 遞歸與非遞歸 轉(zhuǎn)換 三種遍歷樹的算法 遞歸與非遞歸轉(zhuǎn)換的基礎(chǔ)知識是能夠正確 理解三種樹的遍歷方法:前序,中序和后序,第一篇就是關(guān)于這三種遍歷方法的遞歸和非遞歸算法。 一、 為什么要學(xué)習(xí)遞歸與非遞歸的轉(zhuǎn)換的實(shí)現(xiàn)方法 1.并不是每一門語言都支持遞歸的 . 2.有助于理解遞歸的本質(zhì) . 3.有助于理解棧 ,樹等數(shù)據(jù)結(jié)構(gòu) . 二 、 三種遍歷樹的遞歸和非遞歸算法 遞歸與非遞歸的轉(zhuǎn)換基于以下的原理 :所有的遞歸程序都可以用樹結(jié)構(gòu)表示出來 .需要說明的是 ,這個 原理 并沒有經(jīng)過嚴(yán)格的數(shù)學(xué)證明 ,只是我的一個猜想 ,不過在至少在我遇到的例子中是適用的 .學(xué)習(xí)過樹結(jié)構(gòu)的人都 知道 ,有三種方法可以遍歷樹 :前序 ,中序 ,后序 .理解這三種遍歷方式的遞歸和非遞歸的表達(dá)方式是能夠正確實(shí)現(xiàn)轉(zhuǎn)換的關(guān)鍵之處 ,所以我們先來談?wù)勥@個 .需要說明的是 ,這里以特殊的二叉樹來說明 ,不過大多數(shù)情況下二叉樹已經(jīng)夠用 ,而且理解了二叉樹的遍歷 ,其它的樹遍歷方式就不難了。 1)前序遍歷 a)遞歸方式 : void preorder_recursive(Bitree T) /* 先序遍歷二叉樹的遞歸算法 */ if (T) visit(T); /* 訪問當(dāng)前結(jié)點(diǎn) */ preorder_recursive(T-lchild); /* 訪問左子樹 */ preorder_recursive(T-rchild); /* 訪問右子樹 */ b)非遞歸方式 void preorder_nonrecursive(Bitree T) /* 先序遍歷二叉樹的非遞歸算法 */ initstack(S); push(S,T); /* 根指針進(jìn)棧 */ while(!stackempty(S) while(gettop(S,p)&p) /* 向左走到盡頭 */ visit(p); /* 每向前走一步都訪問當(dāng)前結(jié)點(diǎn) */ push(S,p-lchild); pop(S,p); if(!stackempty(S) /* 向右走一步 */ pop(S,p); push(S,p-rchild); 2)中序遍歷 a)遞歸方式 void inorder_recursive(Bitree T) /* 中序遍歷二叉樹的遞歸算法 */ if (T) inorder_recursive(T-lchild); /* 訪問左子樹 */ visit(T); /* 訪問當(dāng)前結(jié)點(diǎn) */ inorder_recursive(T-rchild); /* 訪問右子樹 */ b)非遞歸方式 void inorder_nonrecursive(Bitree T) initstack(S); /* 初始化棧 */ push(S, T); /* 根指針入棧 */ while (!stackempty(S) while (gettop(S, p) & p) /* 向左走到盡頭 */ push(S, p-lchild); pop(S, p); /* 空指針退棧 */ if (!stackempty(S) pop(S, p); visit(p); /* 訪問當(dāng)前結(jié)點(diǎn) */ push(S, p-rchild); /* 向右走一步 */ 3)后序遍歷 a)遞歸方式 void postorder_recursive(Bitree T) /* 中序遍歷二叉樹的遞歸算法 */ if (T) postorder_recursive(T-lchild); /* 訪問左子樹 */ postorder_recursive(T-rchild); /* 訪問右子樹 */ visit(T); /* 訪問當(dāng)前結(jié)點(diǎn) */ b)非遞歸方式 typedef struct BTNode* ptr; enum 0,1,2 mark; PMType; /* 有 mark 域的結(jié)點(diǎn)指針類型 */ void postorder_nonrecursive(BiTree T) /* 后續(xù)遍歷二叉樹的非遞歸算法 */ PMType a; initstack(S); /* S 的元素為 PMType 類型 */ push (S,T,0); /* 根結(jié)點(diǎn)入棧 */ while(!stackempty(S) pop(S,a); switch(a.mark) case 0: push(S,a.ptr,1); /* 修改 mark 域 */ if(a.ptr-lchild) push(S,a.ptr-lchild,0); /* 訪問左子樹 */ break; case 1: push(S,a.ptr,2); /* 修改 mark 域 */ if(a.ptr-rchild) push(S,a.ptr-rchild,0); /* 訪問右子樹 */ break; case 2: visit(a.ptr); /* 訪問結(jié)點(diǎn) */ 三 、 實(shí)現(xiàn)遞歸與非遞歸的換轉(zhuǎn)原理和例子 原理分析 : 通常 ,一個函數(shù)在調(diào)用另一個函數(shù)之前 ,要作如下的事情 :a)將實(shí)在參數(shù) ,返回地址等信息傳遞給被調(diào)用函數(shù)保存 ; b)為被調(diào)用函數(shù)的局部變量分配存儲區(qū) ;c)將控制轉(zhuǎn)移到被調(diào)函數(shù)的入口 . 從被調(diào)用函數(shù)返回調(diào)用函數(shù)之前 ,也要做三件事情 :a)保存被調(diào)函數(shù)的計(jì)算結(jié)果 ;b)釋放被調(diào)函數(shù)的數(shù)據(jù)區(qū) ;c)依照被調(diào)函數(shù)保存的返回地址將控制轉(zhuǎn)移到調(diào)用函數(shù) .所有 的這些 ,不論是變量還是地址 ,本質(zhì)上來說都是 數(shù)據(jù) ,都是保存在系統(tǒng)所分配的棧中的 . ok,到這里已經(jīng)解決了第一個問題 :遞歸調(diào)用時數(shù)據(jù)都是保存在棧中的 ,有多少個數(shù)據(jù)需要保存就要設(shè)置多少個棧 ,而且最重要的一點(diǎn)是 :控制所有這些棧的棧頂指針都是相同的 ,否則無法實(shí)現(xiàn)同步 . 下面來解決第二個問題 :在非遞歸中 ,程序如何知道到底要轉(zhuǎn)移到哪個部分繼續(xù)執(zhí)行 ?回到上面說的樹的三種遍歷方式 ,抽象出來只有三種操作 :訪問當(dāng)前結(jié)點(diǎn) ,訪問左子樹 ,訪問右子樹 .這三種操作的順序不同 ,遍歷方式也不同 .如果我們再抽象一點(diǎn) ,對這 三種操作再進(jìn)行一個概括 ,可以得到 :a)訪問當(dāng)前結(jié)點(diǎn) :對目前的數(shù)據(jù)進(jìn)行一些處理 ;b)訪問左子樹 :變換當(dāng)前的數(shù)據(jù)以進(jìn)行下一次處理 ;c)訪問右子樹 :再次變換當(dāng)前的數(shù)據(jù)以進(jìn)行下一次處理 (與訪問左子樹所不同的方式 ). 下面以先序遍歷來說明 : void preorder_recursive(Bitree T) /* 先序遍歷二叉樹的遞歸算法 */ if (T) visit(T); /* 訪問當(dāng)前結(jié)點(diǎn) */ preorder_recursive(T-lchild); /* 訪問左子樹 */ preorder_recursive(T-rchild); /* 訪問右子樹 */ visit(T)這個操作就是對當(dāng)前數(shù)據(jù)進(jìn)行的處理 , preorder_recursive(T-lchild)就是把當(dāng)前 數(shù)據(jù)變換為它的左子樹 ,訪問右子樹的操作可以同樣理解了 . 現(xiàn)在回到我們提出的第二個問題 :如何確定轉(zhuǎn)移到哪里繼續(xù)執(zhí)行 ?關(guān)鍵在于一下三個地方 :a)確定對當(dāng)前數(shù)據(jù)的訪問順序 ,簡單一點(diǎn)說就是確定這個遞歸程序可以轉(zhuǎn)換為哪種方式遍歷的樹結(jié)構(gòu) ;b)確定這個遞歸函數(shù)轉(zhuǎn)換為遞歸調(diào)用樹時的分支是如何劃分的 ,即確定什么是這個遞歸調(diào)用樹的 左子樹 和 右子樹 c)確定這個遞歸調(diào)用樹何時返回 ,即確定什么結(jié)點(diǎn)是這個遞歸調(diào)用樹的 葉子結(jié)點(diǎn) . 三個例子 好了上面的理論知識已經(jīng)足夠了 ,下面讓我們看 看幾個例子 ,結(jié)合例子加深我們對問題的認(rèn)識 .即使上面的理論你沒有完全明白 ,不要?dú)怵H ,對事物的認(rèn)識總是曲折的 ,多看多想你一定可以明白 (事實(shí)上我也是花了兩個星期的時間才弄得比較明白得 ). 1.例子一 : f(n) = n + ; (n = 2); 這個例子相對簡單一些 ,遞歸程序如下 : int f_recursive(int n) int u1, u2, f; if (n 2) f = n + 1; else u1 = f_recursive(int)(n/2); u2 = f_recursive(int)(n/4); f = u1 * u2; return f; 下面按照我們上面說的 ,確定好遞歸調(diào)用樹的結(jié)構(gòu) ,這一步是最重要的 .首先 ,什么是葉子結(jié)點(diǎn) ,我們看到當(dāng) n = 0) switch(flagcp) case 0: /* 訪問的是根結(jié)點(diǎn) */ if (stackcp = 2) /* 左子樹入棧 */ flagcp = 1; /* 修改標(biāo)志域 */ cp+; stackcp = (int)(stackcp - 1 / 2); flagcp = 0; else /* 否則為葉子結(jié)點(diǎn) */ stackcp += 1; flagcp = 2; break; case 1: /* 訪問的是左子樹 */ if (stackcp = 2) /* 右子樹入棧 */ flagcp = 2; /* 修改標(biāo)志域 */ cp += 2; stackcp = (int)(stackcp - 2 / 4); flagcp = 1; else /* 否則為葉子結(jié)點(diǎn) */ stackcp += 1; flagcp = 2; break; case 2: /* */ if (flagcp - 1 = 2) /* 當(dāng)前是右子樹嗎 ? */ /* * 如 果是右子樹 , 那么對某一棵子樹的后序遍歷已經(jīng) * 結(jié)束 ,接下來就是對這棵子樹的根結(jié)點(diǎn)的訪問 */ stackcp - 2 = stackcp * stackcp - 1; flagcp - 2 = 2; cp = cp - 2; else /* 否則退回到后序遍歷的上一個結(jié)點(diǎn) */ cp-; break; return stack0; 算法分析 :a)flag 只有三個可能值 :0 表示第一次訪問該結(jié)點(diǎn) ,1 表示訪問的是左子樹 ,2表示 已經(jīng)結(jié)束了對某一棵子樹的訪問 ,可能當(dāng)前結(jié)點(diǎn)是這棵子樹的右子樹 ,也可能是葉子結(jié)點(diǎn) .b)每遍歷到某個結(jié)點(diǎn)的時候 ,如果這個結(jié)點(diǎn)滿足葉子結(jié)點(diǎn)的條件 ,那么把它的 flag 域設(shè)為 2;否則根據(jù)訪問的是根結(jié)點(diǎn) ,左子樹或是右子樹來設(shè)置 flag 域 ,以便決定下一次訪問該節(jié)點(diǎn)時的程序轉(zhuǎn)向 . 2.例子二 快速排序算法 遞歸算法如下 : 代碼 : void swap(int array, int low, int high) int temp; temp = arraylow; arraylow = arrayhigh; arrayhigh = temp; int partition(int array, int low, int high) int p; p = arraylow; while (low high) while (low = p) high-; swap(array,low,high); while (low high & arraylow = p) low+; swap(array,low,high); return low; void qsort_recursive(int array, int low, int high) int p; if(low high) p = partition(array, low, high); qsort_recursive(array, low, p - 1); qsort_recursive(array, p + 1, high); 需要說明一下快速排序的算法 : partition 函數(shù)根據(jù)數(shù)組中的某一個數(shù)把數(shù)組劃分為兩個部分 ,左邊的部分均不大于這個 數(shù) ,右邊的數(shù)均不小于這個數(shù) ,然后再對左右兩邊的數(shù)組再進(jìn)行劃分 .這里我們專注于遞歸與非遞歸的轉(zhuǎn)換 ,partition 函數(shù)在非遞歸函數(shù)中同樣的可以調(diào)用 (其實(shí) partition 函數(shù)就是對當(dāng)前結(jié)點(diǎn)的訪問 ). 再次進(jìn)行遞歸調(diào)用樹和棧的分析 : 遞歸調(diào)用樹 :a)對當(dāng)前結(jié)點(diǎn)的訪問是調(diào)用 partition函數(shù) ;b)左子樹 :qsort_recursive(array, low, p - 1);c)右子樹 :qsort_recursive(array, p +1, high); d)葉子結(jié)點(diǎn) :當(dāng) low high 時 ;e)可以看出這是一個先序調(diào)用的二叉樹 .棧 :要保存的數(shù)據(jù)是兩個表示范圍的坐標(biāo) . 代碼 : void qsort_nonrecursive(int array, int low, int high) int m50, n50, cp, p; /* 初始化棧和棧頂指針 */ cp = 0; m0 = low; n0 = high; while (mcp ncp) while (mcp 0) /* 壓棧 , 直到 m1cp = 0 */ while (n1cp 0) /* 壓棧 , 直到 n1cp = 0 */ cp+; m1cp = m1cp - 1; n1cp = n1cp - 1 - 1; /* 計(jì)算 akm(m - 1, 1),當(dāng) n = 0 時 */ m1cp = m1cp - 1; n1cp = 1; /* 改棧頂為 akm(m - 1, n + 1),當(dāng) m = 0 時 */ cp-; m1cp = m1cp - 1; n1cp = n1cp + 1 + 1; while (cp 0 | m1cp 0); return n10 + 1; 四 、 遞歸程序的分類及用途 遞歸程序分為兩類 :尾部遞歸和非尾部遞歸 .上面提到的幾個例子都是非尾部遞歸 ,在一個選擇分支中有至少一個的遞歸調(diào)用 .相對而言 ,尾部遞歸就容易很多了 ,因?yàn)榕c非尾部遞歸相比 ,每個選擇分支只有一個遞歸調(diào)用 , 我們在解決的時候就不需要使用到棧 ,只要循環(huán)和設(shè)置好循環(huán)體就可以了 .下面再舉幾個尾部遞歸的例子吧 ,比較簡單我就不多說什么了 . 1.例子一 g(m, n) = 0 (m = 0, n = 0) = g(m - 1, 2n) + n; (m 0, n = 0) a)遞歸程序 int g_recursive(int m, int n) if (m = 0 & n = 0) return 0; return (g_recurse(m - 1, 2*n) + n); b)非遞歸程序 int g_nonrecursive(int m, int n) int p; for (p = 0; m 0 & n = 0; m-, n *= 2) p += n; return p; 2.例子二 f(n) = n + 1 (n = 0) = n * f(n/2) (n 0) a)遞歸程序 int f_recursive(int n) if (n = 0) return 1; return (n * f_recurse(n/2); b)非遞歸程序 int f_nonrecursive(int n) int m; for (m = 1; n 0; n /= 2) m *= n; return m+; 分析完了遞歸程序的分類 ,讓我們回頭看看在向非遞歸轉(zhuǎn)換的過程中用到了什么來實(shí)現(xiàn)轉(zhuǎn)換 : 1.循環(huán) ,因?yàn)槌绦蛞谀硞€條件下一直執(zhí)行下去 ,要代替遞歸程序 ,循環(huán)必不可少 ,對于尾部遞歸 ,循環(huán)結(jié)束的條件十分容易確定 ,只要按照不同分支的條件寫出來就可以了 .而對于非尾部遞歸程序 ,循環(huán)結(jié)束的條件一般是當(dāng)棧為空時或者是結(jié)束了對遞歸調(diào)用樹的遍歷從樹的根結(jié)點(diǎn)退出時 ,而且有的時候?qū)懗?while()的形式 ,有時寫成 do .while 的形式 (如上面的 akm 函數(shù) ),具體怎樣 ,很難說清楚 ,取決于你對整個遞歸 程序的分析。 2.遞歸調(diào)用樹 ,樹的結(jié)構(gòu)在轉(zhuǎn)換的過程中是不可見的 ,你不必為轉(zhuǎn)換專門寫一個樹結(jié)構(gòu) ,不過能不能把遞歸調(diào)用中的樹遍歷方式以及葉子結(jié)點(diǎn) ,左子樹 ,右子樹等元素確定好是你能否正確解決問題的關(guān)鍵 (這一點(diǎn)已經(jīng)在上面的分析過程中展露無疑 ),確定好這些后 ,剩下的工作大部分就是按照給出的幾種不同的遍歷樹的方式把程序進(jìn)行改寫 ,這個過程就考驗(yàn)?zāi)銓浣Y(jié)構(gòu)還有遍歷方式是否很好的掌握了 (看出基礎(chǔ)的重要了嗎 ?如果回答是 ,那么和我一樣好好的打好基礎(chǔ)吧 ,一切都還不晚 !).對于尾部遞歸而言 ,可以看作沒有遞歸調(diào)用樹 ,所以尾 部遞歸的難度大大降低了。 3.棧 ,非尾部調(diào)用中需要棧來保存數(shù)據(jù) ,這一點(diǎn)已經(jīng)很清楚了 ,需要注意幾個問題 :a)棧有時可能會出現(xiàn)不夠的情況 ,拿上面的 akm函數(shù)來說 ,我用的 50個元素的數(shù)組 ,你如果把 m和n 值設(shè)置得大一些 ,這個棧就不能用了 ,有時你的算法正確了 ,不過沒有注意到這個問題還是會出錯的 ;反過來說 ,在遞歸調(diào)用中 ,系統(tǒng)或者編譯器的優(yōu)化功能不夠好的化 ,在這個棧上可能會消耗很多空間 ,這個時候如果你把程序改成非遞歸的形式 ,然后再用動態(tài)分配技術(shù)分配??赡芫蜁殉绦虻男阅芴岣咭淮髩K -這也是我們學(xué)習(xí)這門技術(shù)的意義 之一 ,因?yàn)橄到y(tǒng)是機(jī)械化的 ,你如果知道更好的優(yōu)化辦法 ,為什么不用呢 ? 什么時候可以用遞歸解決問題 ?到了這一步 ,如果你對于上面說的已經(jīng)相當(dāng)明白的話 ,這個問題不難回答 ,如果我們要解決的問題要分成幾個小的部分 ,而其中的一些與你要解決的問題是一樣的 ,只不過是問題的規(guī)模 (如參數(shù)等 )小了 ,那么這樣的問題可以用遞歸來解決 .根據(jù)問題設(shè)計(jì)好一個遞歸是所有這些的基礎(chǔ) ,轉(zhuǎn)換也是在原來的遞歸程序上進(jìn)行的 ,所以這一步一定要做好 .通常 ,設(shè)計(jì)一個遞歸程序要注意一下幾個問題 :a)可以遞歸解決的問題是什么 ?b)入口和出口參數(shù)是什么 -即要明確好出入的接口。 說白了,遞歸程序是在對所要解決的問題進(jìn)行數(shù)學(xué)上的分析后給出的,也就是說遞歸算法是從純數(shù)學(xué)的角度出 發(fā)考慮的,而非遞歸的算法則是在遞歸算法的基礎(chǔ)上考慮計(jì)算機(jī)內(nèi)部處理遞歸程序的機(jī)制考慮來實(shí)現(xiàn)轉(zhuǎn)換的。任何一個遞歸算法,只要能夠準(zhǔn)確的寫出遞歸調(diào)用樹的情況,分析清楚對當(dāng)前結(jié)點(diǎn)的訪問操作是什么,左子樹右子樹是什么那么實(shí)現(xiàn)起遞歸和非遞歸的轉(zhuǎn)換就很輕松了。 參考文獻(xiàn): 1 張益新 、 沈雁編 : 算法導(dǎo)論 , 國防科大出版社 。 2 嚴(yán)蔚敏 : 數(shù)據(jù)結(jié)構(gòu) , 清華大學(xué)出版社 。 3 徐孝凱:數(shù)據(jù) 結(jié)構(gòu),清華大學(xué)出版社 2006 年 9 月第 2 版。 Recursive algorithm design and conversion of non-recursive SUN Qing-Yu Ab

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論