线性表之链表基本操作的实现3

这里,我们来实现双向循环链表的基本操作。

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;
}

至此,双向循环链表的基本操作我们就学会了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值