数据结构之单链表

单链表

 在单链表中我们会认识一个叫结点的东西,啥是结点呢,如下一个data域,一个next域,data域顾名思义是用来存储数据的(数据类型任意),next域这个就有说道了,这是一个指针域,首先它必须指向地址,其次这个地址还得是下一个结点的地址。
 n个结点连成一个链表,即为线性表的链式存储结构,由于此链表每个结点只包括一个指针域,所以叫做单链表,链表中第一个结点的存储位置叫做头指针

image.png
头插法:
头插法.gif
尾插法:
尾插法.gif

#include <stdio.h>
#include <stdlib.h>

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

//初始化头结点
Node *initList() {
    Node *list = (Node *) malloc(sizeof(Node));
    list->data = 0;
    list->next = NULL;
    return list;
}

//头插法
void headNode(Node *list, int data) {
    //创建新节点
    Node *node = (Node *) malloc(sizeof(Node));
    //将数据存入新节点
    node->data = data;
    //将list节点的指向放入新节点
    node->next = list->next;
    //重置list节点的指向
    list->next = node;
    //用头结点记录节点的个数
    list->data++;
}

//尾插法
void tailNode(Node *list, int data) {
    Node *head = list;
    //开辟新节点空间
    Node *node = (Node *) malloc(sizeof(Node));
    node->data = data;
    node->next = NULL;
    //如果不存在第二节点,则直接插在第一个后边
    if (list->next) {
        list = list->next;
    }
    //一直找,直到找到最后一个节点
    while (list->next) {
        list = list->next;
    }
    //把当前节点连接在后边
    list->next = node;
    //用头结点保存节点的个数
    head->data++;
}

//删除指定节点
int delNode(Node *list, int i) {
    Node *head = list;
    if (i > list->data) {
        printf("输入的索引不合法");
    }
    Node *p = list, *q;
    int j = 0;
    //找到要删的节点的前一个节点
    while (p->next && j < i - 1) {
        p = p->next;
        j++;
    }
    //被删节点等于q
    q = p->next;
    //让被删节点的前一个节点指向被删节点的下一个节点
    p->next = q->next;
    head->data--;
    int temp = q->data;
    free(q);
    return temp;
}

//返回节点个数
void printfNodeLength(Node *list) {
    printf("当前链表还有%d个节点", list->data);
}

//释放某个节点
void FreeList(Node *list) {
    free(list);
}

//销毁链表中每一个节点
void destroyList(Node *list) {
    Node *tempNode = list;
    while (tempNode->next) {
        free(tempNode);
        tempNode = tempNode->next;
    }
}

//清空节点,只保留头结点
void ClearList(Node *list) {
    Node *headNode = list;
    Node *p, *q = list->next;//被删节点
    while (q) {
        p = q->next;//被删节点的下一个
        free(q);//释放被删节点
        q = p;//
        headNode->data--;
        if (headNode->data == 0) {
            printf("当前链表已经已经清空,当前节点数为:%d\n", headNode->data);
            break;
        }
    }
}

//打印链表
void printList(Node *list) {
    list = list->next;
    while (list) {
        printf("%d->", list->data);
        list = list->next;
    }
    printf("NULL\n");
}

int main() {
    Node *list1 = initList();
    headNode(list1, 10);
    headNode(list1, 20);
    headNode(list1, 30);
    headNode(list1, 40);
    headNode(list1, 50);
    printf("头插法输出链表:");
    printList(list1);
    //清空list1
    ClearList(list1);

    printfNodeLength(list1);
    printf("\n");
    
    Node *list2 = initList();
    tailNode(list2, 100);
    tailNode(list2, 200);
    tailNode(list2, 300);
    tailNode(list2, 400);
    tailNode(list2, 500);
    printf("尾插法输出链表:");
    printList(list2);

    return 0;
}
输出结果:
头插法输出链表:50->40->30->20->10->NULL
当前链表已经已经清空,当前节点数为:0   
当前链表还有0个节点
尾插法输出链表:100->200->300->400->500->NULL
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱无盐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值