遞迴法找出某節點的所有父節點直到根節點
今天在C# and Java QQ群裡看到有人在問如下一題:
“
出道題目啊,我的面試題,碰到2次了
sid pid
A NULL
B A
C NULL
D C
E D
F E
sid是子節點,pid是父節點,查出f的所有父節點,一直查到他的根節點為止 ”
要求用sql語句寫出來,一時難倒一片。
仔細分析該題,實際上主要考查演算法技巧,使用sql語句查詢和高階語言實現演算法基本一樣。我們只要設計一個遞迴函式即可(sql語句也可以設計遞迴函式的),其基本演算法如下:
我們假定需要查詢strid的所有父節點則:
準備一個數組儲存所有目標節點 ArrAllPids
將strid的所有父節點加入陣列ArrAllPids
遞迴過程如下:
1) 找出strid的父節點strpid
2)如果strpid為NULL則退出遞迴,否則:
將strpid加入陣列ArrAllPids
將strpid的所有父節點加入陣列ArrAllPids中
此演算法用sql語句或高階語言都可實現,為了除錯方便我暫時用C++做了除錯,結果正確程式碼如下:
#include<stdio.h>
#include<string.h>
struct ps
{
char sid[10];// 子節點
char pid[10];//父節點
};
struct ps AllPs[6]
=
{
"A","NULL",
"B","A",
"C" ,"NULL",
"D", "C",
"E", "D",
"F", "E"
};
int PSSize = 6;
//儲存所有父節點
char ArrAllPids[50][10];
int pidSize = 0;
//將strpid的所有父節點加入陣列AllAllPids中
void AddAllPidsToArr(char strid[])
{
//查詢strsid的父節點到strpid中
char strpid[10];
for (int i=0;i<PSSize;i++)
{
if (!strcmp(AllPs[i].sid,strid))
{
strcpy(strpid,AllPs[i].pid);break;
}
}
//如果為NULL
if (!strcmp(strpid,"NULL"))
{
return;
}
else
{
strcpy(ArrAllPids[pidSize],strpid);//將strpid節點加入陣列ArrAllPids中
pidSize++;
AddAllPidsToArr(strpid);//將strpid的所有父節點加入陣列ArrAllPids中
}
}
void main()
{
AddAllPidsToArr("F");
for (int i=0;i<pidSize;i++)
{
printf("%s/n",ArrAllPids[i]);
}
}