这里,我们来实现双向循环链表的基本操作。
1.创建双向循环链表
DuLinkList CreateDuLinkList(DuLinkList L) //创建一个双向循环空链表
{
L=(DuLinkList)malloc(sizeof(DuLNode));
L->next=L; //它的后驱指向自己
L->prior=L; //它的前驱也指向自己
return L;
}
2.给双向循环链表初始化数据
void AddInitData(DuLinkList head) //这里创建一个首元结点,它的前驱后继与头结点互指
{
DuLinkList L=(DuLinkList)malloc(sizeof(DuLNode));
User user;
user.id=0;
strcpy(user.username,"px");
L->user=user;
L->prior=head; //将待添加结点的前驱设置为头结点的地址
head->next=L; //将头结点的后继设置为待添加结点的地址
L->next=head; //将待添加结点的后继设置为头结点的地址
head->prior=L; //将头结点的前驱设置为待添加结点的地址
}
3.在某个位置插入一个结点
void InsertIntoDuLinkList(DuLinkList head,int index,User user)
{
int i=0;
while(head && i<index) //退出循环后,head代表的是指向目标位置的结点,如果index=0,表示在最末尾加上结点
{
head=head->next;
i++;
}
DuLinkList L=(DuLinkList)malloc(sizeof(DuLNode));
L->user=user;
L->prior=head->prior; //将目标结点的前驱指向目标位置前一个结点
head->prior->next=L; //将目标位置的前一个结点指向目标结点
L->next=head; //将目标结点的后继指向当前目标位置的结点
head->prior=L; //当前目标位置的前驱指向目标结点。至此,目标结点成功插入到目标位置
}
4.删除某个位置的结点
void DeleteElemByIndex(DuLinkList head,int index)
{
int i=0;
while(head && i<index) //循环结束后,head表示指向目标位置的指针
{
head=head->next;
i++;
}
head->prior->next=head->next; //当前目标位置的前一个结点指向当前目标位置的后一个结点
head->next->prior=head->prior; //当前目标位置的后一个结点指向当前目标位置的前一个结点
}
难点1:在某个位置插入一个结点(p=head)
L->prior=head->prior; //1.将目标结点的前驱指向目标位置前一个结点
head->prior->next=L; //2.将目标位置的前一个结点指向目标结点
L->next=head; //3.将目标结点的后继指向当前目标位置的结点
head->prior=L; //4.当前目标位置的前驱指向目标结点。至此,目标结点成功插入到目标位置
难点2:在某个位置删除结点(p=head)
head->prior->next=head->next; //1.当前目标位置的前一个结点指向当前目标位置的后一个结点
head->next->prior=head->prior; //2.当前目标位置的后一个结点指向当前目标位置的前一个结点
这里,附上完整的源码一份
#include<bits/stdc++.h>
using namespace std;
typedef struct
{
char username[20];
int id;
}User;
//双向循环链表的存储结构
typedef struct DuLNode
{
User user; //数据域
struct DuLNode *prior; //直接前驱
struct DuLNode *next; //直接后继
}DuLNode,*DuLinkList; //LinkList为指向LNode的指针类型
//构建双向循环链表
DuLinkList CreateDuLinkList(DuLinkList L)
{
L=(DuLinkList)malloc(sizeof(DuLNode));
L->next=L;
L->prior=L;
return L;
}
//给双向循环链表添加初始化数据
void AddInitData(DuLinkList head)
{
DuLinkList L=(DuLinkList)malloc(sizeof(DuLNode));
User user;
user.id=0;
strcpy(user.username,"px");
L->user=user;
L->prior=head; //将待添加结点的前驱设置为头结点的地址
head->next=L; //将头结点的后继设置为待添加结点的地址
L->next=head; //将待添加结点的后继设置为头结点的地址
head->prior=L; //将头结点的前驱设置为待添加结点的地址
}
//插入数据到某个位置
void InsertIntoDuLinkList(DuLinkList head,int index,User user)
{
int i=0;
while(head && i<index) //退出循环后,head代表的是指向目标位置的结点,如果index=0,表示在最末尾加上结点
{
head=head->next;
i++;
}
DuLinkList L=(DuLinkList)malloc(sizeof(DuLNode));
L->user=user;
L->prior=head->prior; //将目标结点的前驱指向目标位置前一个结点
head->prior->next=L; //将目标位置的前一个结点指向目标结点
L->next=head; //将目标结点的后继指向当前目标位置的结点
head->prior=L; //当前目标位置的前驱指向目标结点。至此,目标结点成功插入到目标位置
}
//测试循环链表
void TestDuLinkList(DuLinkList head)
{
int i=0;
while(head && i<5)
{
cout<<head->user.id<<" "<<head->prior<<" "<<head<<" "<<head->next<<endl;
head=head->next;
i++;
}
}
//删除某个位置的结点
void DeleteElemByIndex(DuLinkList head,int index)
{
int i=0;
while(head && i<index) //循环结束后,head表示指向目标位置的指针
{
head=head->next;
i++;
}
head->prior->next=head->next; //当前目标位置的前一个结点指向当前目标位置的后一个结点
head->next->prior=head->prior; //当前目标位置的后一个结点指向当前目标位置的前一个结点
}
int main()
{
DuLinkList L;
User user;
//构建一个双向循环链表
DuLinkList head=CreateDuLinkList(L);
//给双向循环链表添加初始化数据
AddInitData(head);
//插入数据到某个位置
user.id=1;
strcpy(user.username,"gjw");
InsertIntoDuLinkList(head,0,user);
//测试双向循环链表
//TestDuLinkList(head);
//删除某个位置的结点
DeleteElemByIndex(head,1);
return 0;
}
至此,双向循环链表的基本操作我们就学会了