数据结构-单链表

🌈个人主页: 会编辑的果子君

💫个人格言:"成为自己未来的主人~"

顺序表的问题和思考

中间/头部的插入删除,时间复杂度为O(N)

增容需要申请新空间,拷贝数据,释放旧空间,会有不小的消耗

增容一般是呈2倍的增长,势必会有一定的空间浪费,例如当前容量为100,满了以后增容到200,但是我们只插入了五个数据,后面就没有数据插入了,那么就浪费了95个数据空间。

那,我们应该如何解决上面的问题呢?

是否存在一种数据结构,能够解决以上顺序表表现出来的问题,

中间/头部的插入删除,可以一步到位,不需要挪动数据

不需要扩容

不会造成空间浪费

当然有,这就是链表

链表和顺序表都是线性表

线性表的逻辑结构一定是线性的,物理结构不一定是线性的,

而链表,物理结构一定不是线性的

链表是由一个一个的节点(结点)组成的。

一个节点由两个部分组成:要存储的数据+指针(结构体指针)

cpp 复制代码
struct SListNode {
	int data;
	struct SListNode* next;
};

这个就是节点结构的定义

cpp 复制代码
typedef int SLDataType;
typedef struct SListNode {
	SLDataType data;
	struct SListNode* next;
}SLTNode;

//typedef struct SListNode SLTNode;

链表的打印:

cpp 复制代码
#include"SList.h"
void SLTPrint(SLTNode* phead) {
	SLTNode* pcur = phead;
	while (pcur) {
		printf("%d->", pcur->data);
		pcur = pcur->next;
	}
	printf("NULL\n");
}
cpp 复制代码
void SListTest01() {
	//一般不会这样去创建链表,这里只是为了更好的给大家展示打印的过程
	SLTNode* node1 = (SLTNode*)malloc(sizeof(SLTNode));
	node1->data = 1;
	SLTNode* node2 = (SLTNode*)malloc(sizeof(SLTNode));
	node1->data = 2;
	SLTNode* node3 = (SLTNode*)malloc(sizeof(SLTNode));
	node1->data = 3;
	SLTNode* node4 = (SLTNode*)malloc(sizeof(SLTNode));
	node1->data = 4;

	node1->next = node2;
	node2->next = node3;
	node3->next = node4;
	node4->next = NULL;
	SLTNode* plist = node1;
	SLTPrint(plist);
}
cpp 复制代码
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int SLDataType;
typedef struct SListNode {
	SLDataType data;
	struct SListNode* next;
}SLTNode;

//typedef struct SListNode SLTNode;

void SLTPrint(SLTNode* phead);

//链表的头插,尾插
void SLTPushBack(SLTNode** phead, SLDataType x);
void SLTPushFront(SLTNode** phead, SLDataType x);

//链表的头删,尾删
void SLTPopBack(SLTNode** pphead);
void SLTPopFront(SLTNode** pphead);
cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include"SList.h"
//节点结构的定义
//struct SListNode {
//	int data;
//	struct SListNode* next;
//};

void SListTest01() {
	//一般不会这样去创建链表,这里只是为了更好的给大家展示打印的过程
	SLTNode* node1 = (SLTNode*)malloc(sizeof(SLTNode));
	node1->data = 1;
	SLTNode* node2 = (SLTNode*)malloc(sizeof(SLTNode));
	node2->data = 2;
	SLTNode* node3 = (SLTNode*)malloc(sizeof(SLTNode));
	node3->data = 3;
	SLTNode* node4 = (SLTNode*)malloc(sizeof(SLTNode));
	node4->data = 4;

	node1->next = node2;
	node2->next = node3;
	node3->next = node4;
	node4->next = NULL;
	SLTNode* plist = node1;
	SLTPrint(plist);
}

void SLIstTest02() {
	SLTNode* plist = NULL;
	SLTPushBack(&plist, 1);
	SLTPushBack(&plist, 2);
	SLTPushBack(&plist, 3);
	SLTPushBack(&plist, 4);
	SLTPrint(plist); //1->2->3->4->NULL

}

int main()
{
	//SListTest01();
	SLIstTest02();
	return 0;
}
cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include"SList.h"
void SLTPrint(SLTNode* phead) {
	SLTNode* pcur = phead;
	while (pcur) {
		printf("%d->", pcur->data);
		pcur = pcur->next;
	}
	printf("NULL\n");
}

SLTNode* SLTBuyNode(SLDataType x) {
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
	newnode->data = x;
	newnode->next = NULL;
	return newnode;
}


void SLTPushBack(SLTNode** pphead, SLDataType x) {
	assert(pphead);
	SLTNode* newnode = SLTBuyNode(x);
	//链表为空,新节点作为phead
	if (*pphead = NULL) {
		*pphead = newnode;
		return;
	}
	//链表不为空,找尾节点
	SLTNode* ptail = *pphead;
	while (ptail->next) {
		ptail = ptail->next;
	}
	//ptail就是尾节点
	ptail->next = newnode;
}
void SLTPushFront(SLTNode** pphead, SLDataType x) {
	assert(pphead);
	SLTNode* newnode = SLTBuyNode(x);

	newnode->next = *pphead;
	*pphead = newnode;
}
void SLTPopBack(SLTNode** pphead) {
	assert(pphead);
	//链表不能为空
	assert(*pphead);

	//链表不为空,
	//链表只有一个节点,有多个节点
	if ((*pphead)->next == NULL) {
		free(*pphead);
		*pphead = NULL;
		return;
	}
	SLTNode* ptail = *pphead;
	SLTNode* prev = NULL;
	while (ptail->next) {
		prev = ptail;
		ptail = ptail->next;
	}
	prev->next = NULL;
	//销毁尾节点
	free(ptail);
	ptail = NULL;
}
相关推荐
jimmy.hua2 分钟前
C++刷怪笼(5)内存管理
开发语言·数据结构·c++
Freak嵌入式12 分钟前
全网最适合入门的面向对象编程教程:50 Python函数方法与接口-接口和抽象基类
java·开发语言·数据结构·python·接口·抽象基类
MogulNemenis1 小时前
力扣春招100题——队列
数据结构·算法·leetcode
学java的小菜鸟啊1 小时前
第五章 网络编程 TCP/UDP/Socket
java·开发语言·网络·数据结构·网络协议·tcp/ip·udp
菜鸟求带飞_2 小时前
算法打卡:第十一章 图论part01
java·数据结构·算法
是小Y啦2 小时前
leetcode 106.从中序与后续遍历序列构造二叉树
数据结构·算法·leetcode
万河归海4283 小时前
C语言——二分法搜索数组中特定元素并返回下标
c语言·开发语言·数据结构·经验分享·笔记·算法·visualstudio
秋夫人4 小时前
B+树(B+TREE)索引
数据结构·算法
代码雕刻家5 小时前
数据结构-3.1.栈的基本概念
c语言·开发语言·数据结构
AlexMercer10125 小时前
【C++】二、数据类型 (同C)
c语言·开发语言·数据结构·c++·笔记·算法