PL SQL的遞迴呼叫

2021-08-25 02:06:39 字數 3782 閱讀 7899

已知表route,欄位和內容如下:

起始節點 終止節點 距離

a b 100

a c 150

a d 200

b e 300

b f 800

e g 100

e h 300

要求找出從節點a開始能到達的所有路徑

1.建立表route,插入資料

create table route (

begin_node varchar2(3),

end_node varchar2(3),

distance number(4));

insert into route values('a','b',100);

insert into route values('a','c',150);

insert into route values('a','d',200);

insert into route values('b','e',300);

insert into route values('b','f',800);

insert into route values('e','g',300);

insert into route values('e','h',300);

2.建立t_node型別

create or replace type t_node as object (name varchar2(3), distance number(5));

3.建立t_node_array型別,是t_node型別陣列

create or replace type t_node_array is table of t_node;

4.建立isloopnode(node t_node, nodes t_node_array, nodes_depth number)函式,判斷node是否在nodes中出現過

create or replace function isloopnode(node t_node, nodes t_node_array, nodes_depth number)

return boolean

isi number;

begin

for i in 1..nodes_depth loop

if nodes(i).name = node.name then

return true;

end if;

end loop;

return false;

end;

5.建立過程printpath來列印路徑

create or replace procedure printpath(nodes t_node_array, nodes_depth number)

asi number(4);

begin

for i in 1..nodes_depth loop

if i<>1 then

dbms_output.put('-->');

end if;

dbms_output.put(nodes(i).name||'[');

dbms_output.put(nodes(i).distance||']');

end loop;

dbms_output.put_line('');

end;

6.遍歷過程iterate

create or replace procedure iterate(node in t_node, nodesstack in out t_node_array, stackdepth in out number)

asnextnode t_node;

nextnodes t_node_array := t_node_array();

cursor c_route is select end_node,distance from route where begin_node=node.name;

tempstr varchar2(3);

tempint number(4);

i number(4);

begin

--將當前節點存入路徑棧中

if stackdepth = nodesstack.count then

--需要擴充套件棧

nodesstack.extend(1);

end if;

stackdepth := stackdepth + 1;

nodesstack(stackdepth):= node;

--找開游標,查詢後續節點

open c_route;

fetch c_route into tempstr, tempint;

--沒有後續節點

if c_route%notfound then

--列印出本條線路

printpath(nodesstack, stackdepth);

close c_route;

--回歸到上一節點

stackdepth := stackdepth - 1;

return;

end if;

--依次處理後續節點

--先將節點存到臨時陣列nextnodes,以期盡快關閉游標

while c_route%found loop

--路程要累積起來

nextnode := t_node(tempstr, nodesstack(stackdepth).distance + tempint);

--存入臨時陣列

nextnodes.extend(1);

nextnodes(nextnodes.count) := nextnode;

fetch c_route into tempstr, tempint;

end loop;

close c_route;

for i in 1..nextnodes.count loop

nextnode := nextnodes(i);

--判斷是否與路徑上的先前節點重複

if isloopnode(nextnode, nodesstack, stackdepth) then

--列印出本條線路

printpath(nodesstack, stackdepth);

--回歸到上一節點

stackdepth := stackdepth - 1;

return;

end if;

--非重複節點

iterate(nextnode, nodesstack, stackdepth);

end loop;

--處理完畢本節點,回歸到上一節點

stackdepth := stackdepth - 1;

end;

7.pl/sql呼叫iterate

declare

node t_node;

nodesstack t_node_array:=t_node_array();

stackdepth number(4);

begin

node:=t_node('a', 0);

stackdepth:=0;

iterate(node,nodesstack,stackdepth);

end;

8.執行結果

a[0]-->b[100]-->e[400]-->g[700]

a[0]-->b[100]-->e[400]-->h[700]

a[0]-->b[100]-->f[900]

a[0]-->c[150]

a[0]-->d[200]

函式的遞迴呼叫

乙個函式在它的函式體內呼叫它自身稱為遞迴呼叫。這種函式稱為遞迴函式。c語言允許函式的遞迴呼叫。在遞迴呼叫中,主調函式又是被調函式。執行遞迴函式將反覆呼叫其自身。每呼叫一次就進入新的一層。例如有函式f如下 int f int x 這個函式是乙個遞迴函式。但是執行該函式將無休止地呼叫其自身,這當然是不正...

遞迴的呼叫順序

鋪地板 地板長度為4寬為1,磚頭為1x1 1x2。一共有多少種方法填滿地板,遞迴解題。static int n 4 static int result 0 static void getresult int len if len n return if len 1 n if len 2 n getr...

遞迴呼叫的理解

關於遞迴呼叫的理解問題 前幾天做題的時候,發現 資料結構高分筆記 第一章有這樣乙個思考題,對理解遞迴呼叫幫助很大,題目如下 題目 逆序輸出單鏈表的資料域,要求 指標l指向鍊錶首元結點,且只用l乙個指標 一 分析 在單鏈表的情況下,要逆序輸出結點資料只用乙個指標,除了用遞迴呼叫,好象沒有別的方法了。關...