//=========================================================================== // Recursive procedure to iterate all children of a packed linked list node. // Parameters -------------------------------------------------------------- // PPLLIST plist : packed linked list // PPLLNODE pnode : node address // PITERPROCDATA pipd : iteration data structure // ULONG ulMaxIterations: max. number of iterations, use 0 for unlimited iterations // 20091026 AB added to prevent excessive // data loading into the listboxes // Return value ------------------------------------------------------------ // ULONG count of processed items or 0 in case of broken iteration //=========================================================================== static ULONG iterateNode(PPLLIST pList, PPLLNODE pNode, PITERPROCDATA pIpd, ULONG ulMaxIterations) { LONG tot, ci, hitem; PPLLITEM pi; if ( ulMaxIterations == 0 ) { // set to useful limit ulMaxIterations = LONG_MAX; } // check if according to the current flags must process the node now for ( tot = 0, hitem = pNode->offFirst, pi = FIRSTITEM(pList, pNode); hitem; hitem = pi->offNext, pi = NEXTITEM(pList, pi), tot++ ) { // if the current item is a node if ( pi->isNode ) { // if the item must be processed before its descendants if ( pIpd->iterData.flag & PPLLITER_NODEPRE ) { pIpd->iterData.hItem = (HNDPLLITEM)((PBYTE)pi - (PBYTE)pList); pIpd->iterData.pData = (PVOID)((PPLLNODE)pi + 1); pIpd->iterData.context = PPLLITER_NODEPRE; if ( !pIpd->pFunc(&pIpd->iterData) ) return 0; } /* endif */ // process the descendants pIpd->iterData.nestLevel++; if ( !( ci = iterateNode(pList, (PPLLNODE)pi, pIpd, ulMaxIterations )) ) return 0; tot += ci; pIpd->iterData.nestLevel--; // if the item must be processed after its descendants if ( pIpd->iterData.flag & PPLLITER_NODEPOST ) { pIpd->iterData.hItem = (HNDPLLITEM)((PBYTE)pi - (PBYTE)pList); pIpd->iterData.pData = (PVOID)((PPLLNODE)pi + 1); pIpd->iterData.context = PPLLITER_NODEPOST; if ( !pIpd->pFunc(&pIpd->iterData) ) return 0; } /* endif */ // end (return) if max. number of iterations is reached if ( tot >= ulMaxIterations ) { TRACE1("break after %d iterations (ulMaxIterations)", tot); return tot; } } else { pIpd->iterData.hItem = (HNDPLLITEM)((PBYTE)pi - (PBYTE)pList); pIpd->iterData.pData = (PVOID)((PPLLITEM)pi + 1); pIpd->iterData.context = PPLLITER_NORECUR; if ( !pIpd->pFunc(&pIpd->iterData) ) return 0; // end (return) if max. number of iterations is reached if ( tot >= ulMaxIterations ) { TRACE1("break after %d iterations (ulMaxIterations)", tot); return tot; } } /* endif */ } /* endfor */ return tot; }
/** @return the next smallest number */ int next() { TreeNode *top = minStack.top(); minStack.pop(); iterateNode(top->right); return top->val; }
ULONG PLListIterate(PPLLIST pList, HNDPLLITEM hNode, ULONG flag, PPLLISTITERATE pFunc, PVOID pParm, ULONG ulMaxIterations) { PPLLNODE pnode, pn; ITERPROCDATA ipd; ULONG startLevel; ULONG citems = 0; PPLLITEM pi; //TRACE4("pList=%d, hNode=%d, flag=%d, pFunc=0x%0X", pList, hNode, flag, pFunc); //TRACE2("pParm=%d, ulMaxIterations=%d", pParm, ulMaxIterations); if ( ulMaxIterations == 0 ) { // set to useful limit ulMaxIterations = LONG_MAX; } if ( !pList ) return 0; pnode = pn = PNODEFROMHITEM(pList, hNode); ipd.pFunc = pFunc; ipd.iterData.pParm = pParm; // starting nesting level for ( ipd.iterData.nestLevel = 0; (ULONG)pn > (ULONG)pList; ipd.iterData.nestLevel++ ) { pn = PNODEFROMHITEM(pList, pn->offParent); } if ( flag ) { // recursive call // in neither PPLLITER_NODEPRE nor PPLLITER_NODEPOST were specified // assume PPLLITER_NODEPRE (to process nodes before theirs descendants) if ( !(flag & (PPLLITER_NODEPRE | PPLLITER_NODEPOST)) ) flag |= PPLLITER_NODEPRE; ipd.iterData.flag = flag; // if the starting node is not the root and must be included if ( hNode && (flag & PPLLITER_INCLNODE) ) { ++citems; if ( flag & PPLLITER_NODEPRE ) { ipd.iterData.hItem = hNode; ipd.iterData.pData = ITEMDATA(pnode); // signal the callback procedure in which context it is called // (i.e. on the starting node and before the node descendants ipd.iterData.context = (PPLLITER_INCLNODE | PPLLITER_NODEPRE); if ( !pFunc(&ipd.iterData) ) return 0; } /* endif */ // end (return) if max. number of iterations is reached if ( citems >= ulMaxIterations ) { TRACE1("break after %d iterations (ulMaxIterations)", citems); return citems; } } /* endif */ // iterate through the node descendandts citems = iterateNode(pList, pnode, &ipd, ulMaxIterations); // check if the callback procedure must be called on the starting node if ( bitMaskMatch(flag, (PPLLITER_INCLNODE | PPLLITER_NODEPOST)) ) { ipd.iterData.hItem = hNode; ipd.iterData.pData = ITEMDATA(pnode); ipd.iterData.context = (PPLLITER_INCLNODE | PPLLITER_NODEPOST); if ( !pFunc(&ipd.iterData) ) return 0; } /* endif */ } else { // non recursive loop ipd.iterData.context = PPLLITER_NORECUR; //TRACE3("pList addr=0x%X, cbTot=%d, count=%d", pList, pList->cbTot, pList->count); //TRACE2("cbTot=0x%X, count=0x%X", pList->cbTot, pList->count); for ( citems = 0, pi = FIRSTITEM(pList, pnode); citems < pnode->count; ++citems ) { //TRACE2("citems=%d, pnode->count=%d", citems, pnode->count ); ipd.iterData.hItem = (HNDPLLITEM)((PBYTE)pi - (PBYTE)pList); ipd.iterData.pData = ITEMDATA(pi); if ( !pFunc(&ipd.iterData) ) return 0; pi = NEXTITEM(pList, pi); // end (return) if max. number of iterations is reached if ( citems >= ulMaxIterations ) { TRACE1("break after %d iterations (ulMaxIterations)", citems); return citems; } } /* endfor */ } /* endif */ return citems; }
BSTIterator(TreeNode *root) { // push the left candidates on stack iterateNode(root); }