【数据结构】——单链表(增删查改)

 

目录

前言:

一:单链表的特点

​编辑 二:单链表实现

单链表定义

2.1申请节点(初始化)

2.2单链表尾插 

​编辑 2.3单链表打印

2.4单链表头插

 2.5单链表尾删

2.6单链表头删

 2.7单链表查找

2.8在目标位置后面插入

 2.9删除目标位置后面的值

 2.10在目标位置前插入

2.11删除目标位置

2.12单链表销毁

总代码

test.c

SList.c

SList.h 


前言:

因为顺序进行插入删除时,有时候需要移动大量数据,造成不便,影响了运行效率。这时候引出了它的黄金搭档 单链表;

单链表:通过一组任意的存储单元来存储线性表中的数据元素,不需要使用地址连续的存储单元,因此它不要求在逻辑上相邻的两个元素在物理位置上也相邻。

一:单链表的特点

  1. 单链表不要求逻辑上相邻的两个元素在物理位置上也相邻,因此不需要连续的存储空间。
  2. 单链表是非随机的存储结构,即不能直接找到表中某个特定的结点。查找某个特定的结点时,需要从表头开始遍历,依次查找。
  3. 优点:支持动态内存分配。由于单链表不需要预先分配一段连续的空间,因此可以根据实际需求动态地申请、释放节点空间,避免浪费内存。支持高效的插入、删除操作。由于单链表中的节点是通过指针相连的,因此在插入、删除一个节点时,只需要修改其前驱节点或后继节点的指针即可,时间复杂度为O ( 1 )
  4. 缺点:不支持随机访问。由于单链表中的节点不是连续存储的,因此不能像数组一样通过下标来直接访问一个元素,需要从头节点开始遍历整个链表才能访问任意位置的元素。

 二:单链表实现

单链表定义

每个链表结点,除了存放元素自身的信息外,还需要存放一个指向其后继的指针

单链表功能实现中,需要考虑三种情况:链表为空,一个节点,多个节点

typedef int SLNDatatype;

typedef struct SListNode //定义单链表结点类型
{
	struct SListNode* next;    //数据域,可以是别的各种数据类型
	SLNDatatype val;    //指针域

}SLNode;

2.1申请节点(初始化)

malloc出来一块地址,将有效值赋给val,next给NULL

malloc动态开辟的地址,在程序结束前,都需要进行free释放;

然会该节点的地址

//申请一个节点
SLNode* CreateNode(SLNDatatype x)
{
	SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	newnode->val = x;
	newnode->next = NULL;
	return newnode;
}

2.2单链表尾插 

我们需要改变该链表,传的是地址,形参接受应该为二级指针;

单链表功能实现中,需要考虑三种情况:链表为空,一个节点,多个节点

如果是空,直接将新节点赋给第一个节点

如果是一个及以上节点,找到链表尾部后,指针域next链接新节点数据域data

// 单链表尾插
void SListPushBack(SLNode** pplist, SLNDatatype x)
{
	assert(pplist);
	SLNode* newnode = CreateNode(x);

	if (*pplist == NULL)
	{
		*pplist = newnode;
	}
	else
	{
		//找尾
		SLNode* tail = *pplist;
		while (tail->next != NULL)
		{
			tail = tail->next;
		}
		tail->next = newnode;
	}
}

 2.3单链表打印

在【C】系列中,讲过结构体不管是修改还是打印,最好都传地址来操作,这样不需要额外开辟空间

assert():

断言判断中,其实pplist这个不会为NULL,因为*pplist是地址,哪怕这个地址指向的也是NULL,但是该pplist不为NULL;

assert():

断言是判断不允许为NULL的情况,比如链表为空,还要删除的这类情况;

在打印中:

将下一个地址赋给当前地址,进行遍历操作,和之前的自增++这类不同,因为链表空间不是连续存放的

//打印单链表
void SListPrint(SLNode** pplist)
{
	assert(pplist);
	SLNode* cur = *pplist;
	//遍历打印
	while (cur)
	{
		printf("%d->", cur->val);
		cur = cur->next;
	}
	printf("NULL\n");
}

2.4单链表头插

头部插入不管是空链表还是多个节点,将新链表链接到第一个节点即可

// 单链表的头插
void SListPushFront(SLNode** pplist, SLNDatatype x)
{
	assert(pplist);
	SLNode* phead = *pplist;
	SLNode* newnode = CreateNode(x);

	newnode->next = *pplist;
	*pplist = newnode;
}

 

 2.5单链表尾删

需要考虑两种情况

一个节点:将该节点删除释放即可;

两个及以上节点:循环找到下下个节点为空的节点,将其删除释放;

        也可以定义一个指针 prev:该指针作用是 当cur的下一个节点不等于空时, 记录此位置,如此循环直到找到下一个节点为空,将其cur释放删除,再将prev定义为新的尾,next置NULL;

// 单链表的尾删
void SListPopBack(SLNode** pplist)
{
	assert(pplist);
	assert(*pplist);
	SLNode* cur = *pplist;

	//1.一个节点
	if ((*pplist)->next == NULL)
	{
		free(*pplist);
		*pplist = NULL;
	}
	//2.一个以上的节点
	else
	{

        // 找尾

		/*SLNode* prev = NULL;
		SLNode* tail = *pphead;
		while (tail->next != NULL)
		{
			prev = tail;
			tail = tail->next;
		}

		free(tail);
		tail = NULL;

		prev->next = NULL;*/


		while (cur->next->next != NULL)
		{
			cur = cur->next;
		}
		free(cur->next);
		cur->next = NULL;
	}
}

 

2.6单链表头删

检查断言后,记录第一个节点位置,将第二个节点赋给第一个节点,再释放记录的位置;

可满足一个节点和多个节点

// 单链表头删
void SListPopFront(SLNode** pplist)
{
	assert(pplist);
	assert(*pplist);
	
	SLNode* cur = *pplist;
	*pplist = (*pplist)->next;
	free(cur);
	cur = NULL;
}

 

 2.7单链表查找

查找单链表是否存在此val,存在返回该指针,不存在返回null;

需要注意的是返回的是该指针,而不是该值;后面功能用指针传递更好,在C++库中也是这样定义的,我们可以统一

// 单链表查找
SLNode* SListFind(SLNode* plist, SLNDatatype x)
{
	assert(plist);

	SLNode* cur= plist;
	while (cur)	//遍历查找
	{	
		if (cur->val == x)
		{
			return cur;
		}
		else
		{
			cur= cur->next;
		}
	}
	return NULL;
}

2.8在目标位置后面插入

创建新节点空间后,将newnode链接到原链表尾,这里需要顺序关系,先链接尾部,再将newnode地址链接到原链表尾部


// 单链表在pos位置之后插入x
void SListInsertAfter(SLNode* pos, SLNDatatype x)
{
	assert(pos);
	SLNode* newnode = CreateNode(x);
	newnode->next = pos->next;
	pos->next = newnode;
}

 

 2.9删除目标位置后面的值

删除pos后面,将pos的next记录,再将链表跨过链接,释放记录值

// 单链表删除pos位置之后的值
void SListEraseAfter(SLNode* pos)
{
	assert(pos);
	pos位置后还有两个及以上值
	//if (pos->next->next != NULL)
	//{
	//	SLNode* cur = pos->next;	//cur是要删除的位置
	//	SLNode * next = pos->next->next;	//pos链接下一个位置
	//	
	//	pos->next = next;
	//	free(cur);
	//	cur = NULL;
	//}
	pos位置后只有一个或者没有值
	//else
	//{
	//	free(pos->next);
	//	pos->next = NULL;
	//}

	SLNode* cur = pos->next;
	pos->next = pos->next->next;
	free(cur);
	cur = NULL;

}

 

 2.10在目标位置前插入

精确断言判定后,分成两种情况;

pos为第一个节点:       该操作类似 单链表头插入,调用该函数即可;

pos在链表其他位置:先循环next找,与上同理,注意链接的先后顺序;

这里其实还有一种方式,就是将新节点插入到pos位置后,然后将pos的val值和newnode的val值进行交换即可;

// 在pos的前面插入
void SLTInsert(SLNode** pphead, SLNode* pos, SLNDatatype x)
{
	assert(pos);
	assert(pphead);
	assert(*pphead);
	SLNode* cur = *pphead;
	SLNode* newnode = CreateNode(x);

	//pos在头节点
	if (pos == cur)
	{
		SListPushFront(pphead, x);
	}

	while (cur)
	{
		if (cur->next == pos)	//找到pos位置 前
		{
			newnode->next = pos;
			cur->next = newnode;
			return;
		}
		else
		{
			cur = cur->next;

		}
	}

}

 

2.11删除目标位置

与上同理分两种情况:

pos为第一个节点:类似头删除;

pos在其他位置:记录覆盖即可

// 删除pos位置
void SLTErase(SLNode** pphead, SLNode* pos)
{
	assert(pos);
	assert(pphead);
	assert(*pphead);

	//
	SLNode* cur = *pphead;


//while (cur)
//{
//	if (pos == cur)
//	{
//		cur = cur->next;
//		free(pos);
//		pos = NULL;
//		return;
//	}
//	if (cur->next == pos)
//	{
//		cur->next = cur->next->next;
//		free(pos);
//		pos = NULL;
//		return;
//	}
//	else
//	{
//		cur = cur->next;
//	}
//}

	if (pos == *pphead)
	{
		//头删
		SListPopFront(pphead);
	}
	else
	{
		while (cur->next != pos)
		{
			cur = cur->next;
		}
		cur->next = cur->next->next;
		free(pos);
		pos = NULL;
		}	
}

 

2.12单链表销毁

因为链表是动态开辟空间,在最后需要释放置NULL;

void SLTDestroy(SLNode** pphead)
{
	assert(pphead);
	SLNode* cur = *pphead;
	while (cur)
	{
		SLNode* next = cur->next;
		free(cur);
		cur = next;
	}
	*pphead = NULL;
}

总代码

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"SList.h"



void test1()
{
	SLNode* s = NULL;
	SListPushBack(&s, 1);
	SListPushBack(&s, 2);
	SListPushBack(&s, 3);
	SListPrint(&s);

	SListPushFront(&s, 5);
	SListPrint(&s);
}

void test2()
{
	SLNode* s = NULL;
	SListPushBack(&s, 1);
	SListPushBack(&s, 2);
	SListPushBack(&s, 3);
	SListPrint(&s);

	SListPopBack(&s);
	SListPrint(&s);

	SListPopFront(&s);
	SListPrint(&s);

	SListPopFront(&s);
	SListPrint(&s);
}

void test3()
{
	SLNode* s = NULL;
	SListPushBack(&s, 1);
	SListPushBack(&s, 2);
	SListPushBack(&s, 3);
	SListPrint(&s);

	SLNode* pos = SListFind(s, 1);
	SListInsertAfter(pos, 4);
	SListPrint(&s);
}

void test4()
{
	SLNode* s = NULL;
	SListPushBack(&s, 1);
	SListPushBack(&s, 2);
	SListPushBack(&s, 3);
	SListPushBack(&s, 4);
	SListPushBack(&s, 5);

	SListPrint(&s);

	SLNode* pos = SListFind(s, 2);
	SListEraseAfter(pos);
	SListPrint(&s);

}

void test5()
{
	SLNode* s = NULL;
	SListPushBack(&s, 1);
	SListPushBack(&s, 2);
	SListPushBack(&s, 3);
	SListPrint(&s);
	SLNode* pos = SListFind(s, 2);
	SLTInsert(&s,pos,6);
	SListPrint(&s);

	SLTErase(&s,pos);
	SListPrint(&s);

}
int main()
{
	//test1();
	//test2();
	//test3();
	//test4();
	test5();

	return 0;
}

SList.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"SList.h"

//申请一个节点
SLNode* CreateNode(SLNDatatype x)
{
	SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	newnode->val = x;
	newnode->next = NULL;
	return newnode;
}

// 单链表尾插
void SListPushBack(SLNode** pplist, SLNDatatype x)
{
	assert(pplist);
	SLNode* newnode = CreateNode(x);

	if (*pplist == NULL)
	{
		*pplist = newnode;
	}
	else
	{
		//找尾
		SLNode* tail = *pplist;
		while (tail->next != NULL)
		{
			tail = tail->next;
		}
		tail->next = newnode;
	}
}

//打印单链表
void SListPrint(SLNode** pplist)
{
	assert(pplist);
	SLNode* cur = *pplist;
	//遍历打印
	while (cur)
	{
		printf("%d->", cur->val);
		cur = cur->next;
	}
	printf("NULL\n");
}

// 单链表的头插
void SListPushFront(SLNode** pplist, SLNDatatype x)
{
	assert(pplist);
	SLNode* phead = *pplist;
	SLNode* newnode = CreateNode(x);

	newnode->next = *pplist;
	*pplist = newnode;
}

// 单链表的尾删
void SListPopBack(SLNode** pplist)
{
	assert(pplist);
	assert(*pplist);
	SLNode* cur = *pplist;

	//1.一个节点
	if ((*pplist)->next == NULL)
	{
		free(*pplist);
		*pplist = NULL;
	}
	//2.一个以上的节点
	else
	{
		// 找尾
		/*SLNode* prev = NULL;
		SLNode* tail = *pphead;
		while (tail->next != NULL)
		{
			prev = tail;
			tail = tail->next;
		}

		free(tail);
		tail = NULL;

		prev->next = NULL;*/
		while (cur->next->next != NULL)
		{
			cur = cur->next;
		}
		free(cur->next);
		cur->next = NULL;
	}
}

// 单链表头删
void SListPopFront(SLNode** pplist)
{
	assert(pplist);
	assert(*pplist);
	
	SLNode* cur = *pplist;
	*pplist = (*pplist)->next;
	free(cur);
	cur = NULL;
}

// 单链表查找
SLNode* SListFind(SLNode* plist, SLNDatatype x)
{
	assert(plist);

	SLNode* cur = plist;
	while (cur)	//遍历查找
	{	
		if (cur->val == x)
		{
			return cur;
		}
		else
		{
			cur = cur->next;
		}
	}
	return NULL;
}

// 单链表在pos位置之后插入x
void SListInsertAfter(SLNode* pos, SLNDatatype x)
{
	assert(pos);
	SLNode* newnode = CreateNode(x);
	newnode->next = pos->next;
	pos->next = newnode;
}

// 单链表删除pos位置之后的值
void SListEraseAfter(SLNode* pos)
{
	assert(pos);
	pos位置后还有两个及以上值
	//if (pos->next->next != NULL)
	//{
	//	SLNode* cur = pos->next;	//cur是要删除的位置
	//	SLNode * next = pos->next->next;	//pos链接下一个位置
	//	
	//	pos->next = next;
	//	free(cur);
	//	cur = NULL;
	//}
	pos位置后只有一个或者没有值
	//else
	//{
	//	free(pos->next);
	//	pos->next = NULL;
	//}

	SLNode* cur = pos->next;
	pos->next = pos->next->next;
	free(cur);
	cur = NULL;

}

// 在pos的前面插入
void SLTInsert(SLNode** pphead, SLNode* pos, SLNDatatype x)
{
	assert(pos);
	assert(pphead);
	assert(*pphead);
	SLNode* cur = *pphead;
	SLNode* newnode = CreateNode(x);

	//pos在头节点
	if (pos == cur)
	{
		SListPushFront(pphead, x);
	}

	while (cur)
	{
		if (cur->next == pos)	//找到pos位置 前
		{
			SLNode* prev = cur;
			newnode->next = pos;
			cur->next = newnode;
			return;
		}
		else
		{
			cur = cur->next;

		}
	}

}

// 删除pos位置
void SLTErase(SLNode** pphead, SLNode* pos)
{
	assert(pos);
	assert(pphead);
	assert(*pphead);

	//
	SLNode* cur = *pphead;


//while (cur)
//{
//	if (pos == cur)
//	{
//		cur = cur->next;
//		free(pos);
//		pos = NULL;
//		return;
//	}
//	if (cur->next == pos)
//	{
//		cur->next = cur->next->next;
//		free(pos);
//		pos = NULL;
//		return;
//	}
//	else
//	{
//		cur = cur->next;
//	}
//}

	if (pos == *pphead)
	{
		//头删
		SListPopFront(pphead);
	}
	else
	{
		while (cur->next != pos)
		{
			cur = cur->next;
		}
		cur->next = cur->next->next;
		free(pos);
		pos = NULL;
		}	
}

void SLTDestroy(SLNode** pphead)
{
	assert(pphead);
	SLNode* cur = *pphead;
	while (cur)
	{
		SLNode* next = cur->next;
		free(cur);
		cur = next;
	}
	*pphead = NULL;
}

SList.h 

#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>

typedef int SLNDatatype;

typedef struct SListNode        //链表定义
{
	struct SListNode* next;
	SLNDatatype val;

}SLNode;


// 动态申请一个节点
SLNode* CreateNode(SLNDatatype x);

// 单链表尾插
void SListPushBack(SLNode** pplist, SLNDatatype x);

//打印单链表
void SListPrint(SLNode** phead);

// 单链表的头插
void SListPushFront(SLNode** pplist, SLNDatatype x);

// 单链表的尾删
void SListPopBack(SLNode** pplist);

// 单链表头删
void SListPopFront(SLNode** pplist);

// 单链表查找
SLNode* SListFind(SLNode* plist, SLNDatatype x);

// 单链表在pos位置之后插入x
void SListInsertAfter(SLNode* pos, SLNDatatype x);

// 单链表删除pos位置之后的值
void SListEraseAfter(SLNode* pos);

// 在pos的前面插入
void SLTInsert(SLNode** pphead, SLNode* pos, SLNDatatype x);

// 删除pos位置
void SLTErase(SLNode** pphead, SLNode* pos);

//销毁单链表
void SLTDestroy(SLNode** pphead);

以上就是我对单链表的理解和功能实现介绍,身为初学者,作者能力有限,文中不对的地方,需要改进的地方,还望各位指点,感激不尽!!! 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/140578.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

正点原子嵌入式linux驱动开发——Linux ADC驱动

在之前的笔记中&#xff0c;学习了如何给ICM20608编写IIO驱动&#xff0c;ICM20608本质就是ADC&#xff0c;因此纯粹的ADC驱动也是IIO驱动框架的。本章就学习一下如何使用STM32MP1内部的ADC&#xff0c;并且在学习巩固一下IIO驱动。 ADC简介 ADC ADC&#xff0c;Analog to D…

做一个springboot用户信息模块

目录 用户信息部分 1、获取用户详细信息 前言 代码分析 代码实现 测试 2、更新用户信息 前言 代码实现 测试 3、更新用户头像 前言 代码实现 测试 4、更新用户密码 前言 代码实现 测试 用户信息部分 1、获取用户详细信息 前言 承接上一篇博客登录注册功能…

找工作去哪个网站比较好

吉鹿力招聘网是一个专注于互联网岗位求职招聘的网站&#xff0c;提供海量的互联网人才储备。它主要覆盖了互联网类招聘&#xff0c;包括技术、产品、设计、运营、市场、销售等。吉鹿力招聘网的特点是用户量大&#xff0c;需求旺盛。如果你希望找工作&#xff0c;吉鹿力招聘网是…

[HCTF 2018]admin 1(四种解法!)

题目环境&#xff1a; 有登录和注册两个按钮 先注册一个admin用户 注册admin用户 显示admin用户已经被注册了 好&#xff0c;这就简单了&#xff0c;admin用户存在&#xff0c;但是不清楚admin用户的密码 尝试以下弱口令 第一种解法&#xff1a;密码爆破-尝试弱口令 进去login登…

基于selenium的pyse自动化测试框架

介绍&#xff1a; pyse基于selenium&#xff08;webdriver&#xff09;进行了简单的二次封装&#xff0c;比selenium所提供的方法操作更简洁。 特点&#xff1a; 默认使用CSS定位&#xff0c;同时支持多种定位方法&#xff08;id\name\class\link_text\xpath\css&#xff09…

Python+unittest+requests接口自动化测试框架搭建 完整的框架搭建过程

首先配置好开发环境&#xff0c;下载安装Python并下载安装pycharm&#xff0c;在pycharm中创建项目功能目录。如果不会的可以百度Google一下&#xff0c;该内容网上的讲解还是比较多比较全的&#xff01; 大家可以先简单了解下该项目的目录结构介绍&#xff0c;后面会针对每个文…

第 19 章 网络编程

网络可以使不同物理位置上的计算机达到资源共享和通信的目的&#xff0c;在Java中也提供了专门的网络开发程序包--java.net&#xff0c;以方便开发者进行网络程序的开发&#xff0c;本章将讲解TCP与UDP程序开发 19.1 网络编程简介 将地理位置不同的、具有独立功能的多台计算机…

uview的u-calendar日历组件,当设置了 minDate配置项后,会导致第一次打开日历弹窗,不会精准的滚动到选中的日期(设置了默认日期都没用)

发现需要给month.vue文件里的getMonth方法加一个延时器&#xff0c;猜测是因为设置最小日期后&#xff0c;日历没渲染完毕的时候就已经开始获取节点信息了

C# Onnx Yolov8 Detect 印章 指纹捺印 检测

应用场景 检测文件中的印章和指纹捺印&#xff0c;用于判断文件是否合规&#xff08;是否盖章&#xff0c;是否按印&#xff09; 效果 项目 代码 using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using OpenCvSharp; using System; using System.…

Makefile应用

Makefile实例 在c.c里面&#xff0c;包含一个头文件c.h&#xff0c;在c.h里面定义一个宏&#xff0c;把这个宏打印出来。 c.c&#xff1a; #include <stdio.h> #include <c.h>void func_c() {printf("This is C %d\n", C); }c.h #define C 1然后上传…

跨国企业如何选择安全靠谱的跨国传输文件软件?

随着全球化的不断发展&#xff0c;跨国企业之间的合作变得越来越频繁。而在这种合作中&#xff0c;如何安全、可靠地将文件传输给合作伙伴或客户&#xff0c;成为了跨国企业必须面对的问题。 然而&#xff0c;跨国文件传输并不是一件容易的事情&#xff0c;由于网络物理条件的…

Mysql-库的操作

1.创建数据库 CREATE DATABASE [IF NOT EXISTS] name name后可以加 CHARACTER SET 或者是 charsetname COLLATE collation_name &#xff08;mysql数据库不区分大小写&#xff09; 说明&#xff1a; name表示想创建的库的名字大写的表示关键字 [] 是可选项 CHARACTER SET…

Linux调试器-gdb使用

程序的开发过程 debug和release ​ 程序的发布版本有debug和release版本&#xff0c;debug就是可被调试的&#xff08;debug环境下程序可以进行调试&#xff09;&#xff0c;release是发行版本&#xff0c;测试人员和用户使用的版本。Linux下我们编译代码时默认是release版本&…

苍穹外卖项目学习日记(13)

苍穹外卖项目学习日记(13) day10 Spring task cron表达式 导入spring task坐标&#xff08;spring-context已经存在&#xff09;&#xff0c;添加EnableScheduling注解 订单状态定时处理 新建task包&#xff0c;并且创建OrderTask定时类&#xff0c;添加处理超时订单和处…

网络运维Day12

文章目录 yum概述部署阿里镜像源yum基本使用 NFS网络文件系统NFS共享概述部署NFS服务端部署NFS客户端 Tomcat服务实验拓扑安装Tomcat启动服务客户端&#xff08;真机&#xff09;浏览访问页面测试 Tomcat虚拟主机NGINX服务web服务器对比NGINX简介实验拓扑虚拟机A源码编译安装NG…

ESP32-DHT11温湿度数据上传MQTT服务器

ESP32-DHT11温湿度数据上传MQTT服务器 简介ESP32DHT11 实验实验说明接线MQTT服务器建立连接添加订阅 ESP32驱动DHT11ESP32向MQTT服务器发送数据上传温湿度数据实验结果 简介 ESP32 点击图片购买 ESP32 系列模组集成 Wi-Fi、传统蓝牙和低功耗蓝牙功能&#xff0c;具有广泛的用途…

centos7系统离线安装tcpdump抓包软件、使用教程

tcpdump 是Linux系统下的一个强大的命令&#xff0c;可以将网络中传送的数据包完全截获下来提供分析。它支持针对网络层、协议、主机、网络或端口的过滤&#xff0c;并提供and、or、not等逻辑语句来帮助你去掉无用的信息。 本教程对tcpdump命令使用进行讲解说明&#xff0c;通…

对话金山云高级副总裁刘涛 | 做大模型公司的助力者

“ AIGC的应用化阶段将很快到来&#xff1b;AGI&#xff0c;已步入助手阶段。” 口述 | 刘涛 整理 | 梦婕&云舒 出品&#xff5c;极新 在10月的最后一天&#xff0c;极新有幸采访到了金山云高级副总裁刘涛。我们深入探讨了“云计算逐鹿 AIGC”的话题。作为中国公有云互…

Redhat Linux v8.2 实时内核环境配置及参数调优

BC-Linux V8.2 实时内核环境配置及参数调优 -------物理机 & 虚拟机 一、前言 本文档包含有关Redhat Linux for Real Time的基本安装和调试信息。许多行业和组织需要极高性能的计算&#xff0c;并且可能需要低且可预测的延迟&#xff0c;尤其是在金融和电信行业中。延迟&…

【MySQL】入门基础

文章目录 1 :peach:数据库基础:peach:1.1 :apple:什么是数据库:apple:1.2 :apple:主流数据库:apple:1.3 :apple:服务器/数据库/表关系:apple:1.4 :apple:MySQL架构:apple:1.5 :apple:SQL分类:apple:1.6 :apple:存储引擎:apple: 2 :peach:库的操作:peach:2.1 :apple:创建数据库:…