双向链表的基本操作

双向链表的基本操作:添加、删除、查找、打印。后续会加上双向链表的逆置。

#include "pub.h"

/***********************************************
Function: 
	DllList_Init  双向链表的初始化函数
	llList_Add	  双向链表的添加节点函数
	DllList_Del	  双向链表的删除节点函数
	DllList_Find  双向链表的查找节点函数
	DllList_Adver 双向链表的反转
	DllList_Print 双向链表的打印所有节点函数
 Discrip: No
  Author: yangjian 
    Date: 2013/11/30
***********************************************/

/*双向链表节点定义*/
typedef struct DLL_NODE_INFO
{
	DLL_NODE_INFO *pDllNodeNext;	
	DLL_NODE_INFO *pDllNodePre;
	int			   value;	/*这里用int 类型存储节点类容*/
}DLL_NODE;

/*链表头节点定义*/
typedef struct DLL_LIST_INFO
{
	DLL_NODE *pNext;
	DLL_NODE *pPre;
	ULONG	  ulCount;	/*链表节点计数*/		  
}DLL_LIST;


/*双向链表的初始化函数*/
void DllList_Init(DLL_LIST *pHead)
{
	/*入参合法性判断*/
	if (NULL == pHead)
	{
		return;
	}

	/*链表头初始化*/
	pHead->pNext	= NULL;
	pHead->pPre		= NULL;
	pHead->ulCount  = 0;
	
	return;
}

ULONG DllList_Add(DLL_LIST *pHead, int value)
{
	DLL_NODE *pDllNode = NULL;
	DLL_NODE *pDllNodeTmp = NULL;
	ULONG ulRet = OK;

	/*入参合法性判断*/
	if (NULL == pHead) 
	{
		return FAILED;
	}

	/*为被添加的value 申请DLL_NODE 类型的空间*/
	pDllNode = (DLL_NODE *) malloc(sizeof(DLL_NODE));
	if(NULL == pDllNode)
	{
		return FAILED;
	}

	if (0 == pHead->ulCount)
	{
		/*说明添加的是第一个节点,则要添加到Head 后面*/
		pHead->pNext = pDllNode;
		pDllNode->pDllNodePre  = (DLL_NODE *)pHead;	
	}
	else
	{
		/*遍历双向链表,将DLL_NODE 添加到表尾*/	
		for (pDllNodeTmp = pHead->pNext; ;) //NULL != pDllNodeTmp
		{
			if (NULL == pDllNodeTmp->pDllNodeNext)
			{
				/*说明该节点为尾节点*/
				pDllNodeTmp->pDllNodeNext = pDllNode;
				pDllNode->pDllNodePre  = pDllNodeTmp;	
				
				break;
			}

			pDllNodeTmp = pDllNodeTmp->pDllNodeNext;
		}		
	}
	
	/*DLL_NODE 赋值,并将该节点pDllNodeNext域置为NULL*/
	pDllNode->value		   = value;
	pDllNode->pDllNodeNext = NULL;

	/*链表节点计数加一*/
	pHead->ulCount++;

	return SUCCESS;
}

ULONG DllList_Del(DLL_LIST *pHead, int value)
{
	DLL_NODE *pDllNode = NULL;
	DLL_NODE *pDllNodeTmp = NULL;

	/*入参合法性判断*/
	if (NULL == pHead)
	{	
		return FAILED;
	}

	/*遍历查找存储该值得的节点*/
	pDllNode = pHead->pNext;
	while (NULL != pDllNode)
	{
		pDllNodeTmp = pDllNode->pDllNodeNext;
		if (value == pDllNode->value)
		{
			pDllNode->pDllNodePre->pDllNodeNext = pDllNodeTmp;
			
			/*释放节点,计数减一*/
			free(pDllNode);
			pHead->ulCount--;
		}

		pDllNode = pDllNodeTmp;
	}

	return SUCCESS;
}

void DllList_Adver(DLL_LIST *pHead)
{
	DLL_NODE *pDllNode = NULL;
	DLL_NODE *pDllNodeTmp = NULL;
	DLL_NODE *pDllNodeFirst = NULL;

	if (NULL == pHead)
	{
		return;
	}

	/*只有节点数大于2时才有必要继续*/
	if (1 > pHead->ulCount)
	{
		return;
	}
	
	pDllNodeFirst = pHead->pNext;

	pDllNode = pHead->pNext;
	while (NULL != pDllNode)
	{
		pDllNodeTmp = pDllNode->pDllNodeNext;

		pDllNode->pDllNodeNext = pDllNode->pDllNodePre;
		pDllNode->pDllNodePre  = pDllNodeTmp;

		/*判断是否为尾节点*/
		if (NULL == pDllNodeTmp)
		{
			pHead->pNext = pDllNode;
			pDllNode->pDllNodePre = (DLL_NODE *)pHead;
		}
		else
		{
			pDllNode = pDllNodeTmp;
		}
	}

	/*最后应该把未逆置前的首节点的next域置为空*/
	pDllNodeFirst->pDllNodeNext = NULL;

	return;
}

DLL_NODE *DllList_Find (DLL_LIST *pHead, int value)
{
	DLL_NODE *pDllNode = NULL;
	
	/*入参合法性判断*/
	if (NULL == pHead)
	{	
		return FAILED;
	}
	
	pDllNode = pHead->pNext;
	while (NULL != pDllNode)
	{
		if (value == pDllNode->value)
		{
			return pDllNode;
		}
		
		pDllNode = pDllNode->pDllNodeNext;
	}
	
	return pDllNode;
}

void DllList_Print(DLL_LIST *pHead)
{
	DLL_NODE *pDllNode = NULL;	

	if (NULL == pHead)
	{
		return;
	}

	printf("\r\nThe DLL_LIST value is:");

	pDllNode = pHead->pNext;
	while (NULL != pDllNode)
	{
		printf("  %d", pDllNode->value);
		pDllNode = 	pDllNode->pDllNodeNext;		
	}

	printf("\r\n");

	return;
}

int main(int argc, char *argv[])
{
	int szTest[] = {6, 7, 9, 2, 21, 32};
	int i;
	DLL_NODE *pDllNode = NULL;
	ULONG ulRet = OK;
	DLL_LIST stHead = {0};

	/*链表初始化*/
	DllList_Init(&stHead);

	/*添加节点*/
	for(i = 0; i < 6; i++)
	{
		ulRet = DllList_Add(&stHead, szTest[i]);
		if (SUCCESS != ulRet)
		{
			printf("Add the value szTest[%d]: %d \n", i, szTest[i]);
			return 0;
		}
	}

	/*打印该该链表所有节点*/
	DllList_Print(&stHead);

	/*删除某个节点*/
	DllList_Del(&stHead, 2);

	/*打印该该链表删除后的所有节点*/
	DllList_Print(&stHead);

	/*查找某个节点*/
	pDllNode = DllList_Find(&stHead, 6); 
	if (NULL != pDllNode)
	{
		printf("The value exists in the Dll_list!\n");
	}
	else
	{
		printf("The value does not exist in the Dll_list!\n");
	}
	
	/*双向链表的反转*/
	DllList_Adver(&stHead);
	
    /*打印该该链表的所有节点*/
	DllList_Print(&stHead);
	
	return 0;
}
#include 
   
   
    
    
#include 
    
    
     
     
#include 
     
     
      
       

/*************************************************
			以下为定义的公共设置
*************************************************/

#define ULONG	unsigned long
#define USHORT	unsigned short

#define SUCCESS			1
#define FAILED			0
#define OK				1

     
     
    
    
   
   

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值