双向链表的使用(数据结构)
一、双向链表的概述
双向链表也是链表的一种,它每个数据结点中都有两个结点,分别指向其直接前驱和直接后继。所以我们从双向链表的任意一个结点开始都可以很方便的访问其前驱元素和后继元素
二、双向链表的存储结构
三、双向与单向链表区别
1.单向链表,查找的方向只能是一个方向,而双向链表可以向前或者向后查找。.
2.单向链表不能自我删除,需要靠辅助节点
3.双向链表,则可以自我删除,所以前面我们单链表删除时节点,总是找到 temp,temp 是待删除节点的前一个节点
四、代码测试
struct Node
{
int iData;
struct Node *pPre;
struct Node *pNext;
};
struct Node *g_pHead = NULL;
struct Node *g_pEnd = NULL;
int g_CountNode = 0;
1.头添加法和尾添加法
原理图片展示
头添加
新节点的下一个指向头结点 头结点的前一个指向新节点 新节点成为新的头结点
尾添加
尾结点的下一个指向新节点 新节点的前一个指向尾结点 新节点成为尾结点(上面图片中写错了一个)
void AddNodeByHead(int iData)
{
if(0 > g_CountNode)
{
printf("Node Number is error !!!\n");
return;
}
struct Node *pTemp = (struct Node *)malloc(sizeof(struct Node));
if(NULL == pTemp)
{
printf("malloc is error !!!\n");
return;
}
else
{
pTemp->iData = iData;
pTemp->pPre = NULL;
pTemp->pNext = NULL;
if(NULL == g_pHead)
{
g_pHead = pTemp;
g_pEnd = pTemp;
}
else
{
pTemp->pNext = g_pHead;
g_pHead->pPre = pTemp;
g_pHead = pTemp;
}
}
g_CountNode++;
}
void AddNodeByTail(int iData)
{
if(0 > g_CountNode)
{
printf(" Node Number is error !!!\n");
return;
}
else
{
struct Node *pTemp = (struct Node *)malloc(sizeof(struct Node));
if(NULL == pTemp)
{
printf("malloc is error !!!\n");
return;
}
pTemp->iData = iData;
pTemp->pPre = NULL;
pTemp->pNext = NULL;
if(NULL == g_pHead)
{
g_pHead = pTemp;
g_pEnd = pTemp;
}
else
{
g_pEnd->pNext = pTemp;
pTemp->pPre = g_pEnd;
g_pEnd = pTemp;
}
}
g_CountNode++;
}
2.正向和反向打印链表
双链表的打印和单链表的打印大同小异,主要差异在于单向链表只能从头向尾遍历链表,而双向链表既可以从头到尾也可以从尾到头,在实际的运用中大大的提升了数据处理效率。
图片原理展示
void PrintListByForward()
{
if(NULL == g_pHead )
{
printf("g_pHead IS EMPTY !!!\n");
return ;
}
struct Node *pTemp = g_pHead;
printf("current node is %d\n",g_CountNode);
while(NULL != pTemp)
{
printf("%d ",pTemp->iData);
pTemp=pTemp->pNext;
}
printf("\n");
}
void PrintListByBack()
{
if(NULL == g_pHead)
{
printf("g_pHead is Empty!!!\n");
return ;
}
struct Node *pTemp = g_pEnd;
printf("Node Number IS %d\n",g_CountNode);
while(NULL != pTemp)
{
printf("%d ",pTemp->iData);
pTemp = pTemp->pNext;
}
printf("\n");
}
3.链表的释放
void FreeList()
{
if(NULL == g_pHead)
{
return;
}
struct Node *pTemp = g_pHead;
while(NULL != pTemp)
{
struct Node *pt = pTemp;
pTemp = pTemp->pNext;
free(pt);
}
g_pHead = NULL;
g_pEnd = NULL;
g_CountNode = 0;
}
4.通过指定下标和数据查找结点
struct Node *FindNodeByIndex(int iIndex)
{
if(NULL == g_pHead || iIndex < 0 || iIndex > g_CountNode)
{
printf("Node Index is error !!!\n");
return NULL;
}
int Index = 0;
struct Node *pTemp = g_pHead;
while(pTemp != NULL)
{
if(Index == iIndex)
{
break;
}
pTemp = pTemp->pNext;
Index++;
}
return pTemp;
}
struct Node *FindNodeByData(int iValue)
{
if(NULL == g_pHead)
{
printf("g_pHead is Empty!!!\n");
return NULL;
}
struct Node *pTemp = g_pHead;
while(NULL != pTemp)
{
if(pTemp->iData == iValue)
{
return pTemp;
}
pTemp = pTemp->pNext;
}
}
5.通过指定下标和数据对结点进行数据修改
/通过指定下标修改数据
void ModiNodeByIndex(int iIndex ,int iValue)
{
struct Node *Res = FindNodeByIndex(iIndex);
if(NULL == Res)
{
printf("Find Node is failed!!!\n");
return;
}
else
{
Res->iData = iValue;
}
}
void ModiNodeByData(int iData,int iValue)
{
struct Node *Res = FindNodeByData(iData);
if(NULL == Res)
{
printf("Find Node is failed!!!\n");
return;
}
else
{
Res->iData = iValue;
}
}
6.通过指定下标和数据对结点进行数据删除
void DeleteNode(struct Node *pTemp)
{
if(NULL == g_pHead)
{
printf("Node is Empty!!!\n");
return;
}
if(pTemp == g_pHead )
{
if(pTemp == g_pEnd)
{
free(pTemp);
g_pHead = NULL;
g_pEnd = NULL;
}
else
{
pTemp = pTemp->pNext;
free(pTemp->pPre);
pTemp->pPre = NULL;
}
}
else if(pTemp == g_pEnd)
{
pTemp = pTemp->pPre;
free(pTemp->pNext);
pTemp->pNext = NULL;
}
else
{
pTemp->pPre->pNext = pTemp->pNext;
pTemp->pNext = pTemp->pPre;
free(pTemp);
}
g_CountNode--;
}
void DeleteNodeByIndex(int iIndex)
{
struct Node * Res = FindNodeByIndex(iIndex);
if(Res != NULL)
{
DeleteNode(Res);
}
}
void DeleteNodeByData(int iData)
{
struct Node *Res = FindNodeByData(iData);
while(Res != NULL)
{
DeleteNode(Res);
}
}
7.指定下标或数据结点前添加数据(采样头添加法)
void AddNodeByIndex(int iData,int Count,int iIndex)
{
if(Count == 0 || iIndex < 0 || iIndex > g_CountNode)
{
printf("Node param is error!!!\n");
return;
}
if(iIndex == 0)
{
for(int i = 0 ; i< Count ;i++)
{
AddNodeByHead(iData);
}
}
else if(iIndex == g_CountNode)
{
for(int i = 0; i < Count ;i++)
{
AddNodeByTail(iData);
}
}
else
{
struct Node *pt = g_pHead;
for(int i = 0 ; i < iIndex ;i++)
{
pt = pt->pNext;
}
for(int i = 1 ;i <= Count ;i++)
{
struct Node *pTemp = (struct Node *)malloc(sizeof(struct Node));
if(NULL == pTemp)
{
printf("malloc failed!!!\n");
return;
}
pTemp->iData = iData;
pTemp->pNext = NULL;
pTemp->pPre = NULL;
pt->pPre->pNext = pTemp;
pTemp->pPre = pt->pPre;
pTemp->pNext = pt;
pTemp->pPre = pTemp;
}
g_CountNode+=Count;
}
}
void AddNodeByData(int iData,int iValue)
{
if(NULL == g_pHead)
{
printf(" Node is Empty!!!\n");
return ;
}
struct Node *pTemp = g_pHead;
while(NULL != pTemp)
{
if(pTemp->iData == iData)
{
break;
}
pTemp = pTemp->pNext;
}
if(pTemp != NULL)
{
if(pTemp == g_pHead)
{
AddNodeByHead(iValue);
}
else
{
struct Node *pt = (struct Node *)malloc(sizeof(struct Node));
if(NULL == pt)
{
printf("malloc failed!!!\n");
return;
}
pt->iData = iValue;
pt->pPre = NULL;
pt->pNext = NULL;
pTemp->pPre->pNext = pt;
pt->pPre = pTemp->pPre;
pt->pNext = pTemp;
pTemp->pPre = pt;
g_CountNode++;
}
}
}
8.整体代码测试
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int iData;
struct Node *pPre;
struct Node *pNext;
};
struct Node *g_pHead = NULL;
struct Node *g_pEnd = NULL;
int g_CountNode = 0;
void AddNodeByHead(int iData);
void AddNodeByTail(int iData);
struct Node *FindNodeByIndex(int iIndex);
struct Node *FindNodeByData(int iValue);
void ModiNodeByIndex(int iIndex ,int iValue);
void ModiNodeByData(int iData ,int iValue);
void AddNodeByIndex(int iData,int Count,int iIndex);
void AddNodeByData(int iData,int iValue);
void FreeList();
void PrintListByForward();
void PrintListByBack();
void AddNodeByHead(int iData)
{
if(0 > g_CountNode)
{
printf("Node Number is error !!!\n");
return;
}
struct Node *pTemp = (struct Node *)malloc(sizeof(struct Node));
if(NULL == pTemp)
{
printf("malloc is error !!!\n");
return;
}
else
{
pTemp->iData = iData;
pTemp->pPre = NULL;
pTemp->pNext = NULL;
if(NULL == g_pHead)
{
g_pHead = pTemp;
g_pEnd = pTemp;
}
else
{
pTemp->pNext = g_pHead;
g_pHead->pPre = pTemp;
g_pHead = pTemp;
}
}
g_CountNode++;
}
void AddNodeByTail(int iData)
{
if(0 > g_CountNode)
{
printf(" Node Number is error !!!\n");
return;
}
else
{
struct Node *pTemp = (struct Node *)malloc(sizeof(struct Node));
if(NULL == pTemp)
{
printf("malloc is error !!!\n");
return;
}
pTemp->iData = iData;
pTemp->pPre = NULL;
pTemp->pNext = NULL;
if(NULL == g_pHead)
{
g_pHead = pTemp;
g_pEnd = pTemp;
}
else
{
g_pEnd->pNext = pTemp;
pTemp->pPre = g_pEnd;
g_pEnd = pTemp;
}
}
g_CountNode++;
}
void AddNodeByIndex(int iData,int Count,int iIndex)
{
if(Count == 0 || iIndex < 0 || iIndex > g_CountNode)
{
printf("Node param is error!!!\n");
return;
}
if(iIndex == 0)
{
for(int i = 0 ; i< Count ;i++)
{
AddNodeByHead(iData);
}
}
else if(iIndex == g_CountNode)
{
for(int i = 0; i < Count ;i++)
{
AddNodeByTail(iData);
}
}
else
{
struct Node *pt = g_pHead;
for(int i = 0 ; i < iIndex ;i++)
{
pt = pt->pNext;
}
for(int i = 1 ;i <= Count ;i++)
{
struct Node *pTemp = (struct Node *)malloc(sizeof(struct Node));
if(NULL == pTemp)
{
printf("malloc failed!!!\n");
return;
}
pTemp->iData = iData;
pTemp->pNext = NULL;
pTemp->pPre = NULL;
pt->pPre->pNext = pTemp;
pTemp->pPre = pt->pPre;
pTemp->pNext = pt;
pTemp->pPre = pTemp;
}
g_CountNode+=Count;
}
}
void AddNodeByData(int iData,int iValue)
{
if(NULL == g_pHead)
{
printf(" Node is Empty!!!\n");
return ;
}
struct Node *pTemp = g_pHead;
while(NULL != pTemp)
{
if(pTemp->iData == iData)
{
break;
}
pTemp = pTemp->pNext;
}
if(pTemp != NULL)
{
if(pTemp == g_pHead)
{
AddNodeByHead(iValue);
}
else
{
struct Node *pt = (struct Node *)malloc(sizeof(struct Node));
if(NULL == pt)
{
printf("malloc failed!!!\n");
return;
}
pt->iData = iValue;
pt->pPre = NULL;
pt->pNext = NULL;
pTemp->pPre->pNext = pt;
pt->pPre = pTemp->pPre;
pt->pNext = pTemp;
pTemp->pPre = pt;
g_CountNode++;
}
}
}
struct Node *FindNodeByIndex(int iIndex)
{
if(NULL == g_pHead || iIndex < 0 || iIndex > g_CountNode)
{
printf("Node Index is error !!!\n");
return NULL;
}
int Index = 0;
struct Node *pTemp = g_pHead;
while(pTemp != NULL)
{
if(Index == iIndex)
{
break;
}
pTemp = pTemp->pNext;
Index++;
}
return pTemp;
}
struct Node *FindNodeByData(int iValue)
{
if(NULL == g_pHead)
{
printf("g_pHead is Empty!!!\n");
return NULL;
}
struct Node *pTemp = g_pHead;
while(NULL != pTemp)
{
if(pTemp->iData == iValue)
{
return pTemp;
}
pTemp = pTemp->pNext;
}
}
void ModiNodeByIndex(int iIndex ,int iValue)
{
struct Node *Res = FindNodeByIndex(iIndex);
if(NULL == Res)
{
printf("Find Node is failed!!!\n");
return;
}
else
{
Res->iData = iValue;
}
}
void ModiNodeByData(int iData,int iValue)
{
struct Node *Res = FindNodeByData(iData);
if(NULL == Res)
{
printf("Find Node is failed!!!\n");
return;
}
else
{
Res->iData = iValue;
}
}
void DeleteNode(struct Node *pTemp)
{
if(NULL == g_pHead)
{
printf("Node is Empty!!!\n");
return;
}
if(pTemp == g_pHead )
{
if(pTemp == g_pEnd)
{
free(pTemp);
g_pHead = NULL;
g_pEnd = NULL;
}
else
{
pTemp = pTemp->pNext;
free(pTemp->pPre);
pTemp->pPre = NULL;
}
}
else if(pTemp == g_pEnd)
{
pTemp = pTemp->pPre;
free(pTemp->pNext);
pTemp->pNext = NULL;
}
else
{
pTemp->pPre->pNext = pTemp->pNext;
pTemp->pNext = pTemp->pPre;
free(pTemp);
}
g_CountNode--;
}
void DeleteNodeByIndex(int iIndex)
{
struct Node * Res = FindNodeByIndex(iIndex);
if(Res != NULL)
{
DeleteNode(Res);
}
}
void DeleteNodeByData(int iData)
{
struct Node *Res = FindNodeByData(iData);
while(Res != NULL)
{
DeleteNode(Res);
}
}
void PrintListByForward()
{
if(NULL == g_pHead )
{
printf("g_pHead IS EMPTY !!!\n");
return ;
}
struct Node *pTemp = g_pHead;
printf("current node is %d\n",g_CountNode);
while(NULL != pTemp)
{
printf("%d ",pTemp->iData);
pTemp=pTemp->pNext;
}
printf("\n");
}
void PrintListByBack()
{
if(NULL == g_pHead)
{
printf("g_pHead is Empty!!!\n");
return ;
}
struct Node *pTemp = g_pEnd;
printf("Node Number IS %d\n",g_CountNode);
while(NULL != pTemp)
{
printf("%d ",pTemp->iData);
pTemp = pTemp->pNext;
}
printf("\n");
}
void FreeList()
{
if(NULL == g_pHead)
{
return;
}
struct Node *pTemp = g_pHead;
while(NULL != pTemp)
{
struct Node *pt = pTemp;
pTemp = pTemp->pNext;
free(pt);
}
g_pHead = NULL;
g_pEnd = NULL;
g_CountNode = 0;
}
int main(void)
{
AddNodeByHead(1);
AddNodeByHead(2);
AddNodeByHead(3);
AddNodeByTail(4);
AddNodeByTail(5);
AddNodeByTail(6);
PrintListByForward();
printf("修改后数据:\n");
ModiNodeByData(2,7);
ModiNodeByData(6,70);
ModiNodeByIndex(3,9);
ModiNodeByIndex(4,19);
PrintListByForward();
DeleteNodeByIndex(3);
DeleteNodeByIndex(2);
printf("删除后数据:\n");
PrintListByForward();
return 0;
}
运行结果
|