数据结构-单链表

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

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

顺序表的问题和思考

中间/头部的插入删除,时间复杂度为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;
}
相关推荐
手握风云-4 分钟前
数据结构(Java版)第二期:包装类和泛型
java·开发语言·数据结构
熬夜学编程的小王2 小时前
【C++篇】深度解析 C++ List 容器:底层设计与实现揭秘
开发语言·数据结构·c++·stl·list
阿史大杯茶2 小时前
AtCoder Beginner Contest 381(ABCDEF 题)视频讲解
数据结构·c++·算法
Chris _data2 小时前
二叉树oj题解析
java·数据结构
Lenyiin3 小时前
02.06、回文链表
数据结构·leetcode·链表
爪哇学长3 小时前
双指针算法详解:原理、应用场景及代码示例
java·数据结构·算法
爱摸鱼的孔乙己3 小时前
【数据结构】链表(leetcode)
c语言·数据结构·c++·链表·csdn
烦躁的大鼻嘎4 小时前
模拟算法实例讲解:从理论到实践的编程之旅
数据结构·c++·算法·leetcode
C++忠实粉丝4 小时前
计算机网络socket编程(4)_TCP socket API 详解
网络·数据结构·c++·网络协议·tcp/ip·计算机网络·算法
daiyang123...6 小时前
测试岗位应该学什么
数据结构