通俗易懂C语言--链表

相信了解了结构体,指针,结构体指针的,对于链表也能比较容易的理解,我觉得该怎么去容易理解呢,不仅要看代码,而且还要自己亲自写一下代码,并输出结果,理解其中的每一步。

 什么是链表

我觉得看懂这两段话就行:

链表是可以用如何排列你的数据的一种数据结构,相对于数组(array)链表有两个明显的优点:

  1. 链表可以随时改变大小(数据的多少),而数组的大小一旦在声明的时候定义了就不能被改变
  2. 在链表里面排序是非常简单的,而在数组里面如果想要插入新的元素或者移动一个元素,我们需要的statement会很多,也会浪费很多的时间

数据是不定长的,在存储第一个数据之前难以确定一个将来一共需要存储多少数据的上限,或者虽然可以确定上限,但这个上限又比通常大部分情况下数据可能达到的长度要大得多,因而一次性按照上限把空间分配好是不划算的。而链表则可以在每次需要增加新数据时才为之申请内存,不会造成浪费,也不会因一次申请不足而使数据的数量受到限制。

链表你不一定经常使用,但是代码一定要看得懂

静态链表

静态链表不怎么用,但是可以很好的理解什么是链表,看一段代码:

#include <stdio.h>

// 定义链表节点
typedef struct node{
    int num;
    struct node *next;
}Node;
int main()
{
	//创建三个链表节点,实际就是三个结构体
	Node a;
    Node b;
	Node c;

	//初始化节点数据
	a.num=1;
	b.num=2;
	c.num=3;

	//将它们链接起来,链表有首有尾
	Node *head=&a;
	a.next=&b;
	b.next=&c;
	//c的后面没有了
	c.next=NULL;

    while(head != NULL){//判断是否有数据
        int data = head->num;
        printf("data = %i\n", data);
        head = head->next;//进入下一个节点
    }
    return 0;
}

输出结果:

data = 1
data = 2
data = 3

看完静态链表就能初步理解什么是链表了,下面主要看一下什么是动态链表

动态链表

空链表

头指针带了一个空链表节点, 空链表节点中的next指向NUL

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

// 定义链表节点
typedef struct node{
    int num;
    struct node *next;
}Node;

Node *CreateEmptyList(){//这是什么:返回类型为Node的指针函数
 
      Node *a=(Node *)malloc(sizeof(Node));//这什么意思:创建一个结构体指针,并分配内存,下面的内容就很熟悉了
	  if(a !=NULL){
	      a->next=NULL;//其实就是创建一个指向空的节点
		return a;	  
	  }
}
int main()
{
    Node *head=CreateEmptyList();//这个是不是就像静态链表中的Node *head=&a;
    return 0;
}

非空链表

动态链表头插法

头指针带了一个非空节点, 最后一个节点中的next指向NULL

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

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

Node *createList();

void printNodeList(Node *node);
int main()
{
    Node *head = createList();
    printNodeList(head);
    return 0;
}

Node *createList(){
    // 1.创建头节点
    Node *head = (Node *)malloc(sizeof(Node));
    if(head == NULL){
        return NULL;
    }
    head->next = NULL;//这是什么意思:实际就是建了一个空链表,咱们要往里面见缝插针

    // 2.接收用户输入数据
    int num = -1;
    printf("请输入节点数据\n");
    scanf("%i", &num);//假设输入1

    // 3.通过循环创建其它节点
    while(num != -1){
        // 3.1创建一个新的节点
        Node *cur = (Node *)malloc(sizeof(Node));
        cur->data = num;//这个就等于1

        // 3.2让新节点的下一个节点指向头节点的下一个节点
        cur->next = head->next;//有没有发现,这个cur->next=NULL,意味着它是链尾
        // 3.3让头节点的下一个节点指向新节点
        head->next = cur;//这又是什么意思,就是说倒数第二个节点,也就是链尾的前一个节点

        // 3.4再次接收用户输入数据
        scanf("%i", &num);//咱们再输入2,最后输出-1
    }

    // 3.返回创建好的节点
    return head;//这个循环已经建立好了链表,你输出这个head就行,咱们根据这个头去找数据
}
/**
 * @brief printNodeList 遍历链表
 * @param node 链表指针头
 */
void printNodeList(Node *node){
    Node *head = node->next;
    while(head != NULL){
        int currentData = head->data;
        printf("currentData = %i\n", currentData);
        head = head->next;
    }
}
//假如我输入1,2,3,4
//那么它的输出结果将会是什么呢
//currentData =4
//currentData =3
//currentData =2
//currentData =1

从结果看出来,每插入一个数是不是这个数在上一个数的前面,这个就是头插法

如果插入尾部,就是输入1,2,3,4,输出还是1,2,3,4。

 Node *pre = head;
    while(num != -1){
        // 3.1创建一个新的节点
        Node *cur = (Node *)malloc(sizeof(Node));
        cur->data = num;

        // 3.2让新节点链接到上一个节点后面
        pre->next = cur;
        // 3.3当前节点下一个节点等于NULL
        cur->next = NULL;
        // 3.4让当前节点编程下一个节点的上一个节点
        pre = cur;

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值