双向链表:

简介: 双向链表:

双向链表


1,双向链表节点


20200315211512242.png


2,具体操作


(1)定义结点结构体


      ```c
      typedef int data_t;
      //定义结点结构体
      typedef struct node{    
      data_t data; //数据域    
      struct node *front; //保存上一个结点的地址    
      struct node *next; //保存下一个结点的地址
      }doublelist;
      ```


(2)创建一个空的链表


      ```c
      doublelist *Head = NULL;
      ```


(3)尾插法插入数据


      ```c
      //尾插法插入数据
      void InsertDataByTail(doublelist **head, data_t value)
      {    
      //申请空间并赋值    
      doublelist *temp = (doublelist *)malloc(sizeof(doublelist));    
      temp->data = value;    
      temp->front = NULL;    
      temp->next = NULL;
          if(*head == NULL)    
          {        
          //如果链表为空,则指针保存第一个插入结点的地址        
          *head = temp;        
          //让结点的两个指针域保存NULL表示没有其他结点        
          (*head)->front = NULL;        
          (*head)->next = NULL;      
          }    
          else     
          {        
          //如果不为空,先找到最后一个结点        
          doublelist *p = *head;
              while(p->next != NULL)        
              {            
              p = p->next;        
              }
              //将最后一个结点的地址保存在新插入的结点的front指针里面        
              temp->front = p;        
              //将新插入结点的地址保存在最后一个结点的next指针里面        
              p->next = temp;    
              }
          return ;}
      ```


(4)打印数据


        ```c
        //打印数据
        void PrintData(doublelist *head){    
        printf("%d ", head->data);    
        while(head->next != NULL)    
        {        
        printf("%d ", head->next->data);
                head = head->next;    
                }    
                putchar(10);
            printf("************************************\n");
            while(head != NULL)    
            {        
            printf("%d ", head->data);
                head = head->front;    
                }    
                putchar(10);
                }
        ```


(5)头删法删除数据,返回要删除的结点的数据


        ```c
        //头删法删除数据
        data_t DeleteDataOnHead(doublelist **head){    
        if(*head == NULL)    
        {        
        printf("链表为空不能删除数据了\n");        
        return (data_t)-1;    
        }
            doublelist *temp = *head;    
            data_t value = temp->data;
            //让指针保存新的头结点的地址    
            *head = (*head)->next;    
            //让当前结点的front指针域保存NULL    
            (*head)->front = NULL;
            free(temp);    
            temp = NULL;
            return value;
            }
        ```


(6)插入并排序


        ```c
        //插入并排序
        void InsertDataAndSort(doublelist **head, data_t value){    
        doublelist *temp = (doublelist *)malloc(sizeof(doublelist));    
        temp->data = value;    
        temp->front = NULL;    
        temp->next = NULL;
            if(*head == NULL)    
            {        
            //如果链表中没有数据,则用指针保存新插入结点的地址        
            *head = temp;        
            (*head)->front = NULL;        
            (*head)->next = NULL;    
            }    
            else    
            {        
            //如果新插入的结点的数据小于等于第一个结点        
            if((*head)->data >= temp->data)        
            {            
            //新插入的结点的next保存原本的第一个结点的地址            
            temp->next = *head;            
            //原本的第一个结点的front保存新插入结点的地址            
            (*head)->front = temp;
                    //指针保存新插入结点的地址            
                    *head = temp;            
                    (*head)->front = NULL;        
                    }        
                    else        
                    {            
                    doublelist *p = *head;
                    while(p->next != NULL && p->next->data < temp->data)            
                    {                
                    p = p->next;            
                    }      
                    //如果p结点后面没有数据            
                    if(p->next == NULL)            
                    {                
                    //类似尾插法               
                    p->next = temp;                
                    temp->front = p;            
                    }            
                    //如果p结点后面有数据            
                    else             
                    {                
                    //将新插入结点的地址保存在p后一个结点的front指针里面                
                    p->next->front = temp;                
                    //将p后一个结点的地址保存在新插入结点的next指针里面                
                    temp->next = p->next;
                        //将新插入结点的地址保存在p的结点的next指针里面               
                        p->next = temp;                
                        //将p的结点的地址保存在新插入结点的front指针里面                
                        temp->front = p;            
                        }        
                        }    
                        }
                        }
        ```


相关文章
|
1月前
|
存储
双向链表
单链表每个结点有一个指针域和一个数据域,要访问任何结点都需知道头结点,不能逆着进行。双向链表则添加了一个指针域,通过两个指针域分别指向结点的前一个结点和后一个结点。这样的话,可以通过双链表的任何结点访问到它的前一个结点和后一个结点。 两个指针域一个存储直接后继结点的地址,一般称为右链域,另一个存储直接前驱结点,一般称为左链域。
|
2月前
|
存储
双向链表(详解)
双向链表(详解)
33 1
|
6月前
|
存储
双向链表专题
双向链表专题
46 6
|
6月前
双向链表的实现
双向链表的实现
22 0
|
6月前
|
存储 算法 前端开发
【C/数据结构与算法】:链表的实现(单向链表+双向链表)
【C/数据结构与算法】:链表的实现(单向链表+双向链表)
30 0
|
7月前
秒懂双向链表
秒懂双向链表
33 0
|
7月前
|
存储
双向链表介绍
带头链表⾥的头节点,实际为“哨兵位”,哨兵位节点不存储任何有效元素,只是站在这⾥“放哨的”。哨兵位存在的意义:避免链表出现死循环。
40 0
|
7月前
|
Java
7.双向链表最佳实现
7.双向链表最佳实现
60 1
|
7月前
|
存储
【双向链表】数据结构双向链表的实现
【双向链表】数据结构双向链表的实现
|
存储 算法 搜索推荐
双向链表
双向链表是一种链式存储结构,每个节点包含两个指针,分别指向其前驱和后继。相比于单向链表,双向链表可以在常数时间内向前或向后遍历整个链表。因此,双向链表在需要频繁遍历链表的场景中具有优势。
59 7