您的位置:首页 > 编程语言 > C语言/C++

双向链表

2015-01-11 13:50 267 查看
双向链表
定义:在单链表的每个结点里再增加一个指向其直接前驱的指针域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");
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息