std::list 循环删除指针_[算法答疑]双向循环链表的相关操作算法

本文介绍了如何在C++中创建和操作双向循环链表,包括创建链表、插入结点、删除指定位置或元素的结点以及查找和更新结点。详细阐述了每个操作的步骤,有助于理解和掌握双链表的算法。
摘要由CSDN通过智能技术生成

0cf44e96afbdcd97fb771c1edd180ecf.png

链表,是数据结构中很重要的一个章节,单链表和双链表的相关算法,也是考研的重点,下面学长为大家分享一下关于双链表操作的相关算法。

创建双向循环链表

1:创建头结点,新增结点,然后将头结点与创建的结点进行关联。

e8131020652b67eb57c364b90e7ee642.png7391c8e77b2587cea2b3b2188288fc6b.png

typedef int Status;//函数状态typedef int ElemType;//ElemType 根据实际情况而定typedef struct Node{     ElemType data;    struct Node *prior;//前趋    struct Node *next;//后继   }Node;// 类型重定义typedef struct Node *Linklist;//创建双向链表Status creatLinkList(LinkList *L){    //  1。创建头结点,开辟一个空间;    *L = (LinkList)malloc(sizeof(Node));    //判断是否创建成功    if(*L == NULL) return ERROR;    (*L)->prior=NULL; //前趋置空    (*L)->next =NULL; //后趋置空    (*L) ->data =-1;   //临时    //新增结点       LinkList p = *L;        for(int i=0;i<10;i++){       //创建临时变量节点        LinkList temp = (linkList)malloc(sizeof(Node));        if(temp ==NULL) return ERROR;//容错        //设置前趋后趋和数据        temp->prior = NULL;        temp->next = NULL;        temp->data =i;            //创建关系 p-temp        p->next = temp;        temp->prior = p;        //p 后移        p= p->next;         }    return OK;}void display(LinkList L){    //不打印头结点 跳过L;     LinkList temp = L->next;    if (temp == NULL){       return;    }    while (temp){        printf("打印数据 %d",temp->data);        temp = temp->next;//temp 后移    }}int main(int argc,const char* argv[]){    Status isStatus = 0;    LinkList L;    //创建双向循环列表    isStatus = creatLinkList (&L);    //打印列表    display(L);}

双向链表的插入

3c493ad463993d09e4df771bf895a817.png

764b40b5dd0364ce79fc1f0a445f0f1c.png

双向列表的插入:

  • 首先判断插入位置是否是合法。

  • 然后需要新建结点。

  • 把p指向头结点

  • 循环找到要插入的位置

  • 判断插入位置是否是超过链表长度

  • 判断插入位置是否是结尾 (结尾:将链表尾部结点的next-->插入节点;将插入节点的prior -->尾部结点)

  • 对于非尾部结点:【1:p->next = temp; temp->prior = p ; p->next->prior = temp ; temp->next = p->next】插入节点的前趋跟后趋 分别指向插入结点的后趋及插入节点后节点的前趋。

Status insertList (LinkList *L, int i,ElemType data){    if(i<1) return ERROR;        LinkList temp = (LinkList)malloc(sizeof(Node));    temp->data = data;    temp->next = NULL;    temp->prior = NULL;        LinkList p = *L;        for(int j=1 ; j< i && p;j++){        p = p->next;    }        if(p==NULL) return ERROR;        if(p->next ==NULL){        P->next = temp;        temp->prior = p;     }else{        p->next = temp;        temp->prior = p;                temp->next = p->next;        p->next->prior = temp;    }    return OK;}

双向链表的删除

846daf894fd4456b25f9acf377e98690.png

删除列表指定位置的结点

  • 判断双向列表是否为空,如果是空就直接返回错误

  • 将指针p移动到删除元素位置前一个

  • 判断 k > i 或者 p ==null 返回错误

  • 创建临时删除指针delTemp 指向要删除的结点,并将要删除的结点data 传给*e , 返回

  • p->next 等于要删除的结点的下一个结点。

  • 如果删除结点的下一个节点不为空,则将要删除的下一个结点的前趋指针赋值P

  • 删除delTemp节点;

//5.4 删除双向链表指定位置上的结点Status ListDelete(LinkList *L, int i, ElemType *e){        int k = 1;    LinkList p = (*L);        //1.判断双向链表是否为空,如果为空则返回ERROR;    if (*L == NULL) {        return ERROR;    }          //2. 将指针p移动到删除元素位置前一个    while (k < i && p != NULL) {        p = p->next;        k++;    }        //3.如果k>i 或者 p == NULL 则返回ERROR    if (k>i || p == NULL) {        return  ERROR;    }        //4.创建临时指针delTemp 指向要删除的结点,并将要删除的结点的data 赋值给*e,带回到main函数    LinkList delTemp = p->next;    *e = delTemp->data;        //5. p->next 等于要删除的结点的下一个结点    p->next = delTemp->next;        //6. 如果删除结点的下一个结点不为空,则将将要删除的下一个结点的前驱指针赋值p;    if (delTemp->next != NULL) {        delTemp->next->prior = p;    }        //7.删除delTemp结点    free(delTemp);        return OK;    }

删除双向链表指定的元素

  • 遍历双向循环列表链表

  • 判断当前结点的数据域和data是否一致,如相等,则删除当前结点。

  • 删除:修改被删除结点的后继结点。修改被删除结点的后继结点的前趋。

  • 释放被删除的结点。

1bc10da606eff92dfd0a4edc9f4a8c46.png

Status LinkLisTDeletValue(LinkList * L,int data){    LinkList p = *L;    //遍历双向列表    while (p){      if(p->data ==data){          p->prior->next = p->next;          if (p->next != NULL){             P->next->prior = p->prior;          }          //释放被删除的节点P          free(p);         //退出循环          break;      }        p = p->next;    }}

双向链表查找元素

int selectElem (LinkList L,ElemType elem){   //头结点的下一个节点开始    LinkList p = L->next;    int i = 1;//移动跟踪    while (p){        //遍历查找到数据,返回索引值        if (p->data == elem){           return i;        }        //索引值自增        i++;        p = p->next;    }    return -1;}

双向链表中更新结点

Status replaceLinkList(LinkList * L,int index,ElemType newType){    //p 首元结点开始    LinkList p =(*L)->next;    for (int i=1;i<=index;i++){       p=p->next;    }    p->data = newElem;    return OK;}

算法比较基础,可以结合图形来理解算法,希望能帮助到大家! 

0cf44e96afbdcd97fb771c1edd180ecf.png

3c1ca17ff7d26accac203644ffd76790.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值