数据结构---双链表基础知识

双向链表

维基百科

双向链表,又称为双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。

头插法入结点图解

在这里插入图片描述

一、定义链表结点结构体

头文件

#include <stdio.h>
#include <stdlib.h>//提供malloc()原型
#include <string.h>//提供memset()原型

结构体(定义别名方便书写)

typedef struct Double_List_Node{
    int data;//数据域
    struct Double_List_Node *next;//指针域
    struct Double_List_Node *prev;
}L;

二、创建链表(头结点)

L *create_List()
{
    L *head_Node = (L *)malloc(sizeof(L));
    memset(head_Node, 0, sizeof(L));
    head_Node->next = NULL;
    head_Node->prev = NULL;
    return head_Node;
}

三、创建新结点

L *create_Node(int Data)
{
    L *new_Node = (L *)malloc(sizeof(L));
    memset(new_Node, 0, sizeof(L));
    new_Node->data = Data;
    new_Node->next = NULL;
    new_Node->prev = NULL;
    return new_Node;
}

四、头插法插入结点

void top_insert(L *head_Node, L *new_Node)
{
    new_Node->next = head_Node->next;
    if(head_Node->next != NULL){
        head_Node->next->prev = new_Node;
    }
    new_Node->prev = head_Node;
    head_Node->next = new_Node;
}

五、尾插法插入结点

void tail_insert(L *head_Node, L *new_Node)
{
    while(head_Node->next != NULL){
        head_Node = head_Node->next;//找到链表中的最后一个结点
    }
    new_Node->prev = head_Node;
    head_Node->next = new_Node; 
}

六、删除结点

int delete_Node(L *head_Node, int Data)
{
    while(head_Node->next != NULL){
        head_Node = head_Node->next;
        if(head_Node->data == Data)//找到要删除的结点了!
        {
            if(head_Node->next == NULL)//要删除的结点是最后一个
            {
                head_Node->prev->next = NULL;
                free(head_Node);
            }
            else//要删除的结点不是最后一个
            {
                head_Node->prev->next = head_Node->next;
                head_Node->next->prev = head_Node->prev;
                free(head_Node);
            }
            return 0;
        }
    }
    printf("没有找到要删除的结点!\n");
    return -1;
}

七、打印链表

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

八、逆序打印链表

void rev_Print_List(L *head_Node){
    while(head_Node->next != NULL){
        head_Node = head_Node->next;//找到最后一个结点
    }
    while(head_Node->prev != NULL){
        printf("%d ", head_Node->data);
        head_Node = head_Node->prev;//从最后一个结点开始遍历
    }
    printf("\n");
}

加入主函数进行测试

#include <stdio.h>
#include <stdlib.h>//提供malloc()原型
#include <string.h>//提供memset()原型

typedef struct Double_List_Node{
    int data;//数据域
    struct Double_List_Node *next;//指针域
    struct Double_List_Node *prev;
}L;

//创建链表
L *create_List()
{
    L *head_Node = (L *)malloc(sizeof(L));
    memset(head_Node, 0, sizeof(L));
    head_Node->next = NULL;
    head_Node->prev = NULL;
    return head_Node;
}

//创建链表结点
L *create_Node(int Data)
{
    L *new_Node = (L *)malloc(sizeof(L));
    memset(new_Node, 0, sizeof(L));
    new_Node->data = Data;
    new_Node->next = NULL;
    new_Node->prev = NULL;
    return new_Node;
}

//头插法
void top_insert(L *head_Node, L *new_Node)
{
    new_Node->next = head_Node->next;
    if(head_Node->next != NULL){
        head_Node->next->prev = new_Node;
    }
    new_Node->prev = head_Node;
    head_Node->next = new_Node;
}

//尾插法
void tail_insert(L *head_Node, L *new_Node)
{
    while(head_Node->next != NULL){
        head_Node = head_Node->next;//找到链表中的最后一个结点
    }
    new_Node->prev = head_Node;
    head_Node->next = new_Node; 
}

//打印链表
void print_List(L *head_Node)
{
    while(head_Node->next != NULL){
        head_Node = head_Node->next;
        printf("%d ", head_Node->data);
    }
    printf("\n");
}

//逆序打印
void rev_Print_List(L *head_Node){
    while(head_Node->next != NULL){
        head_Node = head_Node->next;
    }
    while(head_Node->prev != NULL){
        printf("%d ", head_Node->data);
        head_Node = head_Node->prev;
    }
    printf("\n");
}

//删除结点
int delete_Node(L *head_Node, int Data)
{
    while(head_Node->next != NULL){
        head_Node = head_Node->next;
        if(head_Node->data == Data)//找到要删除的结点了!
        {
            if(head_Node->next == NULL)//要删除的结点是最后一个
            {
                head_Node->prev->next = NULL;
                free(head_Node);
            }
            else//要删除的结点不熟最后一个
            {
                head_Node->prev->next = head_Node->next;
                head_Node->next->prev = head_Node->prev;
                free(head_Node);
            }
            return 0;
        }
    }
    printf("没有找到要删除的结点!\n");
    return -1;
}

int main()
{
    L *list = create_List();
    top_insert(list, create_Node(10));
    top_insert(list, create_Node(20));
    top_insert(list, create_Node(30));
    tail_insert(list, create_Node(10));
    tail_insert(list, create_Node(20));
    tail_insert(list, create_Node(30));
    delete_Node(list, 30);
    delete_Node(list, 20);
    print_List(list);
    rev_Print_List(list);
    free(list);
    return 0;
}
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值