服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C语言链表与单链表详解

C语言链表与单链表详解

2022-09-16 14:22诚挚的乔治 C/C++

链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的,本章带你详细了解链表与单链表

链表是什么及链表的优势

链表是一种介于数组的另外一种数据结构:

我们知道数组可以存放很多的元素,这些元素都是呈线性排列,也就是一个挨着一个连续存放

但是当元素足够多时,还能继续正常的存放吗?

事实上的不可以的,虽然系统的内存足够大,但是这些内存不都是连续的,这就导致会出现没有足够的空间去存储这些元素。

其次就是数组的大小需要你去申请,如果你申请的空间足够大,就会导致内存的浪费

而链表就很好的解决了这两个问题 

链表的组成

链表的作用就是相当与数组一样,储存你数据的

但又不同于数组,链表把每一个游离的数据进行连接,连接的方法通过的是指针,也就是地址,

每一个链表都是由一个个结点组成,结点包含,一个是为我们存放数据的空间,另一个是存放下一个结点地址的空间,也就是所谓的数据域和地址域。

C语言链表与单链表详解

链表有时候包括了头结点,它是为了方便而设计的结点,这个头结点一般只包含地址域,也就是结点1的地址,一般情况下,头结点的数据域一般无意义。

最后的结点,指向的是NULL,用来限制链表的大小

单向链表结点的定义

说完链表的组成是结点,那单向链表的结点是如何定义的呢

?
1
2
3
4
5
6
7
8
9
struct  Node  //链表的结点
 
{
 
             int data;                   //结点的值
 
             struct Node  *next;    //下一个结点的地址
 
};

单项链表的创建

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//创建所需的结点
struct Node* createList(int n)
{
    struct Node* first, * t, * last; int i;
    first = (struct Node*)malloc(sizeof(struct Node));
    //给第一个结点数据赋个值
    scanf_s("%d", &first->data);
    last = first ;
    //在创建其他的结点
    for (i = n - 1; i > 0; i--)
    {
        //再首尾中间插入结点.并赋值
        t= (struct Node*)malloc(sizeof(struct Node));
        scanf_s("%d", &t->data);
        last->next = t;
        last=t;
    }
    last->next = NULL;//防止野指针的存在
    return first;
}

其中的first,last,还有t,都是指针变量,用来存放各个节点的地址

sizeof(struct listnode)函数返回结构体Node类型占用的字节数

malloc(sizeof(struct Node))函数功能:系统从内存的空闲空间中,申请存放一个结点的存储空间。

(struct listnode *)malloc(sizeof(struct Node)),函数返回一个指针(地址),指向刚分配给结构体的第一个字节的地址。

malloc函数在头文件stdlib.h中定义 

打印出链表各个结点的数据

?
1
2
3
4
5
6
7
8
9
10
11
12
//再创建函数进行打印出各个结点的值
void printList(struct Node* first)
{
    //把每一个字节数据域的都打印出来
    struct Node* p = first;
    while (p != NULL)
    {
        printf("%d ", p->data);
        p = p->next;
    }
    printf("\n");
}

其中传入函数的是结构体指针

从第一个结点的数据域开始打印,到最后的NULL结束

(访问下一个数据域不能用p++,因为链表不是连续的,地址也不是连续的,如果要访问下一个数据,需要用p = p->next)

释放向系统申请的空间

?
1
2
3
4
5
6
7
8
9
10
11
void destoryList(struct Node* first)
{
    struct Node* p = first, *tmp;
 
    while (p != NULL)
    {
        tmp = p->next;
        free(p);
        p = tmp;
    }
}

这里的 struct Node* p = first, *tmp;

就相当于 struct Node*p=first;

              struct Node *tmp;

例题

从键盘输入一组整数,创建单向链表,并输出链表中的数据。

样例输入:2  5  7  6  3  4

样例输出:2  5  7  6  3  4   

 解答如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include<stdio.h>
#include<stdlib.h>
#define N 6
//链表
struct Node
{
    int data;
    struct Node* next;
};
//创建所需的结点
struct Node* createList(int n)
{
    struct Node* first, * t, * last; int i;
    first = (struct Node*)malloc(sizeof(struct Node));
    //给第一个结点数据赋个值
    scanf_s("%d", &first->data);
    last = first ;
    //在创建其他的结点
    for (i = n - 1; i > 0; i--)
    {
        //再首尾中间插入结点.并赋值
        t= (struct Node*)malloc(sizeof(struct Node));
        scanf_s("%d", &t->data);
        last->next = t;
        last=t;
    }
    last->next = NULL;//防止野指针的存在
    return first;
}
//再创建函数进行打印出各个结点的值
void printList(struct Node* first)
{
    //把每一个字节数据域的都打印出来
    struct Node* p = first;
    while (p != NULL)
    {
        printf("%d ", p->data);
        p = p->next;
    }
    printf("\n");
}
//释放头结点申请的空间
void destoryList(struct Node* first)
{
    struct Node* p = first, *tmp;
 
    while (p != NULL)
    {
        tmp = p->next;
        free(p);
        p = tmp;
    }
}
 
 
 
int main()
{
    struct Node* list;
    list = createList(N);
    printList(list);//输出头节点为list的链表   、、、、、、
    destoryList(list);
    printf("\n");
    return 0;
}

到此这篇关于C语言链表与单链表详解的文章就介绍到这了,更多相关C语言 链表内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://z-ming.blog.csdn.net/article/details/122400440

延伸 · 阅读

精彩推荐
  • C/C++C++对数组的引用实例分析

    C++对数组的引用实例分析

    这篇文章主要介绍了C++对数组的引用实例分析,需要的朋友可以参考下...

    C++教程网11672021-01-28
  • C/C++深入理解atoi()与itoa()函数的用法

    深入理解atoi()与itoa()函数的用法

    本篇文章是对atoi()与itoa()函数的用法进行了详细的分析介绍,需要的朋友参考下...

    C语言教程网2652020-12-06
  • C/C++c++中引用和指针的区别和联系

    c++中引用和指针的区别和联系

    许多人对于引用和指针的区别与联系很纠结(包括我在内O(∩_∩)O哈哈~),最近看到一篇关于引用和指针区别和联系的文章,感觉茅塞顿开,在这里和大家...

    C++教程网9022021-01-19
  • C/C++Windows下VScode实现简单回声服务的方法

    Windows下VScode实现简单回声服务的方法

    回声服务端可以将客户端传来的信息,再原封不动地发送给客户端,因而得名 epoch 服务。接下来通过本文给大家介绍Windows下VScode实现简单回声服务的方法...

    star_function10632021-12-15
  • C/C++C语言实现学生信息管理系统(多文件)

    C语言实现学生信息管理系统(多文件)

    这篇文章主要为大家详细介绍了C语言实现学生信息管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    零商5902021-10-16
  • C/C++实现posix消息队列示例分享

    实现posix消息队列示例分享

    这篇文章主要介绍了实现posix消息队列示例,学习记录锁,线程互斥量,线程条件变量,内存映射,信号,线程的综合应用,需要的朋友可以参考下...

    C语言教程网8062021-01-15
  • C/C++C语言实现简易计算器功能

    C语言实现简易计算器功能

    这篇文章主要为大家详细介绍了C语言实现简易计算器功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    owen-li12032022-09-08
  • C/C++C语言小程序 如何判断两个日期之差

    C语言小程序 如何判断两个日期之差

    输入两个日期,计算之间相差多少天。 用了两种方法实现,第二种利用结构体,代码比较清晰,其余的都一样...

    C语言教程网2092020-12-19