EFIAPI GlueGetFirstNode ( IN CONST LIST_ENTRY *List ) { // // ASSERT List not too long // ASSERT (IsNodeInList (List, List)); return List->ForwardLink; }
/** Checks to see if a doubly linked list is empty or not. Checks to see if the doubly linked list is empty. If the linked list contains zero nodes, this function returns TRUE. Otherwise, it returns FALSE. If ListHead is NULL, then ASSERT(). If ListHead was not initialized with InitializeListHead(), then ASSERT(). If PcdMaximumLinkedListLenth is not zero, and the number of nodes in List, including the List node, is greater than or equal to PcdMaximumLinkedListLength, then ASSERT(). @param ListHead A pointer to the head node of a doubly linked list. @retval TRUE The linked list is empty. @retval FALSE The linked list is not empty. **/ BOOLEAN EFIAPI GlueIsListEmpty ( IN CONST LIST_ENTRY *List ) { // // ASSERT List not too long // ASSERT (IsNodeInList (List, List)); return (BOOLEAN)(List->ForwardLink == List); }
EFIAPI GlueGetNextNode ( IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node ) { // // ASSERT List not too long and Node is one of the nodes of List // ASSERT (IsNodeInList (List, Node)); return Node->ForwardLink; }
/** Determines if a node the last node in a doubly linked list. Returns TRUE if Node is the last node in the doubly linked list specified by List. Otherwise, FALSE is returned. List must have been initialized with InitializeListHead(). If List is NULL, then ASSERT(). If Node is NULL, then ASSERT(). If List was not initialized with InitializeListHead(), then ASSERT(). If PcdMaximumLinkedListLenth is not zero, and the number of nodes in List, including the List node, is greater than or equal to PcdMaximumLinkedListLength, then ASSERT(). If Node is not a node in List, then ASSERT(). @param List A pointer to the head node of a doubly linked list. @param Node A pointer to a node in the doubly linked list. @retval TRUE Node is the last node in the linked list. @retval FALSE Node is not the last node in the linked list. **/ BOOLEAN EFIAPI GlueIsNodeAtEnd ( IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node ) { // // ASSERT List not too long and Node is one of the nodes of List // ASSERT (IsNodeInList (List, Node)); return (BOOLEAN)(!IsNull (List, Node) && List->BackLink == Node); }
/** Determines if a node in a doubly linked list is null. Returns FALSE if Node is one of the nodes in the doubly linked list specified by List. Otherwise, TRUE is returned. List must have been initialized with InitializeListHead(). If List is NULL, then ASSERT(). If Node is NULL, then ASSERT(). If List was not initialized with InitializeListHead(), then ASSERT(). If PcdMaximumLinkedListLenth is not zero, and the number of nodes in List, including the List node, is greater than or equal to PcdMaximumLinkedListLength, then ASSERT(). If Node is not a node in List and Node is not equal to List, then ASSERT(). @param List A pointer to the head node of a doubly linked list. @param Node A pointer to a node in the doubly linked list. @retval TRUE Node is one of the nodes in the doubly linked list. @retval FALSE Node is not one of the nodes in the doubly linked list. **/ BOOLEAN EFIAPI GlueIsNull ( IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node ) { // // ASSERT List not too long and Node is one of the nodes of List // ASSERT (IsNodeInList (List, Node)); return (BOOLEAN)(Node == List); }
EFIAPI GlueInsertTailList ( IN OUT LIST_ENTRY *List, IN OUT LIST_ENTRY *Entry ) { // // ASSERT List not too long and Entry is not one of the nodes of List // ASSERT (!IsNodeInList (List, Entry)); Entry->ForwardLink = List; Entry->BackLink = List->BackLink; Entry->BackLink->ForwardLink = Entry; List->BackLink = Entry; return List; }
/** ElemType SubNode(CirLinkList *list, CirLinkListNode *prevNode) 参数 list : 指向一个链表指针,此处传入表头地址 positon : 待删除结点的位置 返回值 返回待删除结点的数据域 功能 删除链表list中prevNode结点之后的指针个指针 */ ElemType SubNode(CirLinkList *list, CirLinkListNode *prevNode) { assert(list != NULL); // 链表不能为空 assert(prevNode != NULL); // 待删除结点的前一个位置不能为空 assert(IsNodeInList(list, prevNode) != -1); // 待删除位置的前一个结点必须在链表中 // 删除pNode的后一个结点 CirLinkListNode *delNode = prevNode->m_next; ElemType delElem = delNode->m_data; prevNode->m_next = delNode->m_next; free(delNode); list->m_length--; // 结点数目减少一个 list->m_head->m_data--; // 头结点的数据域同样存储着结点总数 return delElem; }
EFIAPI GlueSwapListEntries ( IN OUT LIST_ENTRY *FirstEntry, IN OUT LIST_ENTRY *SecondEntry ) { LIST_ENTRY *Ptr; if (FirstEntry == SecondEntry) { return SecondEntry; } // // ASSERT Entry1 and Entry2 are in the same linked list // ASSERT (IsNodeInList (FirstEntry, SecondEntry)); // // Ptr is the node pointed to by FirstEntry->ForwardLink // Ptr = RemoveEntryList (FirstEntry); // // If FirstEntry immediately follows SecondEntry, FirstEntry willl be placed // immediately in front of SecondEntry // if (Ptr->BackLink == SecondEntry) { return InsertTailList (SecondEntry, FirstEntry); } // // Ptr == SecondEntry means SecondEntry immediately follows FirstEntry, // then there are no further steps necessary // if (Ptr == InsertHeadList (SecondEntry, FirstEntry)) { return Ptr; } // // Move SecondEntry to the front of Ptr // RemoveEntryList (SecondEntry); InsertTailList (Ptr, SecondEntry); return SecondEntry; }
/** 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; }