带头结点的双向链表【数据结构】

带头结点的双向循环链表:

构成:

typedef struct DCList{
	struct DCList* _pNext;
	struct DCList* _pPre;
	DataType _data;
}Node, *pNode;
创建新节点:

pNode DCLBuyNode(DataType data)
{
	pNode NewNode = (pNode)malloc(sizeof(Node));
	if (NULL == NewNode)
	{
		return NULL;
	}
	NewNode->_data = data;
	NewNode->_pNext = NULL;
	NewNode->_pPre = NULL;
	return NewNode;
}
初始化:

void InitDCList(pNode* ppHead)
{
	assert(ppHead);
	*ppHead = DCLBuyNode(0);	//头结点放一个无意义值
	if (NULL == *ppHead)
	{
		return;
	}
	(*ppHead)->_pNext = *ppHead;
	(*ppHead)->_pPre = *ppHead;
}
尾插:
void DCLPushBack(pNode pHead, DataType data)
{
	pNode pNewNode = NULL;
	pNode pTailNode = NULL;
	assert(pHead);
	pNewNode  = DCLBuyNode(data);
	if (NULL == pNewNode)
	{
		return;
	}
	pTailNode = pHead->_pPre;			//找到最后一个节点
	pTailNode->_pNext = pNewNode;			//链接最后一个节点和新节点
	pNewNode->_pPre = pTailNode;			//链接新节点
	pNewNode->_pNext = pHead;
	pHead->_pPre = pNewNode;			//链接头结点和新节点
}
尾删:

void DCLPopBack(pNode pHead)
{
	if (NULL == pHead)
	{
		return;
	}
	pNode pPreTail = pHead->_pPre->_pPre;
	free(pPreTail->_pNext);
	pPreTail->_pNext = pHead;
	pHead->_pPre = pPreTail;
}

头插:

void DCLPushFront(pNode pHead, DataType data)
{
	pNode pNewNode = NULL;
	assert(pHead);
	pNewNode = DCLBuyNode(data);
	if (NULL == pNewNode)
	{
		return;
	}
	pNewNode->_pNext = pHead->_pNext;	//链接新节点和头结点的下一个节点
	pHead->_pNext->_pPre = pNewNode;	
	pHead->_pNext = pNewNode;		
	pNewNode->_pPre = pHead;		
}
头删:
void DCLPopFront(pNode pHead)
{
	pNode pDel = NULL;
	if (pHead == pHead->_pNext)		//只有头结点
	{
		return;
	}
	pDel = pHead->_pNext;
	pDel->_pNext->_pPre = pHead;
	pHead->_pNext = pDel->_pNext;
	free(pDel);
}
任意插:

void DCLInsert(pNode pos, DataType data)	//插在pos前
{
	assert(pos);
	pNode pNewNode = DCLBuyNode(data);
	if (NULL == pNewNode)
	{
		return;
	}
	//注意插入顺序	
	pNewNode->_pNext = pos;						//新节点的下一个指向pos
	pos->_pPre->_pNext = pNewNode;				//pos前一个节点的下一个指向新节点
	pNewNode->_pPre = pos->_pPre;				//新节点的前一个指向pos的前一个
	pos->_pPre = pNewNode;						//pos的前一个指向pos
}
任意删:

void DCLErase(pNode pos)
{
	assert(pos);
	pos->_pPre->_pNext = pos->_pNext;
	pos->_pNext->_pPre = pos->_pPre;
	free(pos);
}
查找:

pNode DCLFind(pNode pHead, DataType data)
{
	pNode pCur = NULL;
	assert(pHead);
	pCur = pHead->_pNext;
	while (pHead != pCur)
	{
		if (data == pCur->_data)
		{
			return pCur;
		}
		pCur = pCur->_pNext;
	}
	return NULL;
}
销毁:

void DestroyDCList(pNode *ppHead)
{
	pNode pDel = NULL;		
	pNode pPreDel = NULL;
	assert(ppHead);
	pDel = (*ppHead)->_pNext;
	while (*ppHead != pDel)
	{
		pPreDel = pDel;
		pDel = pDel->_pNext;
		free(pPreDel);
	}
	free(pDel);				//释放头结点
	(*ppHead) = NULL;
}









  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值