链表完整功能讲解(含各种功能函数代码)(功能代码模板做题快到飞)

链表类型我分为四种来讲:单链表单循环链表双链表双循环链表

单链表

定义介绍

单链表是由一系列节点(Node)组成的线性集合,每个节点包含两部分:

  1. 数据域(Node->data):存储实际的数据。
  2. 指针域(Node->next):存储下一个节点的地址。

链表中的最后一个节点指向 null (NULL)表示链表的结束。

为了使我们使用链表时更加方便,我个人喜欢定义一个头节点,在这个头节点里,第一个data的值是链表中数据储存的个数,地址指向我们储存的第一个结点的数据。

链表是环环相扣的,你要一个一个访问,只有访问到前一个链表才可以拿到“钥匙”(也就是下一个链表Node->data的地址)。理论上链表可以不断一个套下一个,可以无限长。

链表的本质

链表的本质是构建结构体,在这个结构体中含两种变量,一种是指针,一种是我们储存的数据

拿到链表题,我们要做的第一件事就是定义一个名为Node的结构体。

typedef struct Node
{
    int data;
    struct Node* next;
}Node;

这个结构体Node->data是我们储存数据,Node->next是下一个结点的地址。

创建单链表

Node* initlist()
{
    Node* list = (Node*)malloc(sizeof(Node));
    list -> data = 0;
    list -> next = NULL;
    return list;
}

这个代码首先定义一个类型为结构体Node的指针变量list,是list的结构特性能担当起链表的作用,我们首先要给他使用malloc函数动态分配一个Node类型大小的内存空间,并将其地址转换为Node*类型,赋值给指针变量list。

我们最初创建的结点什么都没有,所有我们要给其赋值,先给数据域赋值

list -> data = 0;

再给指针域赋值,由于我们是初始化一个链表,这是它的第一个结点,后面没有结点让他指向,所有它指向为空

list -> next = NULL;

最后返回指向初始化后的头节点的指针

return list;

头插法

void headInsert(Node* list,int data)
{
    Node* node = (Node*)malloc(sizeof(Node));
    node -> data = data;
    node -> next = list -> next;
    list -> next = node;
    list -> data++;
}

尾插法

void tailInsert(Node* list, int data)
{
    Node* head = list;
    Node* node = (Node*)malloc(sizeof(Node));
    node -> data = data;
    node -> next = NULL;
    list = list -> next;
    while(list->next)
    {
        list = list -> next;
    }
    list -> next = node;
    head -> data++;
}

 删除数据

void delete(Node* list,int data)
{
    Node* pre = list;
    Node* current = list -> next;
    while(current)
    {
        if(current -> data == data)
        {
            pre -> next = current -> next;
            free(current);
            break;
        }
        pre = current;
        current = current -> next;
    }
    list -> data--;
}

遍历打印每一个结点

void printList(Node* list)
{
    list = list -> next;
    while(list -> next)
    {
        printf("%d ",list -> data);
        list = list -> next;
    }
    printf("\n");
}

 测试案例

int main()
{
    Node* list = initlist();
    headInsert(list, 1);
    headInsert(list, 2);
    headInsert(list, 3);
    headInsert(list, 4);
    headInsert(list, 5);
    tailInsert(list, 6);
    tailInsert(list, 7);
    tailInsert(list, 8);
    tailInsert(list, 9);
    tailInsert(list, 10);
    printList(list);
    delete(list, 4);
    printList(list);
}

运行截图

 

单循环链表

定义结构体

typedef struct Node
{
    int data;
    struct Node* next;
}Node;

创建链表

Node* initList()
{
    Node* L = (Node*)malloc(sizeof(Node));
    L -> data = 0;
    L -> next = L;
    return L;
}

头插法 

void headInsert(Node* L, int data)
{
    Node* node = (Node*)malloc(sizeof(Node));
    node -> data = data;
    node -> next = L -> next;
    L -> next = node;
    L -> data ++;
}

尾插法

void tailInsert(Node* L, int data)
{
    Node* n = L;
    Node* node = (Node*)malloc(sizeof(Node));
    node -> data = data;
    while(n -> next != L)
    {
        n = n -> next;
    }
    node -> next = L;
    n -> next = node;
    L = n;
}

 删除数据

int delete(Node* L, int data)
{
    Node* preNode = L;
    Node* node = L -> next;
    while(node != L)
    {
        if(node -> data == data)
        {
            preNode -> next = node -> next;
            free(node);
            return 1;
        }
        preNode = node;
        node = node -> next;
    }
    return 0;
}

 遍历打印每一个结点

void printList(Node* L)
{
    Node* node = L -> next;
    while(node != L)
    {

        printf("%d->",node -> data);
        node = node -> next;
    }
    printf("NULL\n");
}

测试案例

int main()
{
    Node* L = initList();
    headInsert(L, 1);
    headInsert(L, 2);
    headInsert(L, 3);
    headInsert(L, 4);
    headInsert(L, 5);
    printList(L);
    tailInsert(L, 6);
    tailInsert(L, 7);
    tailInsert(L, 8);
    tailInsert(L, 9);
    printList(L);
    delete(L, 3);
    printList(L);
}

运行截图

双链表

定义结构体

typedef struct Node
{
    int data;
    struct Node* pre;
    struct Node* next;
}Node;

创建链表

Node* initList()
{
    Node* L = (Node*)malloc(sizeof(Node));
    L -> data = 0;
    L -> pre = NULL;
    L -> next = NULL;
    return L;
}

 头插法

void headInsert(Node* L, int data)
{
    Node* node = (Node*)malloc(sizeof(Node));
    node -> data = data;
    if(L -> data == 0)
    {
        node -> next = NULL;
        node -> pre = L;
        L -> next = node;
        L -> data++;
    }
    else
    {
        node -> pre = L;
        node -> next = L -> next;
        L -> next -> pre = node;
        L -> next = node;
        L -> data++;
    }
}

尾插法

void tailInsert(Node* L, int data)
{
    Node* node = L;
    Node* n = (Node*)malloc(sizeof(Node));
    n -> data = data;
    n -> next = NULL;
    while(node -> next)
    {
        node = node -> next;
    }
    node -> next = n;
    n -> pre = node;
    L -> data++;
}

 删除数据

int delete(Node* L, int data)
{
    Node* node = L -> next;
    while(node)
    {
        if(node -> data == data)
        {
            node -> pre -> next = node -> next;
            node -> next -> pre = node -> pre;
            free(node);
            return 1;
        }
        node = node -> next;
    }
    return 0;
}

遍历打印各节点

void printList(Node* L)
{
    Node* node = L -> next;
    while(node)
    {
        printf("%d -> ",node -> data);
        node = node -> next;
    }
    printf("NULL\n");
}

 测试代码

int main()
{
    Node* L =initList(L);
    headInsert(L, 1);
    headInsert(L, 2);
    headInsert(L, 3);
    headInsert(L, 4);
    tailInsert(L, 5);
    tailInsert(L, 6);
    printList(L);
    delete(L, 3);
    printList(L);
}

运行截图 

双循环链表

定义结构体

typedef struct Node
{
    int data;
    struct Node* pre;
    struct Node* next;
}Node;

创建链表

Node* initList()
{
    Node* L = (Node*)malloc(sizeof(Node));
    L -> data = 0;
    L -> pre = L;
    L -> next = L;
    return L;
}

头插法

void headInsert(Node* L, int data)
{
    Node* node = (Node*)malloc(sizeof(Node));
    node -> data = data;
    if(L -> data == 0)
    {
        node -> pre = L;
        node -> next = L;
        L -> next = node;
        L -> pre = node;
        L -> data++;
    }
    else
    {
        node -> next = L -> next;
        node -> pre = L;
        L -> next -> pre = node;
        L -> next = node;
        L -> data++;
    }
}

尾插法

void tailInsert(Node* L, int data)
{
    Node* node = L;
    while(node -> next != L)
    {
        node = node -> next;
    }
    Node* n = (Node*)malloc(sizeof(Node));
    n -> data = data;
    n -> pre = node;
    n -> next = L;
    node -> next = n;
    L -> pre = n;
    L -> data++;
}

删除数据

int delect(Node* L, int data)
{
    Node* node = L -> next;
    while(node != L)
    {
        if(node -> data == data)
        {
            node -> pre -> next = node -> next;
            node -> next -> pre = node -> pre;
            free(node);
            L -> data--;
            return 1;
        }
        node = node -> next;
    }
    return 0;
}

遍历打印各节点

void printList(Node* L)
{
    Node* node = L -> next;
    while(node != L)
    {
        printf("%d ",node -> data);
        node = node -> next;
    }
    printf("NULL\n");
}

测试案例

int main()
{
    Node* L = initList(L);
    headInsert(L, 1);
    headInsert(L, 2);
    headInsert(L, 3);
    printList(L);
    tailInsert(L, 4);
    tailInsert(L, 5);
    tailInsert(L, 6);
    tailInsert(L, 7);
    printList(L);
    delect(L, 3);
    printList(L);

}

运行截图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值