双向链表节点结构及操作函数定义与实现

ChatGPT4o 使用 ChatGPT 4o 回答

问题:

分析一下下面这段代码是在做什么? typedef struct DLLIST_NODE_ { struct DLLIST_NODE_ *psPrevNode; struct DLLIST_NODE_ *psNextNode; } DLLIST_NODE;

typedef struct DLLIST_NODE_ *PDLLIST_NODE;

static INLINE bool dllist_is_empty(PDLLIST_NODE psListHead) { return ((psListHead->psPrevNode == psListHead) && (psListHead->psNextNode == psListHead)); }

static INLINE void dllist_replace_head(PDLLIST_NODE psOldHead, PDLLIST_NODE psNewHead) { if (dllist_is_empty(psOldHead)) { psNewHead->psNextNode = psNewHead; psNewHead->psPrevNode = psNewHead; } else { /* Change the neighbouring nodes */ psOldHead->psNextNode->psPrevNode = psNewHead; psOldHead->psPrevNode->psNextNode = psNewHead;

	/* Copy the old data to the new node */
	psNewHead->psNextNode = psOldHead->psNextNode;
	psNewHead->psPrevNode = psOldHead->psPrevNode;

	/* Remove links to the previous list */
	psOldHead->psNextNode = psOldHead;
	psOldHead->psPrevNode = psOldHead;
}

}

回答:

这段代码定义了一个双向链表节点的数据结构,并提供了一些操作双向链表的函数。具体来说,它定义了一个双向链表节点的结构体 DLLIST_NODE,并提供了两个内联函数 dllist_is_emptydllist_replace_head 来操作双向链表。下面是对这段代码的详细分析:

数据结构定义

typedef struct DLLIST_NODE_
{
	struct DLLIST_NODE_	*psPrevNode;
	struct DLLIST_NODE_	*psNextNode;
} DLLIST_NODE;

typedef struct DLLIST_NODE_	*PDLLIST_NODE;
  • DLLIST_NODE 结构体定义了一个双向链表节点,包含两个指针:
    • psPrevNode 指向前一个节点。
    • psNextNode 指向下一个节点。
  • PDLLIST_NODE 是一个指向 DLLIST_NODE 结构体的指针类型。

函数 dllist_is_empty

static INLINE
bool dllist_is_empty(PDLLIST_NODE psListHead)
{
	return ((psListHead->psPrevNode == psListHead)
			&& (psListHead->psNextNode == psListHead));
}
  • 这个函数用于检查一个双向链表是否为空。
  • 它接受一个指向链表头节点的指针 psListHead
  • 如果链表头节点的前一个节点和下一个节点都指向它自己,则链表为空,函数返回 true;否则返回 false

函数 dllist_replace_head

static INLINE
void dllist_replace_head(PDLLIST_NODE psOldHead, PDLLIST_NODE psNewHead)
{
	if (dllist_is_empty(psOldHead))
	{
		psNewHead->psNextNode = psNewHead;
		psNewHead->psPrevNode = psNewHead;
	}
	else
	{
		/* Change the neighbouring nodes */
		psOldHead->psNextNode->psPrevNode = psNewHead;
		psOldHead->psPrevNode->psNextNode = psNewHead;

		/* Copy the old data to the new node */
		psNewHead->psNextNode = psOldHead->psNextNode;
		psNewHead->psPrevNode = psOldHead->psPrevNode;

		/* Remove links to the previous list */
		psOldHead->psNextNode = psOldHead;
		psOldHead->psPrevNode = psOldHead;
	}
}
  • 这个函数用于替换双向链表的头节点。
  • 它接受两个指针参数:psOldHead 是当前的头节点,psNewHead 是新的头节点。
  • 首先,它检查旧的头节点是否为空链表:
    • 如果旧的头节点为空链表,则将新的头节点的前一个节点和下一个节点都指向它自己。
  • 如果旧的头节点不是空链表:
    • 更新旧头节点的前一个节点和下一个节点,使它们指向新的头节点。
    • 将旧头节点的前一个节点和下一个节点的信息复制到新的头节点。
    • 最后,将旧头节点的前一个节点和下一个节点指向它自己,断开旧头节点与链表的连接。

总结

这段代码定义了一个双向链表节点的数据结构,并提供了两个操作函数:

  1. dllist_is_empty 用于检查链表是否为空。
  2. dllist_replace_head 用于替换链表的头节点。

这些函数可以用于管理和操作双向链表的数据结构。