算法和流程圖(及N-S流程圖)


算法和流程圖

2.1.1算法

計算機語言只是一種工具。光學習語言的規則還不夠,最重要的是學會針對各種類型的問題,擬定出有效的解決方法和步驟即算法。有了正確而有效的算法,可以利用任何一種計算機高級語言編寫程序,使計算機進行工作。因此,設計算法是程序設計的核心。

並非只有“計算”的問題才有算法。廣義地說,為解決一個問題而采取的方法和步驟,稱為“算法”。不要把“計算方法”(computational method)和“算法”(algorithm)這兩個詞混淆。前者指的是求數值解的近似方法,后者是指解決問題的一步一步的過程。在解一個數值計算問題時,除了要選擇合適的計算方法外,還要根據這個計算方法寫出如何讓計算機一步一步執行以求解的算法。對於計算機外行來說,他們可以只使用別人已設計好的現成算法,只需根據算法的要求給以必要的輸入,就能得到輸出的結果。對他們來說,算法如同一個“黑箱子”一樣,他們可以不了解“黑箱子”中的結構,只是從外部特性上了解算法的作用,即可方便地使用算法。但對於程序設計人員來說,必須會設計算法,並且根據算法編寫程序。

對同一個問題,可以有不同的解題方法和步驟。例如,求1+2+3+…+100,可以先進行1+2,再加3,再加4,一直加到100,也可采取100+(1+99)+(2+98)+…+(49+51)+50=100+50+49×100=5050。還可以有其它的方法。當然,方法有優劣之分。有的方法只需進行很少的步驟,而有些方法則需要較多的步驟。一般說,希望采用方法簡單,運算步驟少的方法。因此,為了有效地進行解題,不僅需要保證算法正確,還要考慮算法的質量,選擇合適的算法。

一個計算問題的解決過程通常包含下面幾步:

          確立所需解決的問題以及最后應達到的要求。必須保證在任務一開始就對它有詳細而確切的了解,避免模棱兩可和含混不清之處。

          分析問題構造模型。在得到一個基本的物理模型后,用數學語言描述它,例如列出解題的數學公式或聯立方程式,即建立數學模型。

          選擇計算方法。如定積分求值問題,可以用矩形法、梯形法或辛普生法等不同的方法。因此用計算機解題應當先確定用哪一種方法來計算。專門有一門學科“計算方法”,就是研究用什么方法最有效、最近似地實現各種數值計算的,換句話說,計算方法是研究數值計算的近似方法的。

          確定算法和畫流程圖。在編寫程序之前,應當整理好思路,設想好一步一步怎樣運算或處理,即為“算法”。把它用框圖畫出來,用一個框表示要完成的一個或幾個步驟,它表示工作的流程,稱為流程圖。它能使人們思路清楚,減少編寫程序中的錯誤。

          編寫程序。

          程序調試,即試算。一個復雜的程序往往不是一次上機就能通過並得到正確的結果的,需要反復試算修改,才得到正確的可供正式運行的程序。

           正式運行得到必要的運算結果。

2.1.2流程圖

為了表示一個算法,可以用不同的方法。常用的有:自然語言;傳統流程圖;結構化流程圖;偽代碼;PAD圖等。這里我們主要介紹流程圖。

a)    傳統流程圖

用圖表示的算法就是流程圖。流程圖是用一些圖框來表示各種類型的操作,在框內寫出各個步驟,然后用帶箭頭的線把它們連接起來,以表示執行的先后順序。用圖形表示算法,直觀形象,易於理解。

美國國家標准化協會ANSI曾規定了一些常用的流程圖符號,為世界各國程序工作者普遍采用。最常用的流程圖符號見圖。

        處理框(矩形框),表示一般的處理功能。

        判斷框(菱形框),表示對一個給定的條件進行判斷,根據給定的條件是否成立決定如何執行其后的操作。它有一個入口,二個出口。

        輸入輸出框(平行四邊形框)。

        起止框(圓弧形框),表示流程開始或結束。

        連接點(圓圈),用於將畫在不同地方的流程線連接起來。如圖中有兩個以1標志的連接點(在連接點圈中寫上“l”)則表示這兩個點是連接在一起的,相當於一個點一樣。用連接點,可以避免流程線的交叉或過長,使流程圖清晰。

        流程線(指向線),表示流程的路徑和方向。

        注釋框, 是為了對流程圖中某些框的操作做必要的補充說明,以幫助閱讀流程圖的人更好地理解流程圖的作用。它不是流程圖中必要的部分,不反映流程和操作。

程序框圖表示程序內各步驟的內容以及它們的關系和執行的順序。它說明了程序的邏輯結構。框圖應該足夠詳細,以便可以按照它順利地寫出程序,而不必在編寫時臨時構思,甚至出現邏輯錯誤。流程圖不僅可以指導編寫程序,而且可以在調試程序中用來檢查程序的正確性。如果框圖是正確的而結果不對,則按照框圖逐步檢查程序是很容易發現其錯誤的。流程圖還能作為程序說明書的一部分提供給別人,以便幫助別人理解你編寫程序的思路和結構。

例:對一個大於或等於3的正整數,判斷它是不是一個素數。

所謂素數,是指除l和該數本身之外,不能被其它任何整數整除的數。例如,13是素數,因為它不能被2,3,4,…,12整除。

判斷一個數N(N>3)是否素數的方法是很簡單的:將N作為被除數,將2到(N—1)各個整數輪流作為除數,如果都不能被整除,則N為素數。算法可以表示如下:

 

① 輸入N的值。

② I=2。

③ N被I除。

④ 如果余數為0,表示N能被I整除,則打印N“不是素數”,算法結束。否則繼續。

⑤ I=I+1。

⑥ 如果I≤N-l,返回③。否則打印N“是素數”。然后結束。

實際上.N不必被2到(N一1)的整數除,只需被2到N/2間整數除即可,甚至只需被2到之間的整數除即可。例如,判斷13是否素數,只需將13被2,3除即可,如都除不盡,N必為素數。步驟⑥可改為:

⑥:如果I≤,返回③。否則算法結束。

Fortran代碼文件為[e_212_01.f][e_212_02.f]

 

 

a)    三種基本結構

傳統的流程圖用流程線指出各框的執行順序,對流程線的使用沒有嚴格限制。因此,使用者可以毫不受限制地使流程隨意地轉來轉去,使流程圖變得毫無規律,閱讀者要花很大精力去追蹤流程,使人難以理解算法的邏輯。如果我們寫出的算法能限制流程的無規律任意轉向,而像一本書那樣,由各章各節順序組成,那樣,閱讀起來就很方便,不會有任何困難,只需從頭到尾順序地看下去即可。

為了提高算法的質量,使算法的設計和閱讀方便,必須限制箭頭的濫用,即不允許無規律地使流程亂轉向,只能按順序地進行下去。但是,算法上難免會包含一些分支和循環,而不可能全部由一個一個框順序組成。如上例不是由各框順序進行的,包含一些流程的向前或向后的非順序轉移。為了解決這個問題,人們設想,如果規定出幾種基本結構,然后由這些基本結構按一定規律組成一個算法結構,就如同用一些基本預制構件來搭成房屋一樣,整個算法的結構是由上而下地將各個基本結構順序排列起來的。1966年,Bohra和Jacoplni提出了以下三種基本結構,用這三種基本結構作為表示一個良好算法的基本單元。

        順序結構:如圖所示的虛線框內,A和B兩個框是順序執行的。順序結構是最簡單的一種基本結構。

       
選擇結構:如圖所示的虛線框中包含一個判斷框。根據給定的條件p是否成立而選擇執行A和B。p條件可以是“x>0”或“x>y”等。注意,無論p條件是否成立,只能執行A或B之一,不可能既執行A又執行B。無論走哪一條路徑,在執行完A或B之后將脫離選擇結構。A或B兩個框中可以有一個是空的,即不執行任何操作。

 

       

       
       


循環結構:又稱重復結構,即反復執行某一部分的操作。有兩類循環結構:

          當型(While):當給定的條件p成立時,執行A框操作,然后再判斷p條件是否成立。如果仍然成立,再執行A框,如此反復直到p條件不成立為止。此時不執行A框而脫離循環結構。

          直到型(Until):先執行A框,然后判斷給定的p條件是否成立。如果p條件不成立,則再執行A,然后再對p條件作判斷。如此反復直到給定的p條件成立為止。此時脫離本循環結構。

       
       
 

 

注意兩種循環結構的異同:(1)兩種循環結構都能處理需要重復執行的操作。(2)當型循環是“先判斷(條件是否成立),后執行(A框)”。而直到型循環則是“先執行(A框),后判斷(條件)”。(3)當型循環是當給定條件成立滿足時執行A框,而直到型循環則是在給定條件不成立時執行A框。

 
   

 

同一個問題既可以用當型循環來處理,也可以用直到型循環來處理。對同一個問題,如分別用當型循環結構和直到型循環結構來處理的話,則兩者結構中的判斷框內的判斷條件恰為互逆條件。Fortran77和90/95標准都不提供do until語句,Compaq Visual Fortran也不提供此擴展(但有些計算機系統則提供),因此需要將直到型循環轉換成一個當型循環結構:直到型循環等於一個A框加上一個當型循環,同時將給定的判斷條件“取反”。

b)    結構流程圖

1973年美國學者I.Nassi和B.Shneiderman提出了一種新的流程圖形式。在這種流程圖中,完全去掉了帶箭頭的流程線。全部算法寫在一個矩形框內。在該框內還可以包含其它的從屬於它的框,即可由一些基本的框組成一個大的框。這種適於結構化程序設計的流程圖稱N-S結構化流程圖,它用以下的流程圖符號:

 
   


(1)順序結構:A和B兩個框組成一個順序結構。

 
   


(2)選擇結構:當p條件成立時執行A操作,p不成立則執行B操作結構。

       
     
   
 


(3)循環結構:當型循環結構下,圖符表示先判斷后執行,當p條件成立時反復執行A操作,直到p條件不成立為止。

直到型循環結構下,圖符表示先執行后判斷,當p條件不成立時反復執行A操作,直到p條件成立為止。

用以上三種N-S流程圖中的基本框.可以組成復雜的N-S流程圖,以表示算法。

例:將判別素數的算法用N-S流程圖表示。

上面的非結構化流程圖不是由三種基本結構組成的:圖中間的循環部分有兩個出口,不符合基本結構的特點。由於不能直接分解為三種基本結構,應當先作必要的變換再用N-S流程圖的三種基本結構的符號來表示。即將第一個菱形框的兩個出口匯合在一點。其方法是設一個標志值K,它的初始狀態為0(表示N為素數),當K≠0時為非素數。注意當型和直到型的判斷條件。

Fortran代碼文件為[e_212_03.f90]

N-S圖表示算法的優點是:比傳統流程圖緊湊易畫,尤其是它廢除了流程線。整個算法結構是由各個基本結構按順序組成的,其上下順序就是執行時的順序。寫算法和看算法只需從上到下進行就可以了,十分方便。歸納起來,一個結構化的算法是由一些基本結構順序組成的;在基本結構之間不存在向前或向后的跳轉,流程的轉移只存在於一個基本結構范圍之內(如循環中流程的跳轉);一個非結構化的算法可以用一個等價的結構化算法代替,其功能不變。如果一個算法不能分解為若干個基本結構,則它必然不是一個結構化的算法。

c)    偽代碼表示的算法

用傳統的流程圖和N-S圖表示算法直觀易懂,但畫起來比較費事,在設計一個算法時,可能要反復修改,而修改流程圖是比較麻煩的。因此,流程圖適宜於表示一個算法,但在設計算法過程中使用不是很理想的(尤其是當算法比較復雜、需要反復修改時)。為了設計算法時方便,常用一種稱為偽代碼的工具。偽代碼是用介於自然語言和計算機語言之間的文字和符號來描述算法。它如同一篇文章一樣,自上而下地寫下來。每一行(或幾行)表示一個基本操作。它不用圖形符號,因此書寫方便、格式緊湊,易懂也便於向計算機語言算法(即程序)過渡。

可以用英文、漢字、中英文混合表示算法,以便於書寫和閱讀為原則。用偽代碼寫算法並無固定的、嚴格的語法規則,只要把意思表達清楚,並且書寫的格式要寫成清晰易讀的形式。例如,對於電子在特殊幾何構型材料中的散射問題:[sphere-1.doc][sphere-2.doc][sphere.f]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM