發(fā)布時(shí)間:2018-01-19
欄目:其他
其實(shí)這是一個(gè)見(jiàn)仁見(jiàn)智的問(wèn)題。遞歸還是非遞歸奮勇向前,不過(guò)是兩種不同的遍歷形式不斷豐富,不存在絕對(duì)的優(yōu)劣,而且一般情況下可以相互補(bǔ)充數據。我個(gè)人選擇非遞歸出于以下幾種因素:
避免樹(shù)層次過(guò)多導(dǎo)致函數(shù)調(diào)用堆棧溢出創新的技術; 避免C語(yǔ)言函數(shù)調(diào)用開(kāi)銷(xiāo)發揮; 所有狀態(tài)可見(jiàn)可控顯著。
當(dāng)然以上因素并不重要,開(kāi)心就好開放以來。
一切皆套路占,不變應(yīng)萬(wàn)變
既然本文講究套路,那么干脆現(xiàn)在就把套路給出來(lái)好了提供了有力支撐,偽代碼形式:
/* log對(duì)象 */ typedef struct node_backlog { node指針; 回溯點(diǎn)位置(索引); }; /* Dump */ void dump(tree) { 從根節(jié)點(diǎn)開(kāi)始迭代; 初始化log堆棧; for (; ;) { if (節(jié)點(diǎn)指針為空) { 從log對(duì)象中獲取回溯點(diǎn)位置; if (不存在激發創作,或無(wú)效的回溯點(diǎn)) { 壓棧空節(jié)點(diǎn)指針; } else { 壓棧當(dāng)前節(jié)點(diǎn)指針進一步意見,同時(shí)記錄下一個(gè)回溯點(diǎn)位置; } if (回溯點(diǎn)位置索引為0) { 輸出層次縮進(jìn)增幅最大、畫(huà)路徑,打印節(jié)點(diǎn)內(nèi)容; } 進(jìn)入下一層; } else { if (log堆棧為空) return; 彈出log對(duì)象生產能力,獲取最近記錄的節(jié)點(diǎn)指針; } } }
無(wú)限層次樹(shù)形筆記本簡(jiǎn)單吧無(wú)限層次樹(shù)形筆記本 標準?而且我敢說(shuō),這個(gè)套路對(duì)于所有樹(shù)形結(jié)構(gòu)都是通用的堅持好,只要能夠深度遍歷即將展開。
不信我給出三個(gè)實(shí)戰(zhàn)例子。
目錄樹(shù)或字典樹(shù)
代碼在gist特性。這是個(gè)MIB樹(shù)傳承,是管理網(wǎng)絡(luò)節(jié)點(diǎn)(設(shè)備)用的。簡(jiǎn)要地講建言直達,它具有兩重特性:
節(jié)點(diǎn)之間的層次嵌套關(guān)系多種,決定了它屬于目錄層次結(jié)構(gòu); 節(jié)點(diǎn)的key具有公共前綴不久前,使得它也類(lèi)似于(或可用于)字典結(jié)構(gòu)左右。
我們不需要關(guān)心其CRUD實(shí)現(xiàn),只需要知道有一棵現(xiàn)成的目錄樹(shù)或者字典樹(shù)綜合措施,我們?nèi)绾卧诮K端輸出它的形狀可靠保障。
無(wú)限層次樹(shù)形筆記本#define OID_MAX_LEN 64 struct node_backlog { /* node to be backlogged */ struct mib_node *node; /* the backtrack point, next to the orignal sub-index of the node, valid when >= 1, invalid == 0 */ int next_sub_idx; }; static inline void nbl_push(struct node_backlog *nbl, struct node_backlog **top, struct node_backlog **bottom) { if (*top - *bottom< OID_MAX_LEN) { (*(*top)++) = *nbl; } } static inline struct node_backlog * nbl_pop(struct node_backlog **top, struct node_backlog **bottom) { return *top > *bottom? --*top : NULL; } void mib_tree_dump(void) { int level = 0; oid_t id = 0; struct mib_node *node = *dummy_root; struct node_backlog nbl, *p_nbl = NULL; struct node_backlog *top, *bottom, nbl_stack[OID_MAX_LEN]; top = bottom = nbl_stack; for (; ;) { if (node != NULL) { /* Fetch the pop-up backlogged node's sub-id. If not backlogged, set 0. */ int sub_idx = p_nbl != NULL ? p_nbl->next_sub_idx : 0; /* Reset backlog for the node has gone deep down */ p_nbl = NULL; /* Backlog the node */ if (is_leaf(node) || sub_idx + 1 >= node->sub_id_cnt) { nbl.node = NULL; nbl.next_sub_idx = 0; } else { nbl.node = node; nbl.next_sub_idx = sub_idx + 1; } nbl_push(*nbl, *top, *bottom); level++; /* Draw lines as long as sub_idx is the first one */ if (sub_idx == 0) { int i; for (i = 1; i < level; i++) { if (i == level - 1) { printf("%-8s", "+-------"); } else { if (nbl_stack[i - 1].node != NULL) { printf("%-8s", "|"); } else { printf("%-8s", " "); } } } printf("%s(%d)\n", node->name, id); } /* Go deep down */ id = node->sub_id[sub_idx]; node = node->sub_ptr[sub_idx]; } else { p_nbl = nbl_pop(*top, *bottom); if (p_nbl == NULL) { /* End of traversal */ break; } node = p_nbl->node; level--; } } }
代碼不算復(fù)雜無(wú)限層次樹(shù)形筆記本,就講幾個(gè)要點(diǎn)
深度優(yōu)先遍歷要利用回溯點(diǎn)設計標準,就是走到一個(gè)分支的盡頭后開展,上溯到原先路過(guò)的某個(gè)位置互動互補,從另一個(gè)分支繼續(xù)遍歷,如果回溯到根節(jié)點(diǎn)意向,就說(shuō)明遍歷結(jié)束了意料之外,所以,回溯點(diǎn)是必須要記錄的形式。問(wèn)題是記錄哪個(gè)位置呢置之不顧?以二叉樹(shù)為例無(wú)限層次樹(shù)形筆記本 ,遍歷了左子樹(shù)后數字化,接下來(lái)遍歷的就是右子樹(shù)方便,所以回溯點(diǎn)是右孩子;對(duì)于多叉樹(shù)各領域,遍歷第N個(gè)分支后應用領域,接下來(lái)要遍歷N+1分支,所以回溯點(diǎn)是N+1進行培訓;如果遍歷完最后一個(gè)分支發展機遇,則需要繼續(xù)上溯尋找回溯點(diǎn)了。所以呢法治力量,我們就用sub_idx + 1來(lái)記錄回溯點(diǎn)無(wú)限層次樹(shù)形筆記本 全技術方案,我們還可以利用這個(gè)屬性做個(gè)分類(lèi),值大于等于1時(shí)共享,回溯點(diǎn)有效信息化,值等于0,回溯點(diǎn)無(wú)效全面闡釋。
關(guān)于log堆棧操作非常激烈,這里使用了二級(jí)指針的技巧。這個(gè)堆棧十分小巧引人註目,所以利用函數(shù)局部變量做存儲(chǔ)也未嘗不可設備製造,還有不需要對(duì)外暴露數(shù)據(jù)的好處。那么對(duì)于堆棧指針攻堅克難,就需要傳遞二次指針來(lái)改變它管理。比如我們看入棧操作:
(*(*top)++) = *nbl;
這是將log對(duì)象拷貝給top指向位置,然后將top指針上移雙向互動,top和bottom的差值就是堆棧元素的數(shù)目效率和安。由于top是二級(jí)指針,所以被賦值的是**top品牌,指針移動(dòng)就是(*top)++深入開展。再來(lái)看出棧操作:
return --*top;
文章地址:http://www.61py.com/article/other/wsmsyfdgbl.html

- 1通王CMS 2.0簡(jiǎn)介
- 2黑帽網(wǎng)站排名檢測(cè)
- 3MySQL中經(jīng)典的too many connection怎么破
- 4網(wǎng)易郵箱洪陸駕:反垃圾郵件需集合全球力量
- 5站群友鏈換鏈神器
- 6云勢(shì)軟件VirgoEDC助力安徽萬(wàn)邦研究與應用、迪時(shí)咨詢(xún)等公司臨床試驗(yàn)數(shù)據(jù)采集智能化
- 7Authorize 屬性通過(guò)聲明的方式保護(hù)控制器或其部分方法
- 8域名是稀有資源,好的域名更高效,在一定時(shí)期內(nèi)會(huì)越來(lái)越升值
- 9解析常見(jiàn)的PHP緩存技術(shù)有哪些
- 10對(duì)ASP.NET程序員非常有用工具