วิธีที่ฉันใช้ในสองภาษาและเชื่อว่า ESRI ใช้ (ขออภัยไม่มีการอ้างอิงอื่นนอกเหนือจาก Jenson และ Domingue ที่อ้างถึงที่อื่นในหน้านี้) คือการเริ่มต้นที่เซลล์ "pour-point" หรือเซลล์ ที่ขอบของตารางทิศทางการไหล (fdr) ตรวจสอบแปดเพื่อนบ้านเพื่อค้นหาว่าการไหลโดยตรงเหล่านั้นเข้าสู่เซลล์ปัจจุบันและกำหนดเซลล์เหล่านั้นให้กับ "ลุ่มน้ำ" ในตารางผลลัพธ์ จากนั้นฟังก์ชั่นนี้จะเรียกซ้ำตัวเองหนึ่งครั้งสำหรับแต่ละเพื่อนบ้านที่ไหลเข้ามา กระบวนการนี้ซ้ำจนกว่าเซลล์ไหลเข้าทั้งหมดจะหมดลงสำหรับจุดไหลและจากนั้นจะทำซ้ำสำหรับจุดไหลทั้งหมด
การออกแบบอัลกอริธึมแบบเรียกซ้ำอาจค่อนข้างแพงเพราะสามารถพยายามเก็บข้อมูลจำนวนมากในหน่วยความจำได้โดยต้องสลับ / หน้าไปยังดิสก์ดังนั้นโดยทั่วไปแล้วจะทำให้ i / o ช้าลง
(ดูความคิดเห็นของ whuber ด้านล่างเกี่ยวกับวิธีการเรียกซ้ำแบบต่าง ๆ ถ้าคุณจะ RYO)
_____________ แก้ไข _____________
ขุดรหัส C เก่าของฉันเป็นตัวอย่าง (หมายเหตุ: ถึงแม้ว่าไพ ธ อนส่วนใหญ่อาจต้องการเรียกใช้จากห้อง แต่ก็ไม่ควรเลวร้ายเกินไป) คิดว่าน่าจะเป็นตัวอย่างที่น่าสนใจ ถึงแม้ว่าผมก็แค่ตอนนี้เผินๆคุ้นเคย w / กว้างแรก VS recursion ลึกแรกฉันคิดว่ากิจวัตรประจำวันของฉันคือความลึกแรก (และที่คำอธิบายภาษาของฉันธรรมชาติดังกล่าวข้างต้นเป็นความเข้าใจผิด) ตามจริงโพสต์ StackOverflow นี้ (หวังว่า @ whuber หรือบุคคลอื่นที่ฉลาดกว่าที่ฉันสามารถยืนยัน / ปฏิเสธ)
รหัส: คำอธิบาย: idir
เป็นแรสเตอร์ของค่าทิศทางการไหล offset
อ้างถึงเซลล์กลางที่กำลังวิเคราะห์อยู่และoff
ตรวจสอบเพื่อนบ้านของเซลล์นั้น ๆ สิ่งนี้จะเรียกฟังก์ชันอื่นdoes_it_flow_into_me
ซึ่งส่งกลับบูลีนว่า flowdir ของเซลล์ข้างเคียงชี้ไปที่เซลล์ปัจจุบันหรือไม่ หากเป็นจริงสำหรับเพื่อนบ้านให้เรียกเก็บเงินจากตำแหน่งนั้น
void shed(int init_x, int init_y, int basin_id){
int i, j, offset, off, flow_dir;
offset = ((init_y - 1) * nc) + (init_x - 1);
*(basin + offset) = basin_id;
/* kernel analysis */
for (i = -1; i < 2; i++) {
for (j = -1; j < 2; j++) {
if ((i) || (j)) {
off = offset + (j * nc + i);
flow_dir = *(idir + off);
if (does_it_flow_into_me(i,j,flow_dir)){
shed(init_x+i, init_y+j,basin_id);
}
} /*not center */
} /* do - j */
} /* do - i */
}