内容简介:在react树中获取当前实例节点的父节点实例获取节点A与B的最近的公共祖先节点算法题:找到两个链表的公共节点
面试中,经常遇到的一个简单算法题:查找两个单链表的公共节点
最近在读react源码的时候发现一个react树中对该算法的运用(见getLowestCommonAncestor函数),在此做简单的记录。
git地址getParent
在react树中获取当前实例节点的父节点实例
//HostComponent组件对应的DOM,比如App的tag=3, 表示为类组件,其child为tag=5对应div元素。 function getParent(inst) { do { inst = inst.return; // TODO: If this is a HostRoot we might want to bail out. // That is depending on if we want nested subtrees (layers) to bubble // events to their parent. We could also go through parentNode on the // host node but that wouldn't work for React Native and doesn't let us // do the portal feature. } while (inst && inst.tag !== HostComponent); if (inst) { return inst; } return null; }
getLowestCommonAncestor
获取节点A与B的最近的公共祖先节点
算法题:找到两个链表的公共节点
export function getLowestCommonAncestor(instA, instB) { //获取子节点A在树中的深度 let depthA = 0; for (let tempA = instA; tempA; tempA = getParent(tempA)) { depthA++; } //获取子节点B在树中的深度 let depthB = 0; for (let tempB = instB; tempB; tempB = getParent(tempB)) { depthB++; } // If A is deeper, crawl up. // 如果A的高度高,那么A节点先往上走depthA - depthB个节点,最后同时走,直到父节点是同一个 while (depthA - depthB > 0) { instA = getParent(instA); depthA--; } // 如果B的高度高,那么B节点先往上走depthB - depthB个节点,最后同时走,直到父节点是同一个 // If B is deeper, crawl up. while (depthB - depthA > 0) { instB = getParent(instB); depthB--; } // Walk in lockstep until we find a match. // 现在,指针所处的位置的高度一致,可以同时往上查找,直到找到公共的节点 let depth = depthA; while (depth--) { if (instA === instB || instA === instB.alternate) { return instA; } instA = getParent(instA); instB = getParent(instB); } return null; }
isAncestor
判断A节点是否是B节点的祖先节点
export function isAncestor(instA, instB) { while (instB) { if (instA === instB || instA === instB.alternate) { return true; } instB = getParent(instB); } return false; }
getParentInstance
对getParent的export封装:
export function getParentInstance(inst) { return getParent(inst); }
traverseTwoPhase
对inst及其以上的树执行冒泡捕获的操作,执行fn。类似事件的冒泡捕获
export function traverseTwoPhase(inst, fn, arg) { const path = []; //将inst的父节点入栈,数组最后的为最远的祖先 while (inst) { path.push(inst); inst = getParent(inst); } let i; //从最远的祖先开始向inst节点捕获执行fn for (i = path.length; i-- > 0; ) { fn(path[i], 'captured', arg); } //从inst节点开始向最远的祖先节点冒泡执行fn for (i = 0; i < path.length; i++) { fn(path[i], 'bubbled', arg); } }
traverseEnterLeave
当关注点从from节点移出然后移入to节点的时候,在from执行执行类似移入移出的操作,from节点
export function traverseEnterLeave(from, to, fn, argFrom, argTo) { const common = from && to ? getLowestCommonAncestor(from, to) : null; const pathFrom = []; while (true) { if (!from) { break; } if (from === common) { break; } const alternate = from.alternate; if (alternate !== null && alternate === common) { break; } pathFrom.push(from); from = getParent(from); } const pathTo = []; while (true) { if (!to) { break; } if (to === common) { break; } const alternate = to.alternate; if (alternate !== null && alternate === common) { break; } pathTo.push(to); to = getParent(to); } //以上代码将from节点到from与to节点的最近公共祖先节点(不包括公共祖先节点)push到pathFrom数组 //以上代码将to节点到from与to节点的最近公共祖先节点(不包括公共祖先节点)push到pathTo数组 // 以下代码用于对pathFrom冒泡,执行fn for (let i = 0; i < pathFrom.length; i++) { fn(pathFrom[i], 'bubbled', argFrom); } // 以下代码用于对pathTo捕获,执行fn for (let i = pathTo.length; i-- > 0; ) { fn(pathTo[i], 'captured', argTo); } }
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 算法与数据结构之递归算法
- Python 数据结构与算法 —— 初识算法
- js实现数据结构及算法之排序算法
- 数据结构和算法面试题系列—递归算法总结
- 数据结构和算法面试题系列—随机算法总结
- 数据结构与算法——常用排序算法及其Java实现
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
创业之初你不可不知的融资知识
桂曙光 / 机械工业出版社 / 2010-6-1 / 48.00元
从零到精通 成功融资必读书 像小说一样好看的趣味融资书 手把手教你找到VC拿到钱 本书以创业者寻找风险投资的逻辑顺序为主线,运用理论分析和实例剖析相结合的手法,将简洁、通俗的语言与丰富的图表工具相结合,辅以中肯的建议,同时运用大量鲜活的、有代表性的成败案例,为读者解读创业之初企业有效成功融资的途径和方法,帮助你的企业开创新的辉煌。一起来看看 《创业之初你不可不知的融资知识》 这本书的介绍吧!