精华内容
下载资源
问答
  • 双链表和循环双链表复习

    千次阅读 2018-08-10 08:40:32
    首先不管是单链表还是双链表或者循环双链表,都是为了提高访问效率,比如同样的插入操作,顺序表需要用数组移动元素,访问效率比较差,相反链表只需要移动指针,而且顺序表是有最大空间的,而链表没有。 双链表格式...

    首先不管是单链表还是双链表或者循环双链表,都是为了提高访问效率,比如同样的插入操作,顺序表需要用数组移动元素,访问效率比较差,相反链表只需要移动指针,而且顺序表是有最大空间的,而链表没有。

    双链表格式:


    struct node     //双向链表
    {
        ElemType data;   //数据域
        struct node *next;   //指针域   指向下一个后继方向
        struct node *prior;           //指向前一个前驱方向
    };

    结点指向 p == p->prior->next == p->next->prior

    双向链表和单链表各个功能使用的区别:

    1.初始化;

    int LinkInit(Node **l)
    {
        *l = (Node *)malloc(sizeof(Node) * 1);   //分配头结点   l 就是头指针
        if (NULL == *l)
        {
            return FAILURE;
        }

        (*l)->next = NULL;    //头结点指针域为空
        (*l)->prior = NULL;   //双向链表,头结点prior指针为空。可以看出相比单链表多分配一个指针

        return SUCCESS;
    }

     

     

    2.插入函数:

    int LinkInsert(Node *l, int n, ElemType e)  //n 插入的位置
    {
        Node *p = l;
        int k = 1;   //k 移动的次数

        if (NULL == l)
        {
            return FAILURE;
        }

        while (k < n && p != NULL)
        {
            p = p->next;
            k++;
        }

        if (k > n || p == NULL)
        {
            return FAILURE;
        }

        Node *q = (Node *)malloc(sizeof(Node) * 1);
        if (NULL == q)
        {
            return FAILURE;
        }

        q->data = e;
        q->prior = p;//多了一步指向p头指针的前继
        q->next = p->next;
        p->next = q;
        if (NULL != q->next)    //多了一步如果q不是最后一个结点(画图理解会发现,后面p后面结点如果没有这一步会少一个前驱)
        {
            q->next->prior = q;
        }

        return SUCCESS;
    }

    3.浏览函数和单链表一样

    int LinkTraverse(Node *l, void (*p)(ElemType))//比较函数判断是否相等
    {
        if (NULL == l)
        {
            return FAILURE;
        }
        Node *q = l;

        while (q->next)
        {
            q = q->next;
            p(q->data);
        }

        return SUCCESS;
    }

    4,长度函数一样

    int LinkLength(Node *l)
    {
        if (NULL == l)
        {
            return FAILURE;
        }

        int len = 0;
        Node *p = l->next;

        while (p)
        {
            len++;
            p = p->next;
        }

        return len;
    }

     

    5.判空函数一样

    int LinkEmpty(Node *l)
    {
        return (l->next == NULL) ? TRUE : FALSE;
    }

    6删除函数:

    int LinkDelete(Node *l, int p, ElemType *e)//删除位置p
    {
        int k = 1;
        Node *q = l;

        if (l == NULL)
        {
            return FAILURE;
        }

        while (k < p && q != NULL)//移动被删元素前一个
        {
            q = q->next;
            k++;
        }

        if (k > p || q == NULL)
        {
            return FAILURE;
        }

        Node *n = q->next;//让n指向q后面要删的元素
        *e = n->data;//将被删元素放入e中
        q->next = n->next;  //指向被删元素的后面一个 ,如果n是最后一个指向nuLL
        if (n->next != NULL)     //如果不是最后一个进入循环  
        {
            n->next->prior = q;//让n后面的元素的前继指向q
        }
        free(n);释放删除元素

        return SUCCESS;
    }

     

    清空函数的区别:

    int LinkClear(Node *l)
    {
        if (NULL == l)
        {
            return FAILURE;
        }

        Node *p = l->next;

        while (p)
        {
            l->next = p->next;
            //p->next->prior = l;//可有可无,目的是让后面结点的前驱指向头结点
            free(p);
            p = l->next;//防止p为野指针,free(P)会让变成NULL,并将p往后指向,依次释放,直到最后一个结点
        }

        return SUCCESS;
    }

     

    注意:双链表没有倒叙的说法
    二:双链循环链表

    循环链表,和单链表最大的区别,单链表最后指向NULL;而循环链表指向头结点或者第一个结点

     

    如图:可以看出首尾的链表,在空表的时候都是头尾都是指向自己的。

    所以初始化也与单链表有一定区别:

    int LinkInit(Node **l)
    {
        *l = (Node *)malloc(sizeof(Node) * 1);   //分配头结点   l 就是头指针
        if (NULL == *l)
        {
            return FAILURE;
        }

        (*l)->next = (*l);    //后继指向自己
        (*l)->prior = (*l);   //前驱指向自己

        return SUCCESS;
    }

    插入函数:

    int LinkInsert(Node *l, int n, ElemType e)  //n 插入的位置
    {
        Node *p = l;
        int k = 1;   //k 移动的次数

        if (NULL == l)    //入参判断
        {
            return FAILURE;
        }

        if (n > LinkLength(l) + 1)    //超过最大长度报错,由于是循环链表,最后会回到头结点
        {
            return FAILURE;
        }

        while (k < n)     //***
        {
            p = p->next;
            k++;
        }


        if (k > n)    //循环次数大于插入位置,会让数据变得不准确,比如n=0,k=1,不进入while循环,数据被送入头结点
        {
            return FAILURE;
        }

        Node *q = (Node *)malloc(sizeof(Node) * 1);
        if (NULL == q)
        {
            return FAILURE;
        }


        q->data = e;
        q->prior = p;
        q->next = p->next;
        p->next = q;
        if (l != q->next)    //如果q不是最后一个结点 **
        {
            q->next->prior = q;
        }

        return SUCCESS;
    }
     

    浏览函数:

     

    int LinkTraverse(Node *l, void (*p)(ElemType))
    {
        if (NULL == l)
        {
            return FAILURE;
        }
        Node *q = l;

        while (q->next != l)     //不等于本身  
        {
            q = q->next;
            p(q->data);
        }

        return SUCCESS;
    }

    测试长度函数:

    int LinkLength(Node *l)
    {
        if (NULL == l)
        {
            return FAILURE;
        }

        int len = 0;
        Node *p = l->next;

        while (p != l)   //不等于本身 **
        {
            len++;
            p = p->next;
        }

        return len;
    }

    判断是否为空函数

    int LinkEmpty(Node *l)
    {
        return (l->next == l && l->prior == l) ? TRUE : FALSE;  //前驱和后继指向头结点,判断为空表
    }

    元素获取函数

    int GetElem(Node *l, int p, ElemType *e)    //p 位置
    {
        if (NULL == l || p < 1)   //入参判断  p不能小于0
        {
            return FAILURE;
        }

        Node *q = l->next;   //双向循环链表,q指向第一个结点  //**
        int i;

        for (i = 1; i < p && q != l; i++)    //循环p次,同时满足q不为空  双向循环链表 i = 1**
        {
            q = q->next;
        }

        if (q == l)      //如果q为空,说明p(位置)大于长度  **这里要用q=L来判断插入位置是否大于长度
        {
            return FAILURE;
        }

        *e = q->data;     //q已经指向第p个结点

        return SUCCESS;
    }

    查询函数:

     

    int LocateElem(Node *l, ElemType e, int (*p)(ElemType, ElemType))
    {
        if (NULL == l)
        {
            return FAILURE;
        }
        
        Node *q = l->next;
        int len = 1;

        while (q != l)     //双向循环链表  最后指向头结点
        {
            if (p(e, q->data) == TRUE)
            {
                return len;
            }
            q = q->next;
            len++;
        }

        return FAILURE;
    }

     

     

    删除函数:

    int LinkDelete(Node *l, int p, ElemType *e)
    {
        int k = 1;
        Node *q = l;

        if (l == NULL)
        {
            return FAILURE;
        }

        if (p > LinkLength(l) + 1)   //判断位置p是否合法  ,因为相对于普通链表没有p=nuLL末尾判断条件
        {
            return FAILURE;
        }

        while (k < p)  //**
        {
            q = q->next;
            k++;
        }

        if (k > p)  //**
        {
            return FAILURE;
        }

        Node *n = q->next;
        *e = n->data;
        q->next = n->next;   
                             //如果不是最后一个  **

        n->next->prior = q;
        free(n);

        return SUCCESS;
    }

     

    清空函数:

    int LinkClear(Node *l)
    {
        if (NULL == l)
        {
            return FAILURE;
        }

        Node *p = l->next;

        while (p != l)  //不回到头结点时
        {
            l->next = p->next;
            //p->next->prior = l;
            free(p);
            p = l->next;
        }

        l->prior = l;   //**

        return SUCCESS;
    }

     

     

    展开全文
  • 1. 循环双链表循环双链表就是循环单链表双链表的集合体了。2. 基本操作操作名称操作说明InsertInHead(val_list)头插法创建循环双链表InsertInTail(val_list)尾插法创建循环双链表IsEmpty()判断循环双链表是否为空...

    文章目录

    前言

    1. 循环双链表

    2. 基本操作

    3. 代码实现前言

    本篇章主要介绍线性表中的循环双链表,并用Python实现其基本操作。

    1. 循环双链表

    循环双链表就是循环单链表和双链表的集合体了。

    f07e925127982b214c7896bf979d0174.png

    2. 基本操作

    操作名称

    操作说明

    InsertInHead(val_list)

    头插法创建循环双链表

    InsertInTail(val_list)

    尾插法创建循环双链表

    IsEmpty()

    判断循环双链表是否为空

    LengthList()

    返回循环双链表的长度

    TraverseList()

    打印出循环双链表里的数据元素

    InsertInPosition(pos, data)

    在指定位置插入

    SearchWithPosition(pos)

    按位置查找结点

    SearchWithVal(data)

    按值查找结点

    RemoveWithPosition(pos)

    移除指定位置的结点

    RemoveWithVal(data)

    移除指定值的结点

    3. 代码实现

    class CircularDoubleLinkList(object):

    def __init__(self):

    self.__head = DoubleLinkNode(None)

    self.__head.next = self.__head

    def InsertInHead(self, val_list):

    """

    头插法

    :param val_list:

    :return:

    """

    prehead = self.__head

    for val in val_list:

    new_node = DoubleLinkNode(val)

    if self.IsEmpty():

    prehead.next = new_node

    new_node.prior = prehead

    new_node.next = self.__head

    self.__head.prior = new_node

    else:

    new_node.next = prehead.next

    prehead.next.prior = new_node

    prehead.next = new_node

    new_node.prior = prehead

    def InsertInTail(self, val_list):

    """

    尾插法

    :param val_list:

    :return:

    """

    prehead = self.__head

    for val in val_list:

    new_node = DoubleLinkNode(val)

    prehead.next = new_node

    new_node.prior = prehead

    new_node.next = self.__head

    self.__head.prior = new_node

    prehead = prehead.next

    def IsEmpty(self):

    """

    判断循环双链表是否为空, 空表返回True

    :return:

    """

    if self.__head.next == self.__head:

    return True

    def LengthList(self):

    """

    返回循环双链表的长度

    :return:

    """

    prehead = self.__head

    count = 0

    if self.IsEmpty():

    return count

    while prehead.next != self.__head:

    count += 1

    prehead = prehead.next

    return count

    def TraverseList(self):

    """

    遍历循环双链表, 并打印

    :return:

    """

    prehead = self.__head

    if self.IsEmpty():

    print('链表为空!')

    return 0

    while prehead.next != self.__head:

    prehead = prehead.next

    print(prehead.data, end=' ')

    print('')

    def InsertInPosition(self, pos, data):

    """

    在某个位置插入

    :param pos: [1, LengthSingleLinkList + 1]

    :param data:

    :return:

    """

    prehead = self.__head

    new_node = DoubleLinkNode(data)

    if pos <= 0 or pos > self.LengthList() + 1:

    print('插入位置错误!')

    return 0

    count = 0

    while count < pos - 1:

    prehead = prehead.next

    count += 1

    if prehead.next != self.__head:

    new_node.next = prehead.next

    prehead.next.prior = new_node

    else:

    new_node.next = self.__head

    self.__head.prior = new_node

    new_node.prior = prehead

    prehead.next = new_node

    def SearchWithPosition(self, pos):

    """

    按位置查找元素

    :param pos: [1, LengthSingleLinkList]

    :return:

    """

    prehead = self.__head

    if pos <= 0 or pos > self.LengthList():

    print('位置错误!')

    return -1

    count = 0

    while count < pos:

    prehead = prehead.next

    count += 1

    data = prehead.data

    return data

    def SearchWithVal(self, data):

    """

    按值查找元素

    :param data:

    :return:

    """

    prehead = self.__head

    count = 0

    while prehead.next != self.__head:

    prehead = prehead.next

    count += 1

    if prehead.data == data:

    return count

    print('该节点不存在!')

    return -1

    def RemoveWithPosition(self, pos):

    """

    按位置移除元素

    :param pos: [1, LengthSingleLinkList]

    :return:

    """

    prehead = self.__head

    if pos <= 0 or pos > self.LengthList():

    print('位置错误!')

    return 0

    count = 0

    while count < pos - 1:

    prehead = prehead.next

    count += 1

    temp = prehead.next

    if temp.next == self.__head:

    prehead.next = self.__head

    self.__head.prior = prehead

    else:

    prehead.next = temp.next

    temp.next.prior = prehead

    del temp

    def RemoveWithVal(self, data):

    """

    按值移除元素

    :param data:

    :return:

    """

    prehead = self.__head

    while prehead.next != self.__head:

    prehead = prehead.next

    if prehead.data == data:

    if prehead.next == self.__head:

    prehead.prior.next = self.__head

    self.__head.prior = prehead.prior

    else:

    prehead.prior.next = prehead.next

    prehead.next.prior = prehead.prior

    return -1

    print('该节点不存在!')

    测试代码如下:

    from LinkList import CircularDoubleLinkList

    if __name__ == '__main__':

    l1 = CircularDoubleLinkList()

    print('头插法创建循环双链表l1: ', end='')

    l1.InsertInHead([1, 3, 5, 7])

    l1.TraverseList()

    l2 = CircularDoubleLinkList()

    print('尾插法创建循环双链表l2: ', end='')

    l2.InsertInTail([1, 3, 5, 7])

    l2.TraverseList()

    print('链表l2的长度为: %d' % l2.LengthList())

    print('在链表l2的第3个位置上插入值为2的节点: ', end='')

    l2.InsertInPosition(3, 2)

    l2.TraverseList()

    print('链表l2的第4个位置上的节点的值为: %d' % l2.SearchWithPosition(4))

    print('链表l2值为7的节点的位置为: %d' % l2.SearchWithVal(7))

    print('移除链表l2的第5个位置上的节点: ', end='')

    l2.RemoveWithPosition(5)

    l2.TraverseList()

    print('移除链表l2值为1的节点: ', end='')

    l2.RemoveWithVal(1)

    l2.TraverseList()

    运行结果如下:

    aea2b332c8b4d5c67a7b38e04bcab959.png

    文章来源: https://blog.csdn.net/qq_42730750/article/details/107869233

    展开全文
  • 单向循环链表和双向循环链表的操作集

    双向链表

    • int inseser_debut_liste(Liste *list, int valeur) //插头
    • int inseser_fin_liste(Liste *list, int valeur) //插尾
    • int supprimer(Liste*list,int position) //删除
    typedef struct Element
    {
        int valeur;
        struct Element *suivant;
        struct Element *precedent;
    }Element;
    
    typedef struct Liste
    {
        Element *tete;   //头
        Element *queue;  //尾
        int taille;     //元素个数
    }Liste;
    
    int inseser_debut_liste(Liste *list, int valeur) //插头
    {
        Element *p=malloc(sizeof(Element));
        if(p==NULL) return -1;
        p->valeur=valeur;
        if(list->tete)
            list->tete->precedent=p;
        else
            list->queue=p;
        p->suivant=list->tete;
        list->tete=p;
        p->precedent=NULL;
        list->taille++;
        return 0;
    }
    
    int inseser_fin_liste(Liste *list, int valeur) //插尾
    {
        Element *p=malloc(sizeof(Element));
        if(p==NULL) return -1;
        p->valeur=valeur;
        if(list->queue)
            list->queue->suivant=p;
        else
            list->tete=p;
        p->precedent=list->queue;
        list->queue=p;
        p->suivant=NULL;
        list->taille++;
        return 0;
    }
    
    int supprimer(Liste*list,int position)
    {
        int k=1;
        if(list->nb==0||position<=0||position>list->taille)
            return -1;
        Element *p=list->tete;
        while(k<position)
        {
            p=p->suivant;
            k++;
        }
        if(p->precedent)
            p->precedent->suivant=p->suivant;
        else
            list->tete=p->suivant;
        if(p->suivant)
            p->suivant->precedent=p->precedent;
        else
            list->queue=p->precedent;
        list->taille--;
        free(p);
    }
    循环双向链表
    建立哨兵sentinelle的双向列表
    • T_list * Creer_list()  //创建list
    • void Inserer_Tete(T_list *l, int x) //插头
    • void Inserer_Queue(T_list *l, int x)  //插尾
    • void Print_list(T_list *l)
    • void Supprimer_Cellule(T_cell *c)  //删除单元
    • T_cell *Chercher_Val(T_list *l, int val)  //查找
    • void Supprimer_Val(T_list *l, int val) 
    • int Liste_Vide(T_list *l) //判断是否为空
    Figure1:插头 Figure2:插


    typedef struct cellule
    {
        int clé;
        struct cellule *succ;
        struct cellule *pred;
    }T_cell;
    typedef struct liste
    {
        T_cell *sentinelle;
    }T_list;
    T_list * Creer_list()
    {
        T_list *l;
        T_cell *c;
        l=(T_list *)malloc(sizeof(T_list));
        c=(T_cell *)malloc(sizeof(T_cell));
        l->sentinelle=c;
        c->pred=c;
        c->succ=c;
        return(l);
    }
    void Inserer_Tete(T_list *l, int x)
    {
        T_cell *c, *sentinelle;
        c=(T_cell *)malloc(sizeof(T_cell));
        c->clé=x;
        sentinelle=l->sentinelle;
        c->succ=sentinelle->succ;
        c->pred=sentinelle;
        sentinelle->succ->pred=c;
        sentinelle->succ=c;
    }
    
    void Inserer_Queue(T_list *l, int x)
    {
        T_cell *c, *sentinelle;
        c=(T_cell *)malloc(sizeof(T_cell));
        c->clé=x;
        sentinelle=l->sentinelle;
        c->succ=sentinelle;
        c->pred=sentinelle->pred;
        sentinelle->pred->succ=c;
        sentinelle->pred=c;
    }
    
    void Print_list(T_list *l)
    {
        T_cell *c;
        c=l->sentinelle->succ;
        while(c!=l->sentinelle)
        {
            printf("%d ",c->clé);
            c=c->succ;
        }
    }
    
    
    void Supprimer_Cellule(T_cell *c)
    {
        c->pred->succ=c->succ;
        c->succ->pred=c->pred;
    }
    
    T_cell *Chercher_Val(T_list *l, int val)
    {
        T_cell *c, *sentinelle;
        sentinelle=l->sentinelle;
        c=sentinelle->succ;
        while((c!=sentinelle)&&(c->clé!=val))
            c=c->succ;
        if(c==sentinelle)
            return NULL;
        else
            return c;
    }
    
    void Supprimer_Val(T_list *l, int val)
    {
        T_cell *c;
        c=Chercher_Val(l,val);
        if(c!=NULL)
        {
            Supprimer_Cellule(c);
            free(c);
        }
    }
    int Liste_Vide(T_list *l)
    {
        return(l->sentinelle->pred==l->sentinelle->succ);
    }





       

    展开全文
  • 循环链表和双向链表

    2013-05-22 12:40:43
    课件主要讲了循环链表,双向链表的操作,插入,删除等 循环链表、双向链表及线性表应用示例
  • 主要介绍了C语言中双向链表和双向循环链表详解的相关资料,需要的朋友可以参考下
  • 双向链表和双向循环链表的区别就是在尾节点的指向。双向循环链表的尾节点的next指向NULL。双向循环链表的尾节点的next指向首元结点,首元节点的prior指向尾节点。关于双向循环链表,可以看上一篇文章...

    f01a3c863383aac31ef73fe0f8611531.png

    双向链表和双向循环链表的区别就是在尾节点的指向。双向循环链表的尾节点的next指向NULL。双向循环链表的尾节点的next指向首元结点,首元节点的prior指向尾节点。

    关于双向循环链表,可以看上一篇文章

    https://zhuanlan.zhihu.com/p/12556623zhuanlan.zhihu.com

    双向循环链表的节点和双向链表一样

    0.0.双向循环链表的节点

    和双向链表一样,都包含前驱,元素,后继

    2ad37570ad0918fb3cc685608c61b648.png
    结构节点

    0.1空链表

    前驱和后继都是指向自己的

    1bb84d9be71cc7bff1746505fbb90345.png
    空链表

    0.2.非空双向循环链表

    e1cd0a6fad1e652d891a9a3f1308131e.png
    双向循环链表

    0.3准备工作

    #define ERROR 0
    #define TRUE 1
    #define FALSE 0
    #define OK 1
    
    #define MAXSIZE 20 /* 存储空间初始分配量 */
    
    typedef int Status;/* Status是函数的类型,其值是函数结果状态代码,如OK等 */
    typedef int ElemType;/* ElemType类型根据实际情况而定,这里假设为int */
    
    //定义结点
    typedef struct Node{
        ElemType data;
        struct Node *prior;
        struct Node *next;
    }Node;
    
    typedef struct Node * LinkList;

    1.初始化双向循环链表

    // 初始化链表
    Status initialLinkedList(LinkList *L) {
        // 设计头结点
        *L = (LinkList)malloc(sizeof(Node));
        if (*L == NULL) return ERROR;
        (*L) -> next = *L;
        (*L) -> prior = *L;
        (*L) -> data = -1;
        return OK;
    }

    2.遍历双向循环链表

    // 遍历双向循环链表
    Status Display(LinkList L){
        
        if (L == NULL) {
            printf("打印的双向循环链表为空!nn");
            return ERROR;
        }
        printf("双向循环链表内容:  ");
        
        LinkList p = L->next;
        // 等于头节点时,即遍历完毕
        while (p != L) {
            printf("%d  ",p->data);
            p = p->next;
        }
        printf("nn");
        return OK;
    }
    

    3.插入数据

    双向循环链表的插入和双向链表类似

    731b547342d382b6e042308c67fe7eaa.png
    插入元素

    ①遍历得到需要插入位置的上一个节点(p)

    ②创建需要插入的节点temp

    ③让p的next节点的prior指向temp (p.next.prior -> temp),这时③2就断开了

    ④让temp的next指向p的next (temp.next -> p.next)

    ⑤让p的next指向temp (p.next->temp),这时⑤2断开

    ⑥让temp的prior指向p

    注意:上面的③和④必须在⑤和⑥的前面,且位置不能交换,当然③和④可以交换,⑤和⑥也可以交换

    // 双向循环链表插入元素
    /*当插入位置超过链表长度则插入到链表末尾*/
    Status LinkListInsert(LinkList *L, int index, ElemType e){
       
        //1. 创建指针p,指向双向链表头
        LinkList p = (*L);
        int i = 1;
        
        //2.双向循环链表为空,则返回error
        if(*L == NULL) return ERROR;
       
        //3.找到插入前一个位置上的结点p
        while (i < index && p->next != *L) {
            p = p->next;
            i++;
        }
        
        //4.如果i>index 则返回error
        if (i > index)  return ERROR;
        
        //5.创建新结点temp
        LinkList temp = (LinkList)malloc(sizeof(Node));
        
        //6.temp 结点为空,则返回error
        if (temp == NULL) return ERROR;
        
        //7.将生成的新结点temp数据域赋值e.
        temp->data = e;
        
        //8.将结点temp 的前驱结点为p;
        temp->prior = p;
        //9.temp的后继结点指向p->next;
        temp->next = p->next;
        //10.p的后继结点为新结点temp;
        p->next = temp;
        
        //如果temp 结点不是最后一个结点
        if (*L != temp->next) {
            //11.temp节点的下一个结点的前驱为temp 结点
            temp->next->prior = temp;
        }else{
            (*L)->prior = temp;
        }
        
        return OK;
    }

    打印结果如下

    b87fa80a0930404247317bbe4e47f961.png
    插入数据的打印

    4.双向循环链表的元素删除

    删除和双向链表一样

    f4dd8969a947fda4cd999d7ec8d7357a.png
    删除元素

    ①遍历需要删除节点的上一个节点得到节点p

    ②让p的next指向p的next的next (p.next=p.next.next),此时②1断开

    ③让p的next的next的prior指向p (p.next.next->p), 此时③2断开

    ④释放deleNode (free(deleNode))

    // 双向循环链表删除结点
    Status LinkListDelete(LinkList *L,int index,ElemType *e){
        
        int i = 1;
        LinkList temp = (*L)->next;
        
        if (*L == NULL) {
            return  ERROR;
        }
        
        //如果删除到只剩下首元结点了,则直接将*L置空;
        if(temp->next == *L){
            free(*L);
            (*L) = NULL;
            return OK;
        }
        
        //1.找到要删除的结点
        while (i < index) {
            temp = temp->next;
            i++;
        }
        // 给e赋值要删除结点的数据域
        *e = temp->data;
    
        //2.修改被删除结点的前驱结点的后继指针 图第2步
        temp->prior->next = temp->next;
        //3.修改被删除结点的后继结点的前驱指针 图第3步
        temp->next->prior = temp->prior;
        //4. 释放结点temp
        free(temp);
        return OK;
        
    }

    删除后的结果

    fd13a925d0b533d6a04f9bd0869427f7.png
    删除后
    展开全文
  • 双向链表 包含两个指针,一个prev指向前一个节点,一个next指向后一个节点。 双向循环链表 最后一个节点的 next 指向head,而 head 的prev指向最后一个节点,构成一个环。
  • 循环双链表

    2013-06-09 19:08:45
    循环双链表采用纯C编写,其中包含初始化、增加结点、修改结点删除结点等
  • 创建循环单链表和循环双链表 循环单链表 //初始化与一个循环链表 bool InitList(LinkList &L){ L=(LNode *)malloc(sizeof(LNode)); //分配一个头结点 if (L==NULL) //内存不足,分配失败 return false...
  •  循环链表一般包括循环单链表和循环双链表,如下图所示: 循环单链表   循环单链表与单链表的区别在于,表中最后一个结点的指针不是NULL,而改为指向头结点,从而使整个链表形成一个环。   一般对循环单链表只...
  • 双链表、循环双链表

    2018-04-14 11:16:07
    程序小白,希望大家多交流,共同学习 //双向链表 #include&lt;iostream&gt; using namespace std; struct DNode { int data; DNode *prior, *next; }; typedef DNode DNode, *DLinkList; //初始化...
  • 单向循环链表和双向循环链表

    千次阅读 2019-11-25 11:58:10
    单向循环链表和双向循环链表1.单向循环链表2.双向循环链表 关于顺序表、单向链表和双向链表请将鼠标移步 此处点击 1.单向循环链表 代码实现: //#pragma once //作为头文件时加上这行 #include<stdio.h> #...
  • 循环双向链表

    2019-10-01 23:32:05
    第一次用C#描述链表,大学时用C++ 描述链表的感觉很一致,用visual studio很快就可以实现单向链表,双向链表, 和循环链表。 The reference type of C# is a key, and play the same role as pointer in C++. 上...
  • 双向链表和循环链表

    2019-05-15 21:35:44
    双向链表和单链表的区别就在于多了一个前驱;有需要查看单链表的在主页里面查找; 双向链表代码如下: typedef class Node { public: int data; Node *next; Node *pre; }node; class doublelist { public: ...
  • 实验3 循环链表和双链表 数据结构 实验3 循环链表和双链表 数据结构 实验3 循环链表和双链表 数据结构
  • 双链表和循环链表

    2016-09-05 17:20:00
    同样,双链表也分为带头结点的双链表和不带头结点的双链表,情况类似于单链表。带头结点的双链表 head->next 为null的时候链表为空。不带头结点的双链表head为null的时候链表为空。 1.采用尾插法建立双链表 vo....
  • 双向链表和循环链表并用 双向链表使用前驱指针以及后继指针 循环链表就是尾指针指向头 约瑟夫环问题:n个人围成一个圈,指定一个数字v,从第一个人开始报数,每轮报到v的选手出局,由下一个人接着从头开始报,最后一...
  • 本篇文章主要介绍了JavaScript数据结构之双向链表和双向循环链表的实现,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 双向链表和双向循环链表 介绍: (Introduction:) Before going into doubly linked list implementation, you must have basic knowledge about Linked List. If you haven’t read about Linked List or Singly ...
  • 上篇教程给大家分享了单链表的概念,以及如何用 Java 实现一个单链表的结构。...循环链表循环链表本质上就是一种单链表,两者的不同之处在于链表中最后一个节点的指针指向哪里,在单链表中,末尾节点的指针指向...
  • 循环链表和双链表

    2018-06-30 22:23:52
    1、假设在长度大于1的单循环链表中,既无头结点也无头指针。s为指向某个结点的指针,试编写算法删除结点*s的直接前驱结点。...(头结点可以另辟空间)3、有一双链表,每个结点中除有prior、datanext域外...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,730
精华内容 1,892
关键字:

循环双链表和双循环链表