数据结构 -- 链表&双向链表

Posted peterz1997

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构 -- 链表&双向链表相关的知识,希望对你有一定的参考价值。

        链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。


        使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。链表最明显的好处就是,常规数组排列关联项目的方式可能不同于这些数据项目在记忆体或磁盘上顺序,数据的存取往往要在不同的排列顺序中转换。链表允许插入和移除表上任意位置上的节点,但是不允许随机存取。链表有很多种不同的类型:单向链表,双向链表以及循环链表等。


        相较之于单链表,双向链表在查找前驱节点时更为方便,而单向链表却需要遍历查找;而相较之于双向链表,单链表在更加节省内存空间(双向链表比单链表多定义了一个指向前驱结点的指针)。


        以下为关于单链表以及双向链表的c++实现方法:


        1. 单链表

#include <cstdio>
#include <cstdlib>
#include <iostream>

using namespace std;

typedef struct linkTable{
    int info;
    linkTable *next;
};

//创建链表

linkTable* createLinkTable(linkTable *node)
{
    int temp = 0;
    linkTable *head = NULL;
    linkTable *p = (linkTable*)malloc(sizeof(linkTable));
    while (1)
    {
        scanf("%d",&temp);
        if (temp != -9999)
        {
            if (head == NULL)
            {
                p->info = temp;
                p->next = NULL;
                head = p;
            }else{
                linkTable *newnode = (linkTable *)malloc(sizeof(linkTable));
                newnode->info = temp;
                newnode->next = NULL;
                p->next = newnode;
                p = p->next;
            }
        }else{
            break;
        }
    }
    return head;

}

//在链表头部插入节点

linkTable* insertToHead(linkTable *node , int val)
{
    linkTable *newnode = (linkTable*)malloc(sizeof(linkTable));
    scanf("%d",newnode->info);
    newnode->next = node;
    return newnode;
}

//在链表中间插入节点

void insertToMid(linkTable *node , int val , int pos)
{
    int count = 0;
    linkTable *newnode = (linkTable*)malloc(sizeof(linkTable));
    newnode->info = val;
    while (node->next != NULL && ++count < pos-1)
    {
        node = node->next;
    }
    newnode->next = node->next;
    node->next = newnode;
    return;
}

//插入尾部节点

void insertToTail(linkTable *node , int val)
{
    linkTable *newnode = (linkTable*)malloc(sizeof(linkTable));
    newnode->info = val;
    newnode->next = NULL;
    while (node->next != 0)
    {
        node = node->next;
    }
    node->next = newnode;
    return;
}

//显示所有节点数值

void display(linkTable *node)
{
    while (node != NULL)
    {
        printf("%d ",node->info);
        node = node->next;
    }
    return;
}

//删除起始节点

linkTable* deleteHead(linkTable *node)
{
    linkTable *tempNode = (linkTable*)malloc(sizeof(linkTable));
    tempNode = node;
    node = node->next;
    free(tempNode);
    return node;
}

//删除尾部节点

void deleteTail(linkTable *node)
{
    linkTable *tempNode = (linkTable*)malloc(sizeof(linkTable));
    while (node->next->next != NULL && node->next != NULL)
    {
        node = node->next;
    }
    tempNode = node->next;
    node->next = NULL;
    free(tempNode);
    return;
}

//搜索指定节点,并返回节点

linkTable* searchNode(linkTable *node , int val)
{
    while (node->info != val)
    {
        if (node == NULL)
        {
            printf("No element ! 
");
            return NULL;
        }
        node = node->next;
    }
    return node;
}

int main(void)
{
    linkTable *node = (linkTable*)malloc(sizeof(linkTable));
    node = createLinkTable(node);
    display(node);
    return 0;
}



        2. 双向链表

#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cmath>

using namespace std;

typedef struct DLinkList{
    int info;
    DLinkList *prev;
    DLinkList *next;
};

//链表的创建

DLinkList* createDLT(void)
{
    int temp = 0;
    DLinkList *p = (DLinkList*)malloc(sizeof(DLinkList));
    DLinkList *head = NULL;
    while (1)
    {
        scanf("%d",&temp);
        if (temp != -9999)
        {
            if (head == NULL)
            {
                head = (DLinkList*)malloc(sizeof(DLinkList));
                p->info = temp;
                p->next = NULL;
                p->prev = NULL;
                head = p;
            }else{
                DLinkList *newnode = (DLinkList*)malloc(sizeof(DLinkList));
                newnode->info = temp;
                newnode->prev = p;
                newnode->next = NULL;
                p->next = newnode;
                p = p->next;
            }
        }else{
            break;
        }
    }
    return head;
}

//链表的遍历输出

void display(DLinkList *node)
{
    while (node != NULL)
    {
        printf("%d  ",node->info);
        node = node->next;
    }
    return;
}

//添加链表头节点

DLinkList* insert_Head(DLinkList *node , int val)
{
    DLinkList *newnode = (DLinkList*)malloc(sizeof(DLinkList));
    newnode->info = val;
    newnode->next = node;
    newnode->prev = NULL;
    node->prev = newnode;
    return newnode;
}

//删除链表某位置元素

void delete_Elem(DLinkList *node , int n)
{
    int count = 1;
    while (count < n && node != NULL)
    {
        node = node->next;
        count++;
    }
    if (node != NULL)
    {
        if (node->next != NULL)
        {
            node->prev->next = node->next;
            node->next->prev = node->prev;
        }else{
            node->prev->next = NULL;
        }
    }
    return;
}

int main(void)
{
    DLinkList *node = (DLinkList*)malloc(sizeof(DLinkList));
    node = createDLT();
    node = insert_Head(node,9);
    delete_Elem(node,2);
    display(node);
    return 0;
}


















以上是关于数据结构 -- 链表&双向链表的主要内容,如果未能解决你的问题,请参考以下文章

数据结构循环链表&&双向链表详解和代码实例

数据结构-双向链表&双向循环链表

数据结构 -- 链表&双向链表

双向链表<一>

[leetcode] 432. 全 O 的数据结构 | STL 双向链表&哈希

线性表:双向链表