C 双向链表简单操作

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

/* 双链表节点定义 */
typedef struct tagStDulNode
{
	int iData;
	struct tagStDulNode *pstPrior; /* 指向前驱节点 */
	struct tagStDulNode *pstNext;  /* 指向后继节点 */
}StDulNode;

/* 创建具有iNum个节点的双向链表 */
StDulNode *Create(int iNum);

/* 正序遍历 */
void traverse1(StDulNode *pstHead);

/* 反序遍历 */
void traverse2(StDulNode *pstHead);

/* 删除数据为iData的节点,返回头 删除节点的下一个节点的位置 */
StDulNode *DeleteNode(StDulNode *pstHead, int iData);

/* 在数据位iData的节点前插入一个新的节点,返回新节点的位置 */
StDulNode *InsertNode(StDulNode *pstHead, int iData);

StDulNode *Create(int iNum)
{
	StDulNode *pstHead = NULL;
	StDulNode *pstP = NULL;
	StDulNode *pstQ = NULL;
	int iCount = 0;

	assert(iNum > 0);
	pstHead = (StDulNode *)malloc(sizeof(StDulNode)); /* 分配第一个节点 */
	assert(NULL != pstHead);

	/* 初始化第一个节点 */
    pstHead->iData = iCount;
    pstHead->pstNext = pstHead;  /* 指向其自身 */
    pstHead->pstPrior = pstHead; /* 指向其自身 */

    pstQ = pstHead;

    for (iCount = 1; iCount < iNum; iCount ++)
    {
    	pstP = (StDulNode *)malloc(sizeof(StDulNode)); /* 分配下一个节点 */
    	assert(NULL != pstP);

    	/* 初始化下一个节点  */
    	pstP->iData = iCount;

    	pstQ->pstNext = pstP;
    	pstP->pstNext = pstHead; /* 新插入节点的Next指向头节点 */
    	pstP->pstPrior = pstQ;   /* 新插入节点的Prior指向上一个节点 */

    	pstQ = pstP;    /* pstQ指向新插入的节点 */
    	pstHead->pstPrior = pstP; /* 头节点指向最后一个插入的值 */
    	pstP = NULL;
    }

    return pstHead;
}

void traverse1(StDulNode *pstHead)
{
    StDulNode *pstP = NULL;

	assert(NULL != pstHead);
	printf("%d\n", pstHead->iData); /* 头节点 */
	pstP = pstHead->pstNext;
	while (pstHead != pstP)
	{
		printf("%d\n", pstP->iData);
		pstP = pstP->pstNext;
	}

	return ;
}

void traverse2(StDulNode *pstHead)
{
    StDulNode *pstP = NULL;

	assert(NULL != pstHead);
	pstP = pstHead->pstPrior;
	while (pstHead != pstP)
	{
		printf("%d\n", pstP->iData);
		pstP = pstP->pstPrior;
	}
	printf("%d\n", pstHead->iData); /* 头节点 */

	return ;
}

StDulNode *DeleteNode(StDulNode *pstHead, int iData)
{
	StDulNode *pstP = NULL;
	StDulNode *pstQ = NULL;

	assert(pstHead != NULL);
	if (iData == pstHead->iData) /* 如果要删除的节点为第一节点 */
	{
		pstP = pstHead;
	}
	else /* 寻找要删除的节点,用pstP指向要删除的节点 */
	{
		pstP = pstHead->pstNext;
		while((iData != pstP->iData) && (pstP != pstHead))
		{
			pstP = pstP->pstNext;
		}

		if (pstP == pstHead) /* 没有找到要删除的节点 */
		{
			printf("No Node find. %d\n", iData);

			return pstHead;
		}
	}

	pstQ = pstP->pstNext;
	pstP->pstPrior->pstNext = pstQ;
	pstQ->pstPrior = pstP->pstPrior;

	printf("Delete %d\n", pstP->iData);
	free(pstP);
	pstP = NULL;

	return pstQ;
}

StDulNode *InsertNode(StDulNode *pstHead, int iData)
{
	StDulNode *pstP = NULL;
	StDulNode *pstTmp = NULL;

	assert(NULL != pstHead);
	/* 找到要插入节点的位置 */
	if (iData == pstHead->iData)
	{
		pstP = pstHead;
	}
	else
	{
		pstP= pstHead->pstNext;
		while ((iData != pstP->iData) && (pstP != pstHead))
		{
			pstP = pstP->pstNext;
		}

		if (pstP == pstHead)
		{
			printf("NO NODE FOUNED. %d\n", iData);
			return pstHead;
		}
	}

	/* 分配待插入节点并初始化 */
	pstTmp = (StDulNode *)malloc(sizeof(StDulNode));
	assert(NULL != pstTmp);
	pstTmp->iData = 11;
	pstTmp->pstNext = pstTmp;
	pstTmp->pstPrior = pstTmp;

	/* 插入节点到链表中 */
	pstP->pstPrior->pstNext = pstTmp;
	pstTmp->pstPrior = pstP->pstPrior;
	pstTmp->pstNext = pstP;
	pstP->pstPrior = pstTmp;

	return pstTmp;
}

int main(int argc, char **argv)
{
	StDulNode *pstDulNode = NULL;
	pstDulNode = Create(10); /* 创建10个节点 */

	pstDulNode = InsertNode(pstDulNode, 9);
	traverse2(pstDulNode);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值