• 双向链表


    1.双向链表的优点:双向链表的主要优点是对于任意给的结点,都可以很轻易的获取其前结点和后结点,其主要缺点是每个结点需要保存next和prev两个属性,因此需要更多的空间开销,同时结点的插入与删除操作也将更加耗时,因为需要操作更多的指向操作

    2.双向链表的结构

      (1)单个节点的结构:

                        

      (2)数据的结构:

                     

      (3)尾部插入节点:

        

      (4)中间插入

      

    3.双向链表的具体操作

    #include "stdafx.h"
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    //节点结构
    typedef struct LinkedList
    {
        struct LinkedList * prior;
        int data;
        struct LinkedList * next;
    }LinkedList, *PLinkedList;
    //双链表的创建函数
    PLinkedList initLine(PLinkedList head);
    //输出双链表的函数
    void Display(PLinkedList head);
    //插入节点
    void InsertElem(PLinkedList head, int data);
    //删除指定节点
    void DeleteElem(PLinkedList head, int data);
    int main() 
    {
        //创建一个头指针
        PLinkedList    head = NULL;
        //调用链表创建函数
        head = initLine(head);
        //输出创建好的链表
        Display(head);
        //尾部插入一个节点
        InsertElem(head, 10);
        Display(head);
        //删除尾部的节点
        DeleteElem(head, 10);
        Display(head);
    
        //显示双链表的优点
        printf("链表中第 4 个节点的直接前驱是:%d", head->next->next->next->prior->data);
    
        
        system("pause");
        return 0;
    }
    
    void InsertElem(PLinkedList head, int data)
    {
        if (head == NULL){
            printf("The list is empty.
    ");        //  头结点为空,则无法插入
            return;
        }
        PLinkedList tmpHead = head;        //  创建一个临时的头结点指针
        while (tmpHead->next!=NULL)
        {
            tmpHead = tmpHead->next;
        }
        if (tmpHead->next == NULL)
        {
            PLinkedList addition = (PLinkedList)malloc(sizeof(LinkedList));
            _ASSERT(addition != NULL);
            addition->data = data;        //  数据域赋值
            addition->next = tmpHead->next;        //  后向指针连接
            tmpHead->next = addition;
            addition->prior = tmpHead;            //  将插入结点的front 指向头结点
        }
    }
    
    void DeleteElem(PLinkedList head, int data)
    {
        if (head == NULL){
            printf("The list is empty.
    ");
            return;
        }
        PLinkedList tmpHead = head;
        while (tmpHead->next != NULL){
            tmpHead = tmpHead->next;
            if (tmpHead->data == data)
            {
                //此节点为最后一个节点
                if (tmpHead->next == NULL)
                {
                    tmpHead->prior->next = NULL;        //  将被删结点的上一个结点的next 指针指向 NULL
                    tmpHead->prior->prior = head;        //  将被删结点的上一个结点的prior指向头节点
                }
                //删除中间节点
                else
                {
                    tmpHead->prior->next = tmpHead->next;        //  将被删结点的上一个结点的next 指针指向 被删结点的下一个结点
                    tmpHead->next->prior = tmpHead->prior;        //  将被删结点的下一个结点的 front 指针指向 被删结点的上一个结点
                }
                break;
            }
        }
        free(tmpHead);        //  释放内存
    }
    
    
    PLinkedList initLine(PLinkedList head)
    {
        //创建一个首元节点,链表的头指针为head
        head = (PLinkedList)malloc(sizeof(LinkedList));
        //对节点进行初始化
        head->prior = NULL;
        head->next = NULL;
        head->data = 1;
        //声明一个指向首元节点的指针,方便后期向链表中添加新创建的节点
        PLinkedList list = head;
        for (int i = 2; i <= 5; i++) {
            //创建新的节点并初始化
            PLinkedList body = (PLinkedList)malloc(sizeof(LinkedList));
            body->prior = NULL;
            body->next = NULL;
            body->data = i;
            //新节点与链表最后一个节点建立关系
            list->next = body;
            body->prior = list;
            //list永远指向链表中最后一个节点
            list = list->next;
        }
        //返回新创建的链表
        return head;
    }
    
    void Display(PLinkedList head)
    {
        PLinkedList temp = head;
        while (temp) {
            //如果该节点无后继节点,说明此节点是链表的最后一个节点
            if (temp->next == NULL) {
                printf("%d
    ", temp->data);
            }
            else{
                printf("%d <-> ", temp->data);
            }
            temp = temp->next;
        }
    }
    111
  • 相关阅读:
    在vue中引入layer弹框的简易方法
    in ./node_modules/qs/lib/index.js Module build failed: Error: ENOENT: no such file or directory, o
    vue路由传参的三种基本方式
    跳转路由时传参,elementUI的table表格点击对应行,获取对应行的数据;更改el-table头部样式
    用Vue写移动端时有哪些UI框架
    1月25日学习日志
    1月22日学习日志
    1月21日学习日志
    1月20日学习日志
    1月19日学习日志
  • 原文地址:https://www.cnblogs.com/zwj-199306231519/p/13032107.html
Copyright © 2020-2023  润新知