/* get previous item from list */ MemPtr ListPrev ( LinkedList list, /* list handler */ MemPtr item /* list item */ ) { ListNode* node; node = FindPrevNode( list, item ); if ( node != NULL ) return node->data; else return NULL; }
/** ElemType DeleteCurrNode(CirLinkList *list, CirLinkListNode *currNode); 参数 list : 指向一个链表指针,此处传入表头地址 positon : 待删除结点的位置 返回值 返回待删除结点的数据域 功能 删除链表list中prevNode结点之后的指针个指针 */ ElemType DeleteCurrNode(CirLinkList *list, CirLinkListNode *currNode) { assert(list != NULL); // 链表不能为空 assert(currNode != NULL); // 待删除结点的前一个位置不能为空 assert(IsNodeInList(list, currNode) != -1); // 待删除的结点必须在链表中 ElemType delElem = -1; // 待删除结点的数据域 CirLinkListNode *delNode = NULL; // 指向将要删除的结点的指针 // if(list->m_length == 0) // { // // return -1; // } // printf("length = %d\n", list->m_length); if(currNode->m_next != list->m_head) // 如果待删除结点不是最后一个结点 { // 将currNode的后一个结点delNode作为删除结点, delNode = currNode->m_next; currNode->m_next = delNode->m_next; //从链表中删除delNode // 并将delNode的数据域保存到delNode中 delElem = currNode->m_data; // delElem保存currNode的数据域 currNode->m_data = delNode->m_data; // 真正删除的结点其实是currNode下一个结点, 因此用currNode保存下一个结点的数据域 } else // 否则待删除结点是最后一个结点 { // 直接将最后一个结点删除即可, 应该把其前一个结点的指针域赋值为空 delNode = currNode; // 下面应该将currnNode的前一个结点的指针域赋值为空[时间复杂度O(n)] CirLinkListNode *prevNode = FindPrevNode(list, currNode); prevNode->m_next = list->m_head; /// BUG1 最后一个结点的后一个结点 } free(delNode); list->m_length--; // 结点数目减少一个 list->m_head->m_data--; // 头结点的数据域同样存储着结点总数 return delElem; }
void mozInlineSpellWordUtil::BuildSoftText() { // First we have to work backwards from mSoftStart to find a text node // containing a DOM word separator, a non-inline-element // boundary, or the hard start node. That's where we'll start building the // soft string from. nsIDOMNode* node = mSoftBegin.mNode; PRInt32 firstOffsetInNode = 0; PRInt32 checkBeforeOffset = mSoftBegin.mOffset; while (node) { if (ContainsDOMWordSeparator(node, checkBeforeOffset, &firstOffsetInNode)) break; checkBeforeOffset = PR_INT32_MAX; if (IsBreakElement(mCSSView, node)) { // Since FindPrevNode follows tree *preorder*, we're about to traverse // up out of 'node'. Since node induces breaks (e.g., it's a block), // don't bother trying to look outside it, just stop now. break; } node = FindPrevNode(node, mRootNode); } // Now build up the string moving forward through the DOM until we reach // the soft end and *then* see a DOM word separator, a non-inline-element // boundary, or the hard end node. mSoftText.Truncate(); mSoftTextDOMMapping.Clear(); PRBool seenSoftEnd = PR_FALSE; // Leave this outside the loop so large heap string allocations can be reused // across iterations nsAutoString str; while (node) { if (node == mSoftEnd.mNode) { seenSoftEnd = PR_TRUE; } PRBool exit = PR_FALSE; if (IsTextNode(node)) { GetNodeText(node, str); PRInt32 lastOffsetInNode = str.Length(); if (seenSoftEnd) { // check whether we can stop after this for (PRInt32 i = node == mSoftEnd.mNode ? mSoftEnd.mOffset : 0; i < PRInt32(str.Length()); ++i) { if (IsDOMWordSeparator(str.CharAt(i))) { exit = PR_TRUE; // stop at the first separator after the soft end point lastOffsetInNode = i; break; } } } if (firstOffsetInNode < lastOffsetInNode) { PRInt32 len = lastOffsetInNode - firstOffsetInNode; mSoftTextDOMMapping.AppendElement( DOMTextMapping(NodeOffset(node, firstOffsetInNode), mSoftText.Length(), len)); mSoftText.Append(Substring(str, firstOffsetInNode, len)); } firstOffsetInNode = 0; } if (exit) break; CheckLeavingBreakElementClosure closure = { mCSSView, PR_FALSE }; node = FindNextNode(node, mRootNode, CheckLeavingBreakElement, &closure); if (closure.mLeftBreakElement || (node && IsBreakElement(mCSSView, node))) { // We left, or are entering, a break element (e.g., block). Maybe we can // stop now. if (seenSoftEnd) break; // Record the break mSoftText.Append(' '); } } #ifdef DEBUG_SPELLCHECK printf("Got DOM string: %s\n", NS_ConvertUTF16toUTF8(mSoftText).get()); #endif }