前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【C++】AVL树

【C++】AVL树

作者头像
风中的云彩
发布于 2025-05-06 05:22:34
发布于 2025-05-06 05:22:34
6700
代码可运行
举报
文章被收录于专栏:C/C++的自学之路C/C++的自学之路
运行总次数:0
代码可运行

AVL树的概念

1. AVL树是一种 自平衡二叉搜索树,具有以下性质:

  • 空树性质一棵AVL树可以是空树
  • 递归性质:如果非空,则AVL树满足以下条件:
    1. 左右子树均为AVL树
    2. 左右子树的高度差(即平衡因子)的绝对值不超过1

2. AVL树需要引入一个平衡因子的概念,每个结点都有一个平衡因子,任何结点的平衡因子等于右子树的高度减去左子树的高度,也就是说任何结点的平衡因子等于01-1。 3. AVL树整体结点数量和分布与完全二叉树类似,高度可以控制在log(N),那么增删查改的效率也可以控制在log(N),相比二叉搜索树有了本质的提升。

AVL树的插入

整体的插入规则

1. 先按 二叉搜索树规则 进行插入。 2. 新增结点只会影响祖先结点的高度 ,也就是可能会影响部分祖先结点的平衡因子。所以 需要更新从新增结点到根结点路径上的平衡因子 ,实际中最坏情况下要更新到根,有些情况更新到中间就可以停止了。 3. 更新平衡因子过程中没有出现问题,则插入结束。 4. 更新平衡因子过程中出现不平衡对不平衡子树旋转 。旋转后,本质调平衡的同时,本质降低了子树的高度,不会再影响上一层,所以插入结束。

平衡因子更新原则

1. 平衡因子 = 右子树高度 - 左子树高度 。 2. 只有 子树高度变化 才会影响当前结点的平衡因子。 3. 插入结点会增加高度 。当新增结点在 parent的右子树parent的平衡因子++ ;当新增结点在 parent的左子树parent平衡因子--

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
bool insert(const K& x, const V& y)
{
	Node* cur = _root;
	Node* parent = nullptr;
	if (_root == nullptr)
	{
		_root = new Node(x, y);
		return true;
	}
	else
	{
		while (cur != nullptr)
		{
			if (cur->_key < x)
			{
				parent = cur;
				cur = cur->_right;
			}
			else if (cur->_key > x)
			{
				parent = cur;
				cur = cur->_left;
			}
			else
			{
				return false;//不允许有重复
			}
		}
	}
	cur = new Node(x, y);
	if (parent->_key < cur->_key)
	{
		parent->_right = cur;
	}
	else
	{
		parent->_left = cur;
	}
	cur->_parent = parent;
	//更新平衡因子
	while (parent)
	{
		if (cur == parent->left)
		{
			parent->bf--;
		}
		else if (cur == parent->right)
		{
			parent->bf++;
		}
		if (parent->_bf == 0)
		{
			break;
		}
		else if (parent->_bf == 1 || parent->_bf == -1)
		{
			cur = parent;
			parent = parent->_parent;
		}
		else if (parent->_bf == 2 || parent->_bf == -2)
		{
			//需要进行旋转调整
            ...
		}
		else
		{
			assert(false);
		}
	}
	return true;
}

旋转原则

1. 保持二叉搜索树性质的前提下让旋转的树从不平衡变平衡。 3. 旋转总共分为四种, 左单旋右单旋左右双旋右左双旋

右单旋
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void Rotate_Right(Node* parent)
{
	Node* ppNode = parent->_parent;
	Node* sub_left = parent->_left;
	Node* subl_right = sub_left->_right;

	sub_left->_right=parent;
	parent->_parent = sub_left;
	parent->_left = subl_right;
	if (subl_right)
	{
		subl_right->_parent = parent;
	}
	if (ppNode==nullptr)
	{
		_root = sub_left;
		sub_left->_parent = nullptr;
	}
	else
	{
		if (ppNode->_left == parent)
		{
			ppNode->_left = sub_left;
		}
		else
		{
			ppNode->_right = sub_left;
		}
	}
}
左单旋
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void Rotate_Left(Node* parent)
{
	Node* ppNode = parent->_parent;
	Node* sub_right = parent->_right;
	Node* subr_left = sub_right->_left;

	sub_right->_left = parent;
	parent->_parent = sub_right;
	parent->_right = subr_left;
	if (subr_left)
	{
		subr_left->_parent = parent;
	}
	if (ppNode == nullptr)
	{
		_root = sub_right;
		sub_right->_parent = nullptr;
	}
	else
	{
		if (ppNode->_left == parent)
		{
			ppNode->_left = sub_right;
		}
		else
		{
			ppNode->_right = sub_right;
		}
	}
}
左右双旋
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void Rotate_Left_Right(Node* parent)
{
	Node* sub_left = parent->_left;
	Node* subl_right = sub_left->_right;
	int bf=subl_right->_bf;

	Rotate_Left(sub_left);
	Rotate_Right(parent);

	if (bf == 0)
	{
		parent->_bf = 0;
		sub_left->_bf = 0;
		subl_right->_bf = 0;
	}
	else if (bf == 1)
	{
		parent->_bf = 0;
		sub_left->_bf = -1;
		subl_right->_bf = 0;
	}
	else if (bf == -1)
	{
		parent->_bf = 1;
		sub_left->_bf = 0;
		subl_right->_bf = 0;
	}
	else
	{
		assert(false);
	}
}
右左双旋
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void Rotate_Right_Left(Node* parent)
{
	Node* sub_right = parent->_right;
	Node* subr_left = sub_right->_left;
	int bf = subr_left->_bf;

	Rotate_Right(sub_right);
	Rotate_Left(parent);

	if (bf == 0)
	{
		parent->_bf = 0;
		sub_right->_bf = 0;
		subr_left->_bf = 0;
	}
	else if (bf == 1)
	{
		parent->_bf = -1;
		sub_right->_bf = 0;
		subr_left->_bf = 0;
	}
	else if (bf == -1)
	{
		parent->_bf = 0;
		sub_right->_bf = 1;
		subr_left->_bf = 0;
	}
	else
	{
		assert(false);
	}
}

插入的整体代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
bool insert(const K& x, const V& y)
{
	Node* cur = _root;
	Node* parent = nullptr;
	if (_root == nullptr)
	{
		_root = new Node(x, y);
		return true;
	}
	else
	{
		while (cur != nullptr)
		{
			if (cur->_key < x)
			{
				parent = cur;
				cur = cur->_right;
			}
			else if (cur->_key > x)
			{
				parent = cur;
				cur = cur->_left;
			}
			else
			{
				return false;//不允许有重复
			}
		}
	}
	cur = new Node(x, y);
	if (parent->_key < cur->_key)
	{
		parent->_right = cur;
	}
	else
	{
		parent->_left = cur;
	}
	cur->_parent = parent;
	//更新平衡因子
	while (parent)
	{
		if (cur == parent->_left)
		{
			parent->_bf--;
		}
		else if (cur == parent->_right)
		{
			parent->_bf++;
		}
		if (parent->_bf == 0)
		{
			break;
		}
		else if (parent->_bf == 1 || parent->_bf == -1)
		{
			cur = parent;
			parent = parent->_parent;
		}
		else if (parent->_bf == 2 || parent->_bf == -2)
		{
			//开始旋转
			if (parent->_bf == -2 && parent->_left->_bf == -1)
			{
				Rotate_Right(parent);
				break;
			}
			else if (parent->_bf == 2 && parent->_right->_bf == 1)
			{
				Rotate_Left(parent);
				break;
			}
			else if (parent->_bf == -2 && parent->_left->_bf == 1)
			{
				Rotate_Left_Right(parent);
				break;
			}
			else if (parent->_bf == 2 && parent->_right->_bf == -1)
			{
				Rotate_Right_Left(parent);
				break;
			}
			else
			{
				assert(false);
			}
		}
		else
		{
			assert(false);
		}
	}
	return true;
}
void Rotate_Right(Node* parent)
{
	Node* ppNode = parent->_parent;
	Node* sub_left = parent->_left;
	Node* subl_right = sub_left->_right;

	sub_left->_right=parent;
	parent->_parent = sub_left;
	parent->_left = subl_right;
	if (subl_right)
	{
		subl_right->_parent = parent;
	}
	if (ppNode==nullptr)
	{
		_root = sub_left;
		sub_left->_parent = nullptr;
	}
	else
	{
		if (ppNode->_left == parent)
		{
			ppNode->_left = sub_left;
		}
		else
		{
			ppNode->_right = sub_left;
		}
	}
}
void Rotate_Left(Node* parent)
{
	Node* ppNode = parent->_parent;
	Node* sub_right = parent->_right;
	Node* subr_left = sub_right->_left;

	sub_right->_left = parent;
	parent->_parent = sub_right;
	parent->_right = subr_left;
	if (subr_left)
	{
		subr_left->_parent = parent;
	}
	if (ppNode == nullptr)
	{
		_root = sub_right;
		sub_right->_parent = nullptr;
	}
	else
	{
		if (ppNode->_left == parent)
		{
			ppNode->_left = sub_right;
		}
		else
		{
			ppNode->_right = sub_right;
		}
	}
}
void Rotate_Left_Right(Node* parent)
{
	Node* sub_left = parent->_left;
	Node* subl_right = sub_left->_right;
	int bf=subl_right->_bf;

	Rotate_Left(sub_left);
	Rotate_Right(parent);

	if (bf == 0)
	{
		parent->_bf = 0;
		sub_left->_bf = 0;
		subl_right->_bf = 0;
	}
	else if (bf == 1)
	{
		parent->_bf = 0;
		sub_left->_bf = -1;
		subl_right->_bf = 0;
	}
	else if (bf == -1)
	{
		parent->_bf = 1;
		sub_left->_bf = 0;
		subl_right->_bf = 0;
	}
	else
	{
		assert(false);
	}
}
void Rotate_Right_Left(Node* parent)
{
	Node* sub_right = parent->_right;
	Node* subr_left = sub_right->_left;
	int bf = subr_left->_bf;

	Rotate_Right(sub_right);
	Rotate_Left(parent);

	if (bf == 0)
	{
		parent->_bf = 0;
		sub_right->_bf = 0;
		subr_left->_bf = 0;
	}
	else if (bf == 1)
	{
		parent->_bf = -1;
		sub_right->_bf = 0;
		subr_left->_bf = 0;
	}
	else if (bf == -1)
	{
		parent->_bf = 0;
		sub_right->_bf = 1;
		subr_left->_bf = 0;
	}
	else
	{
		assert(false);
	}
}

AVL树的遍历

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public:
    void InOrder()
    {
	    _InOrder(_root);
    }

private:
    void _InOrder(Node* root)
    {
	    if (root == nullptr)
	    {
		    return;
	    }
	    else
	    {
		    _InOrder(root->_left);
		    cout << root->_key << " " << root->_val << endl;
		    _InOrder(root->_right);
	    }
    }

AVL树的检验

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public:
    bool IsAVLTree(Node* root)
    {
	    if (root == nullptr)
	    {
		    return true;
	    }
	    int left_height = _Height(root->_left);
	    int right_height = _Height(root->_right);
	    int diff = right_height - left_height;
	    if (abs(diff) >= 2)
	    {
		    cout << "高度差异常" << " " << root->_key;
		    return false;
	    }
	    if (diff != root->_bf)
	    {
		    cout << "平衡因子异常" << " " << root->_key;
		    return false;
	    }
	    return IsAVLTree(root->_left) && IsAVLTree(root->_right);//从中间节点向左右两边递归
    }
private:
    int _Height(Node* root)
    {
	    if (root == nullptr)
	    {
	    	return 0;
	    }
	    int left_Height = _Height(root->_left);
	    int right_Height = _Height(root->_right);
	    return left_Height > right_Height ? left_Height + 1 : right_Height + 1;
    }

AVL树整体代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cassert>
using namespace std;

template <class K,class V>
struct AVLTNode
{
	typedef AVLTNode<K, V> Node;

	K _key;
	V _val;
	Node* _left;
	Node* _right;
	Node* _parent;
	int _bf; 

	AVLTNode(const K& key,const V& val)
		: _key(key)
		, _val(val)
		, _left(nullptr)
		, _right(nullptr)
		, _parent(nullptr)
		, _bf(0)
	{}
};

template<class K, class V>
class AVLTree
{
	typedef AVLTNode<K, V> Node;
	typedef AVLTree<K, V> Tree;

public:

	AVLTree()
		:_root(nullptr)
	{}

	bool insert(const K& x, const V& y)
	{
		Node* cur = _root;
		Node* parent = nullptr;
		if (_root == nullptr)
		{
			_root = new Node(x,y);
			return true;
		}
		else
		{
			while (cur != nullptr)
			{
				if (cur->_key < x)
				{
					parent = cur;
					cur = cur->_right;
				}
				else if (cur->_key > x)
				{
					parent = cur;
					cur = cur->_left;
				}
				else
				{
					return false;//不允许有重复
				}
			}
		}
		cur = new Node(x, y);
		if (parent->_key < cur->_key)
		{
			parent->_right = cur;
		}
		else
		{
			parent->_left = cur;
		}
		cur->_parent = parent;
		//更新平衡因子
		while (parent)
		{
			if (cur == parent->_left)
			{
				parent->_bf--;
			}
			else if (cur == parent->_right)
			{
				parent->_bf++;
			}
			if (parent->_bf == 0)
			{
				break;
			}
			else if (parent->_bf == 1 || parent->_bf == -1)
			{
				cur = parent;
				parent = parent->_parent;
			}
			else if (parent->_bf == 2 || parent->_bf == -2)
			{
				//开始旋转
				if (parent->_bf == -2 && parent->_left->_bf == -1)
				{
					Rotate_Right(parent);
					break;
				}
				else if (parent->_bf == 2 && parent->_right->_bf == 1)
				{
					Rotate_Left(parent);
					break;
				}
				else if (parent->_bf == -2 && parent->_left->_bf == 1)
				{
					Rotate_Left_Right(parent);
					break;
				}
				else if (parent->_bf == 2 && parent->_right->_bf == -1)
				{
					Rotate_Right_Left(parent);
					break;
				}
				else
				{
					assert(false);
				}
			}
			else
			{
				assert(false);
			}
		}
		return true;
	}

	Node* Find(const K& x)
	{
		Node* cur = _root;
		while (cur != nullptr)
		{
			if (cur->_key < x)
			{
				cur = cur->_right;
			}
			else if (cur->_key > x)
			{
				cur = cur->_left;
			}
			else
			{
				return cur;
			}
		}
		return nullptr;
	}

	void InOrder()
	{
		_InOrder(_root);
	}

	bool IsAVLTree(Node* root)
	{
		if (root == nullptr)
		{
			return true;
		}
		int left_height = _Height(root->_left);
		int right_height = _Height(root->_right);
		int diff = right_height - left_height;
		if (abs(diff) >= 2)
		{
			cout << "高度差异常" << " " << root->_key;
			return false;
		}
		if (diff != root->_bf)
		{
			cout << "平衡因子异常" << " " << root->_key;
			return false;
		}
		return IsAVLTree(root->_left) && IsAVLTree(root->_right);//从中间节点向左右两边递归
	}
	
private:

	void _InOrder(Node* root)
	{
		if (root == nullptr)
		{
			return;
		}
		else
		{
			_InOrder(root->_left);
			cout << root->_key << " " << root->_val << endl;
			_InOrder(root->_right);
		}
	}

	void Rotate_Right(Node* parent)
	{
		Node* ppNode = parent->_parent;
		Node* sub_left = parent->_left;
		Node* subl_right = sub_left->_right;

		sub_left->_right = parent;
		parent->_parent = sub_left;
		parent->_left = subl_right;
		if (subl_right)
		{
			subl_right->_parent = parent;
		}
		if (ppNode == nullptr)
		{
			_root = sub_left;
			sub_left->_parent = nullptr;
		}
		else
		{
			if (ppNode->_left == parent)
			{
				ppNode->_left = sub_left;
			}
			else
			{
				ppNode->_right = sub_left;
			}
		}
	}

	void Rotate_Left(Node* parent)
	{
		Node* ppNode = parent->_parent;
		Node* sub_right = parent->_right;
		Node* subr_left = sub_right->_left;

		sub_right->_left = parent;
		parent->_parent = sub_right;
		parent->_right = subr_left;
		if (subr_left)
		{
			subr_left->_parent = parent;
		}
		if (ppNode == nullptr)
		{
			_root = sub_right;
			sub_right->_parent = nullptr;
		}
		else
		{
			if (ppNode->_left == parent)
			{
				ppNode->_left = sub_right;
			}
			else
			{
				ppNode->_right = sub_right;
			}
		}
	}

	void Rotate_Left_Right(Node* parent)
	{
		Node* sub_left = parent->_left;
		Node* subl_right = sub_left->_right;
		int bf = subl_right->_bf;

		Rotate_Left(sub_left);
		Rotate_Right(parent);

		if (bf == 0)
		{
			parent->_bf = 0;
			sub_left->_bf = 0;
			subl_right->_bf = 0;
		}
		else if (bf == 1)
		{
			parent->_bf = 0;
			sub_left->_bf = -1;
			subl_right->_bf = 0;
		}
		else if (bf == -1)
		{
			parent->_bf = 1;
			sub_left->_bf = 0;
			subl_right->_bf = 0;
		}
		else
		{
			assert(false);
		}
	}

	void Rotate_Right_Left(Node* parent)
	{
		Node* sub_right = parent->_right;
		Node* subr_left = sub_right->_left;
		int bf = subr_left->_bf;

		Rotate_Right(sub_right);
		Rotate_Left(parent);

		if (bf == 0)
		{
			parent->_bf = 0;
			sub_right->_bf = 0;
			subr_left->_bf = 0;
		}
		else if (bf == 1)
		{
			parent->_bf = -1;
			sub_right->_bf = 0;
			subr_left->_bf = 0;
		}
		else if (bf == -1)
		{
			parent->_bf = 0;
			sub_right->_bf = 1;
			subr_left->_bf = 0;
		}
		else
		{
			assert(false);
		}
	}

	int _Height(Node* root)
	{
		if (root == nullptr)
		{
			return 0;
		}
		int left_Height = _Height(root->_left);
		int right_Height = _Height(root->_right);
		return left_Height > right_Height ? left_Height + 1 : right_Height + 1;//子树的高度等于左右子树高度的最大值加1。
	}

	Node* _root;
};
int main()
{
	AVLTree<int, string> a1;
	a1.insert(1, "苹果");
	a1.insert(2, "西瓜");
	a1.insert(3, "菠萝");
	a1.insert(8, "车厘子");
	a1.insert(4, "樱桃");
	a1.insert(5, "梨子");
	a1.insert(6, "香蕉");
	a1.insert(7, "哈密瓜");
	a1.InOrder();
	auto it = a1.Find(5);
	if (a1.Find(5))
	{
		cout << it->_key << "->" << it->_val;
	}
	return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-05-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
万字图解 | 深入揭秘TCP工作原理
大家好,我是「云舒编程」,今天我们来聊聊计算机网络面试之-(传输层tcp)工作原理。
公众号 云舒编程
2024/01/25
1.5K0
万字图解 | 深入揭秘TCP工作原理
TCP原理(三次握手四次挥手)
原文:https://blog.csdn.net/qq_50156012/article/details/123391854
入门笔记
2022/06/02
2920
TCP原理(三次握手四次挥手)
从 TCP 三次握手说起:浅析TCP协议中的疑难杂症 ( 2 )
本文主要介绍了在Linux系统中,如何通过配置TCP参数来优化网络性能。主要包括了TCP的四次挥手释放连接、TCP的慢启动和快速恢复、TCP的保活机制以及TCP的延迟应答机制等方面的内容。通过这些优化措施,可以大大提高Linux网络性能,减少网络拥堵和丢包现象,提高整体的网络吞吐量和连接的稳定性。
小时光
2016/09/28
4.2K0
从 TCP 三次握手说起:浅析TCP协议中的疑难杂症 ( 2 )
这次,终于学会了 TCP
这是一篇详细介绍 TCP 各种特点的文章,内容主要包括 TCP 三次握手和四次挥手细节问题、TCP 状态之间的转换、TCP 超时和重传、关于 TCP 包失序和重复问题、TCP 的数据流与窗口管理、TCP 的拥塞控制,思维导图如下。
cxuan
2021/07/12
8360
这次,终于学会了 TCP
面试反客为主 TCP
承接上文 HTTP,数据经过应用层就到传输层,但数据到传输层之前需要先获得服务端的 IP 地址,这就涉及到 DNS 域名解析。
sowhat1412
2022/09/20
3240
面试反客为主 TCP
《计算机网络传输层 TCP协议》
每个TCP报文段由固定的20Byte头部组成,TCP报文头部 选项可以跟在固定标头之后。 带有标头,使其最多可以标记 65535 个数据字节。
梅花
2021/11/11
7140
《计算机网络传输层 TCP协议》
【Linux】: 传输层协议 TCP
🔥 之前在这篇文章 传输层协议 UDP 中已经说过关于传输层的部分内容,现在我们来了解一下传输层 TCP 的内容吧
IsLand1314
2025/02/20
3580
【Linux】: 传输层协议 TCP
端口timewait如何解决_如何检测端口状态
本文根据众多互联网博客内容整理后形成,引用内容的版权归原始作者所有,仅限于学习研究使用
全栈程序员站长
2022/10/04
3K0
端口timewait如何解决_如何检测端口状态
Python Web学习笔记之图解TCP/IP协议和浅析算法
 本文通过两个图来梳理TCP-IP协议相关知识。TCP通信过程包括三个步骤:建立TCP连接通道,传输数据,断开TCP连接通道。如图1所示,给出了TCP通信过程的示意图。 图1主要包括三部分:建立连接、
Jetpropelledsnake21
2018/06/14
7010
从TCP的三次握手和四次挥手说起
传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。
acupt
2019/09/10
5130
从TCP的三次握手和四次挥手说起
网络通信——TCP “三次握手“、“四次挥手“ 详解
第一次握手: 客户端发送syn包(seq=x)到服务器,并进入SYN_SEND状态,等待服务器确认;
SmallRoll小卷
2023/03/03
5030
网络通信——TCP “三次握手“、“四次挥手“ 详解
网络基础篇-TCP
三次握手是保证客户端和服务端都能够知道消息的有去有回的最小次数。如果是2次,客户端没有给服务端回复ACK, 服务端不知道客户端有没有收到SYN+ACK,如果建立连接,客户端可能已经挂掉或者网络不可达。或者另外一种情况,客户端之前发送的SYN(由于重试等原因)又达到了服务端,这个链接如果建立了,也是无效的。四次也是可以的,只是三次就够了。
Check King
2021/08/09
4280
Java程序员必须掌握的网站知识 —— TCP
本文主要通过整理网络上的资料,整理出的关于TCP方面的简单理论知识。作为Java程序员虽然更多的时候我们都是直接调用现成的API,但是对网络知识有个宏观的概念能方便我们更好的编写代码。当然,文中涉及的
tomas家的小拨浪鼓
2018/06/27
1.1K0
TCP/IP(五)传输层之细说TCP的三次握手和四次挥手
前言   这一篇我将介绍的是大家面试经常被会问到的,三次握手四次挥手的过程。以前我听到这个是什么意思呀?听的我一脸蒙逼,但是学习之后就原来就那么回事! 一、运输层概述 1.1、运输层简介   这一层的功能也挺简单的,运输层提供应用层提供端到端通信服务,通俗的讲,两个主机通讯,也就是应用层上的进程之间的通信,也就是转换为进程和进程之间的通信了,我们之前学到网络层,   IP协议能将分组准确的发送到目的主机,但是停留在网络层,并不知道要怎么交给我们的主机应用进程,通过前面的学习,我们学习有mac地址,通过mac
用户1195962
2018/01/18
1.3K0
TCP/IP(五)传输层之细说TCP的三次握手和四次挥手
后端面试总结-网络篇
每个包的TCP首都都有4个字节的序列号,用来解决乱序和重复问题(根据序列号对收到的包进行正确的排序,再交给应用层;会丢弃掉序列号相同的数据包)
会玩code
2022/04/24
8520
后端面试总结-网络篇
面试必备!TCP协议经典十五连问!
TCP协议是大厂面试必问的知识点。整理了15道非常经典的TCP面试题,希望大家都找到理想的offer呀
捡田螺的小男孩
2021/07/19
1.3K0
后台开发-核心技术与应用实践--TCP协议
为使不同计算机厂家的计算机能够互相通信,国际标准化组织 ISO 1981 年正式推荐了一个网络系统结构一一七层参考模型,也叫作开放系统互连模型。
范中豪
2021/03/18
5080
后台开发-核心技术与应用实践--TCP协议
万字长文 | 23 个问题 TCP 疑难杂症全解析
这篇文章我想由浅到深地过一遍 TCP,不是生硬的搬出各个知识点,从问题入手,然后从发展、演进的角度来看 TCP。
敖丙
2020/09/14
8900
万字长文 | 23 个问题 TCP 疑难杂症全解析
TCP/IP中你不得不知的十大秘密
这段时间 有一点心很浮躁,不过希望自己马上要矫正过来。好好学习编程!这段时间我想好好地研究一下TCP/IP协议和网络传输这块!加油 一、TCP/IP模型 TCP/IP协议模型(Transmission
用户1195962
2018/01/18
1K0
TCP/IP中你不得不知的十大秘密
TCP三次握手图_tcp为什么三次握手
我们先来看看 TCP 头的格式,标注颜色的表示与本文关联比较大的字段,其他字段不做详细阐述。
全栈程序员站长
2022/11/10
9080
TCP三次握手图_tcp为什么三次握手
推荐阅读
相关推荐
万字图解 | 深入揭秘TCP工作原理
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档