链表基本概念

目录

一、链表

二、链表的分类

2.1 链表分为:静态链表和动态链表

2.2  带头和不带头链表

2.3  单向链表、双向链表、循环链表

三、链表总结



一、链表

  1. 链表是一种常用的数据结构,它通过指针将一些列数据结点,连接成一个数据链。相对于数组,链表具有更好的动态性
  2. 数据域用来存储数据,指针域用于建立与下一个结点的联系。

 数组和链表的区别:

数组:一次性分配一块连续的存储区域。

优点:随机访问元素效率高

缺点:1) 需要分配一块连续的存储区域(很大区域,有可能分配失败)

      2) 删除和插入某个元素效率低

链表:无需一次性分配一块连续的存储区域,只需分配n块节点存储区域,通过指针建立关系。

优点:1) 不需要一块连续的存储区域

  2) 删除和插入某个元素效率高

缺点:随机访问元素效率低

二、链表的分类

2.1 链表分为:静态链表和动态链表

  1. 所有结点都是在程序中定义的,不是临时开辟的,也不能用完后释放,这种链表称为“静态链表”。
  2. 所谓动态链表,是指在程序执行过程中从无到有地建立起一个链表,即一个一个地开辟结点和输入各结点数据,并建立起前后相链的关系。

 静态链表

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

//节点的结构体
struct LinkNode
{
	int num; //数据域
	struct LinkNode * next; //指针域
};

void test01()
{
	//创建节点
	struct LinkNode node1 = { 10, NULL };
	struct LinkNode node2 = { 20, NULL };
	struct LinkNode node3 = { 30, NULL };
	struct LinkNode node4 = { 40, NULL };
	struct LinkNode node5 = { 50, NULL };

	//建立关系
	node1.next = &node2;
	node2.next = &node3;
	node3.next = &node4;
	node4.next = &node5;

	//遍历链表
	struct LinkNode * pCurrent = &node1;

	while (pCurrent != NULL)
	{
		printf("%d\n", pCurrent->num);
		pCurrent = pCurrent->next;
	}
}

int main(){
	test01();
	system("pause");
	return EXIT_SUCCESS;
}

动态链表

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

struct LinkNode
{
	int num;
	struct LinkNode * next;
};

void test01()
{
	//创建节点
	struct LinkNode * node1 = malloc(sizeof(struct LinkNode));
	struct LinkNode * node2 = malloc(sizeof(struct LinkNode));
	struct LinkNode * node3 = malloc(sizeof(struct LinkNode));
	struct LinkNode * node4 = malloc(sizeof(struct LinkNode));
	struct LinkNode * node5 = malloc(sizeof(struct LinkNode));

	//给数据域赋值
	node1->num = 100;
	node2->num = 200;
	node3->num = 300;
	node4->num = 400;
	node5->num = 500;

	//建立关系
	node1->next = node2;
	node2->next = node3;
	node3->next = node4;
	node4->next = node5;
	node5->next = NULL;

	//遍历链表
	struct LinkNode * pCurrent = node1;
	while (pCurrent!=NULL)
	{
		printf("%d\n", pCurrent->num);
		pCurrent = pCurrent->next;
	}

	free(node1);
	free(node2);
	free(node3);
	free(node4);
	free(node5);
	node1 = NULL;
	node2 = NULL;
	node3 = NULL;
	node4 = NULL;
	node5 = NULL;
}

int main(){
	test01();
	system("pause");
	return EXIT_SUCCESS;
}

2.2  带头和不带头链表

带头链表固定一个节点作为头结点(数据域不保存有效数据),起一个标志位的作用,不管链表节点如果改变,此头结点固定不变

不带头链表:头结点不固定,根据实际需要变换头结点(如在原来头结点前插入新节点,新节点重新作为链表的头结点)。

2.3  单向链表、双向链表、循环链表

   单向链表:

åé¾è¡¨ç»æå¾

  • 单链表有两个特殊的结点,分别是第一个结点——头结点和最后一个结点——尾结点。
    • 头结点:用来记录链表的基地址。
    • 尾结点:尾结点的后继指针指向一个空地址NULL。

 双向链表 

ååé¾è¡¨ç»æå¾

  • 单链表和双向链表的区别
    • 单链表的结点只有一个指向,即后继指针next指向下一个结点。
    • 双向链表的结点有两个指向,一个后继指针next指向下一个结点,还有一个前驱指针prev指向上一个结点

 循环链表 

循ç¯é¾è¡¨ç»æå¾

  循环链表的尾结点不指向空,而是指向头结点,类似一个环形结构。


三、链表总结

  • 由于链表的内存空间是零散的,所以不支持随机访问。
  • 插入、删除不需要移动数据,所以效率高。
  • 因为链表的每个内存块都不是连续的,所以不需要提前计算内存的大小,内存空间可以根据结点数量的改变而改变。

推荐一个不错的学习网站 C/C++后台高级服务器 https://ke.qq.com/course/417774?flowToken=1010783icon-default.png?t=M85Bhttps://ke.qq.com/course/417774?flowToken=1010783

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值