双向链表
定义:在单链表的每个结点里再增加一个指向其直接前驱的指针域prior。这样形成的链表中有两个方向不同的链,称为双向链表。
typedef int ElemType;
typedef struct LNode{
ElemType data;
struct LNode *Prior;
struct LNode *Next;
}NODE, *pNODE;
//创建双向链表
pNODE CreateDbLinkList(void);
//打印链表
void TraverseDbLinkList(pNODE pHead);
//判断链表是否为空
int IsEmptyDbLinkList(pNODE pHead);
//计算链表长度
int GetLengthDbLinkList(pNODE pHead);
//向链表插入节点
int InsertDbLinkList(pNODE pHead, int pos, ElemType data);
//从链表删除节点
int DeleteDbLinkList(pNODE pHead, int pos);
1 创建双向链表
//创建双向链表
pNODE CreateDbLinkList(void)
{
int i,len;
ElemType val;
pNODE pHead=(pNODE)malloc(sizeof(NODE));
pNODE pTail=NULL;
if (pHead==NULL)
{
printf("内存分配失败!\n");
exit(-1);//退出程序
}
pHead->data=0;
pHead->Prior=NULL;
pHead->Next=NULL;
pTail=pHead;//初始化尾指针
printf("请输入想创建的链表的长度!\n");
scanf("%d",&len);
for (i=0; i<len; i++)
{
pNODE pNew=(pNODE)malloc(sizeof(NODE));
printf("请输入第%d个元素的值\n",i+1);
scanf("%d",&val);
pNew->data=val;
pNew->Next=NULL;
pNew->Prior=pTail;
pTail->Next=pNew;
pTail=pNew;
}
return pHead;
}
2 判断链表是否为空
//判断链表是否为空
int IsEmptyDbLinkList(pNODE pHead)
{
return pHead->Next==NULL;
}
3 打印链表
//打印链表
void TraverseDbLinkList(pNODE pHead)
{
if (IsEmptyDbLinkList(pHead))
{
printf("链表为空!\n");
}
else
{
pNODE p=(pNODE)malloc(sizeof(NODE));
p=pHead->Next;
while(p)
{
printf("%d ",p->data);
p=p->Next;
}
printf("\n");
}
}
4 计算链表长度
//获得链表长度
int GetLengthDbLinkList(pNODE pHead)
{
int i=0;//计数
pNODE p=(pNODE)malloc(sizeof(NODE));
p=pHead->Next;
while(p)
{
i++;
p=p->Next;
}
return i;
}
5 向链表插入节点
//在第pos个结点前插入数据域为data的结点
int InsertDbLinkList(pNODE pHead, int pos, ElemType data)
{
int len=GetLengthDbLinkList(pHead);
if (pos<1||pos>len)
{
return 0;//插入失败
}
else
{
int i=1;//循环变量
pNODE pNew=(pNODE)malloc(sizeof(NODE));
pNODE p=pHead->Next;
if(p==NULL)
{
printf("链表为空!\n");
return 0;
}
while(p!=NULL&&i<pos-1)
{
p=p->Next;//p指向第pos个结点的前驱结点
i++;
}
if (pNew==NULL)
{
printf("分配内存失败!\n");
return 0;
}
pNew->data=data;
pNew->Next=p->Next;
p->Next->Prior=pNew;
pNew->Prior=p;
p->Next=pNew;
}
}
6 从链表删除节点
//从带有头结点双向循环链表中删除第pos个结点
int DeleteDbLinkList(pNODE pHead, int pos)
{
int len=GetLengthDbLinkList(pHead);
int i=1;
pNODE p=pHead->Next;
if (pos<1||pos>len-1)
{
printf("删除结点失败,重新选择结点位置!\n");
return 0;
}
while(p!=NULL&&i<pos)//p指向第pos个结点
{
p=p->Next;
i++;
}
p->Prior->Next=p->Next;
p->Next->Prior=p->Prior;
free(p);
return 1;
}
7 程序运行结果
int main()
{
pNODE pHead=(pNODE)malloc(sizeof(NODE));
pHead=CreateDbLinkList();
TraverseDbLinkList(pHead);
printf("\n");
printf("链表长度为%d\n",GetLengthDbLinkList(pHead));
printf("\n");
if (InsertDbLinkList(pHead,2,0))
{
printf("插入结点成功!\n");
}
TraverseDbLinkList(pHead);
printf("\n");
if (DeleteDbLinkList(pHead,2))
{
printf("删除结点成功!\n");
}
TraverseDbLinkList(pHead);
printf("\n");
}