一文搞定面试中的二叉树问题

一文搞定面试中的二叉树问题

版权所有,转载请注明出处,谢谢!
http://blog.csdn.net/walkinginthewind/article/details/7518888

树是一种比较重要的数据结构,尤其是二叉树。二叉树是一种特殊的树,在二叉树中每个节点最多有两个子节点,一般称为左子节点和右子节点(或左孩子和右孩子),并且二叉树的子树有左右之分,其次序不能任意颠倒。二叉树是递归定义的,因此,与二叉树有关的题目基本都可以用递归思想解决,当然有些题目非递归解法也应该掌握,如非递归遍历节点等等。本文努力对二叉树相关题目做一个较全的整理总结,希望对找工作的同学有所帮助。

二叉树节点定义如下:
struct BinaryTreeNode
{
    int m_nValue;
    BinaryTreeNode* m_pLeft;
    BinaryTreeNode* m_pRight;
};

相关链接:
轻松搞定面试中的链表题目

题目列表:

1. 求二叉树中的节点个数
2. 求二叉树的深度
3. 前序遍历,中序遍历,后序遍历
4.分层遍历二叉树(按层次从上往下,从左往右)
5. 将二叉查找树变为有序的双向链表
6. 求二叉树第K层的节点个数
7. 求二叉树中叶子节点的个数
8. 判断两棵二叉树是否结构相同
9. 判断二叉树是不是平衡二叉树
10. 求二叉树的镜像
11. 求二叉树中两个节点的最低公共祖先节点
12. 求二叉树中节点的最大距离
13. 由前序遍历序列和中序遍历序列重建二叉树
14.判断二叉树是不是完全二叉树

详细解答

1. 求二叉树中的节点个数
递归解法:
(1)如果二叉树为空,节点个数为0
(2)如果二叉树不为空,二叉树节点个数 = 左子树节点个数 + 右子树节点个数 + 1
参考代码如下:

[cpp] view plaincopy
  1. int GetNodeNum(BinaryTreeNode * pRoot)  
  2. {  
  3.     if(pRoot == NULL) // 递归出口  
  4.         return 0;  
  5.     return GetNodeNum(pRoot->m_pLeft) + GetNodeNum(pRoot->m_pRight) + 1;  
  6. }  
2. 求二叉树的深度
递归解法:
(1)如果二叉树为空,二叉树的深度为0
(2)如果二叉树不为空,二叉树的深度 = max(左子树深度, 右子树深度) + 1
参考代码如下:
[cpp] view plaincopy
  1. int GetDepth(BinaryTreeNode * pRoot)  
  2. {  
  3.     if(pRoot == NULL) // 递归出口  
  4.         return 0;  
  5.     int depthLeft = GetDepth(pRoot->m_pLeft);  
  6.     int depthRight = GetDepth(pRoot->m_pRight);  
  7.     return depthLeft > depthRight ? (depthLeft + 1) : (depthRight + 1);   
  8. }  
3. 前序遍历,中序遍历,后序遍历
前序遍历递归解法:
(1)如果二叉树为空,空操作
(2)如果二叉树不为空,访问根节点,前序遍历左子树,前序遍历右子树
参考代码如下:
[cpp] view plaincopy
  1. void PreOrderTraverse(BinaryTreeNode * pRoot)  
  2. {  
  3.     if(pRoot == NULL)  
  4.         return;  
  5.     Visit(pRoot); // 访问根节点  
  6.     PreOrderTraverse(pRoot->m_pLeft); // 前序遍历左子树  
  7.     PreOrderTraverse(pRoot->m_pRight); // 前序遍历右子树  
  8. }  
中序遍历递归解法
(1)如果二叉树为空,空操作。
(2)如果二叉树不为空,中序遍历左子树,访问根节点,中序遍历右子树
参考代码如下:
[cpp] view plaincopy
  1. void InOrderTraverse(BinaryTreeNode * pRoot)  
  2. {  
  3.     if(pRoot == NULL)  
  4.         return;  
  5.     InOrderTraverse(pRoot->m_pLeft); // 中序遍历左子树  
  6.     Visit(pRoot); // 访问根节点  
  7.     InOrderTraverse(pRoot->m_pRight); // 中序遍历右子树  
  8. }  
后序遍历递归解法
(1)如果二叉树为空,空操作
(2)如果二叉树不为空,后序遍历左子树,后序遍历右子树,访问根节点
参考代码如下:
[cpp] view plaincopy
  1. void PostOrderTraverse(BinaryTreeNode * pRoot)  
  2. {  
  3.     if(pRoot == NULL)  
  4.         return;  
  5.     PostOrderTraverse(pRoot->m_pLeft); // 后序遍历左子树  
  6.     PostOrderTraverse(pRoot->m_pRight); // 后序遍历右子树  
  7.     Visit(pRoot); // 访问根节点  
  8. }  

4.分层遍历二叉树(按层次从上往下,从左往右)

相当于广度优先搜索,使用队列实现。队列初始化,将根节点压入队列。当队列不为空,进行如下操作:弹出一个节点,访问,若左子节点或右子节点不为空,将其压入队列。

[cpp] view plaincopy
  1. void LevelTraverse(BinaryTreeNode * pRoot)  
  2. {  
  3.     if(pRoot == NULL)  
  4.         return;  
  5.     queue<BinaryTreeNode *> q;  
  6.     q.push(pRoot);//添加元素到队列尾部  
  7.     while(!q.empty())  
  8.     {  
  9.         BinaryTreeNode * pNode = q.front();//指向队列的首部  
  10.         q.pop();//删除首部元素(即指针)  
  11.         Visit(pNode); // 访问节点  
  12.         if(pNode->m_pLeft != NULL)  
  13.             q.push(pNode->m_pLeft);//添加元素到队列尾部  
  14.         if(pNode->m_pRight != NULL)  
  15.             q.push(pNode->m_pRight);//添加元素到队列尾部  
  16.     }  
  17.     return;  
  18. }  
5. 将二叉查找树变为有序的双向链表

要求不能创建新节点,只调整指针。
递归解法:
(1)如果二叉树查找树为空,不需要转换,对应双向链表的第一个节点是NULL,最后一个节点是NULL
(2)如果二叉查找树不为空:
如果左子树为空,对应双向有序链表的第一个节点是根节点,左边不需要其他操作;
如果左子树不为空,转换左子树,二叉查找树对应双向有序链表的第一个节点就是左子树转换后双向有序链表的第一个节点,同时将根节点和左子树转换后的双向有序链表的最后一个节点连接;
如果右子树为空,对应双向有序链表的最后一个节点是根节点,右边不需要其他操作;
如果右子树不为空,对应双向有序链表的最后一个节点就是右子树转换后双向有序链表的最后一个节点,同时将根节点和右子树转换后的双向有序链表的第一个节点连接。
参考代码如下:
[cpp] view plaincopy
  1. /****************************************************************************** 
  2. 参数: 
  3. pRoot: 二叉查找树根节点指针 
  4. pFirstNode: 转换后双向有序链表的第一个节点指针 
  5. pLastNode: 转换后双向有序链表的最后一个节点指针 
  6. ******************************************************************************/  
  7. void Convert(BinaryTreeNode * pRoot,   
  8.              BinaryTreeNode * & pFirstNode, BinaryTreeNode * & pLastNode)  
  9. {  
  10.     BinaryTreeNode *pFirstLeft, *pLastLeft, * pFirstRight, *pLastRight;  
  11.     if(pRoot == NULL)   
  12.     {  
  13.         pFirstNode = NULL;  
  14.         pLastNode = NULL;  
  15.         return;  
  16.     }  
  17.   
  18.     if(pRoot->m_pLeft == NULL)  
  19.     {  
  20.         // 如果左子树为空,对应双向有序链表的第一个节点是根节点  
  21.         pFirstNode = pRoot;  
  22.     }  
  23.     else  
  24.     {  
  25.         Convert(pRoot->m_pLeft, pFirstLeft, pLastLeft);  
  26.         // 二叉查找树对应双向有序链表的第一个节点就是左子树转换后双向有序链表的第一个节点  
  27.         pFirstNode = pFirstLeft;  
  28.         // 将根节点和左子树转换后的双向有序链表的最后一个节点连接  
  29.         pRoot->m_pLeft = pLastLeft;  
  30.         pLastLeft->m_pRight = pRoot;  
  31.     }  
  32.   
  33.     if(pRoot->m_pRight == NULL)  
  34.     {  
  35.         // 对应双向有序链表的最后一个节点是根节点  
  36.         pLastNode = pRoot;  
  37.     }  
  38.     else  
  39.     {  
  40.         Convert(pRoot->m_pRight, pFirstRight, pLastRight);  
  41.         // 对应双向有序链表的最后一个节点就是右子树转换后双向有序链表的最后一个节点  
  42.         pLastNode = pLastRight;  
  43.         // 将根节点和右子树转换后的双向有序链表的第一个节点连接  
  44.         pRoot->m_pRight = pFirstRight;  
  45.         pFirstRight->m_pLeft = pRoot;  
  46.     }  
  47.   
  48.     return;  
  49. }  
6. 求二叉树第K层的节点个数
递归解法:
(1)如果二叉树为空或者k<1返回0
(2)如果二叉树不为空并且k==1,返回1
(3)如果二叉树不为空且k>1,返回左子树中k-1层的节点个数与右子树k-1层节点个数之和
参考代码如下:
[cpp] view plaincopy
  1. int GetNodeNumKthLevel(BinaryTreeNode * pRoot, int k)  
  2. {  
  3.     if(pRoot == NULL || k < 1)  
  4.         return 0;  
  5.     if(k == 1)  
  6.         return 1;  
  7.     int numLeft = GetNodeNumKthLevel(pRoot->m_pLeft, k-1); // 左子树中k-1层的节点个数  
  8.     int numRight = GetNodeNumKthLevel(pRoot->m_pRight, k-1); // 右子树中k-1层的节点个数  
  9.     return (numLeft + numRight);  
  10. }  
7. 求二叉树中叶子节点的个数

完全二叉树有2*n-1 个节点,则它的叶子节点数为?

完全二叉树的节点数是奇数,说明此完全二叉树也是满二叉树,也就是说每个内部节点正好都有2个叶结点.
设内部节点数为a,叶节点数为b,结点总数为m,明显有a+b=m (1)
非空满二叉树中所有节点的出度正好等于入度,每个内部节点出度为2,叶节点出度为0,所有节点的出度和为2a;根节点入度为0,其他节点的入度为1,所有节点的入度和为a+b-1;因此有2a=a+b-1 (2)
由(1),(2)得 b=(m+1)/2,a=(m-1)/2,b=a+1
也就是说,非空满二叉树的叶节点数正好比内部节点数多1
此完全二叉树的结点总数为2n-1,因此其叶结点数为n.


递归解法:

(1)如果二叉树为空,返回0
(2)如果二叉树不为空且左右子树为空,返回1
(3)如果二叉树不为空,且左右子树不同时为空,返回左子树中叶子节点个数加上右子树中叶子节点个数
参考代码如下:
[cpp] view plaincopy
  1. int GetLeafNodeNum(BinaryTreeNode * pRoot)  
  2. {  
  3.     if(pRoot == NULL)  
  4.         return 0;  
  5.     if(pRoot->m_pLeft == NULL && pRoot->m_pRight == NULL)  
  6.         return 1;  
  7.     int numLeft = GetLeafNodeNum(pRoot->m_pLeft); // 左子树中叶节点的个数  
  8.     int numRight = GetLeafNodeNum(pRoot->m_pRight); // 右子树中叶节点的个数  
  9.     return (numLeft + numRight);  
  10. }  

8. 判断两棵二叉树是否结构相同

不考虑数据内容。结构相同意味着对应的左子树和对应的右子树都结构相同。
递归解法:
(1)如果两棵二叉树都为空,返回真
(2)如果两棵二叉树一棵为空,另一棵不为空,返回假
(3)如果两棵二叉树都不为空,如果对应的左子树和右子树都同构返回真,其他返回假
参考代码如下:
[cpp] view plaincopy
  1. bool StructureCmp(BinaryTreeNode * pRoot1, BinaryTreeNode * pRoot2)  
  2. {  
  3.     if(pRoot1 == NULL && pRoot2 == NULL) // 都为空,返回真  
  4.         return true;  
  5.     else if(pRoot1 == NULL || pRoot2 == NULL) // 有一个为空,一个不为空,返回假  
  6.         return false;  
  7.     bool resultLeft = StructureCmp(pRoot1->m_pLeft, pRoot2->m_pLeft); // 比较对应左子树   
  8.     bool resultRight = StructureCmp(pRoot1->m_pRight, pRoot2->m_pRight); // 比较对应右子树  
  9.     return (resultLeft && resultRight);  
  10. }   
9. 判断二叉树是不是平衡二叉树
递归解法:
(1)如果二叉树为空,返回真
(2)如果二叉树不为空,如果左子树和右子树都是AVL树并且左子树和右子树高度相差不大于1,返回真,其他返回假
参考代码:
[cpp] view plaincopy
  1. bool IsAVL(BinaryTreeNode * pRoot, int & height)  
  2. {  
  3.     if(pRoot == NULL) // 空树,返回真  
  4.     {  
  5.         height = 0;  
  6.         return true;  
  7.     }  
  8.     int heightLeft;  
  9.     bool resultLeft = IsAVL(pRoot->m_pLeft, heightLeft);  
  10.     int heightRight;  
  11.     bool resultRight = IsAVL(pRoot->m_pRight, heightRight);  
  12.     if(resultLeft && resultRight && abs(heightLeft - heightRight) <= 1) // 左子树和右子树都是AVL,并且高度相差不大于1,返回真  
  13.     {  
  14.         height = max(heightLeft, heightRight) + 1;  
  15.         return true;  
  16.     }  
  17.     else  
  18.     {  
  19.         height = max(heightLeft, heightRight) + 1;  
  20.         return false;  
  21.     }  
  22. }  
10. 求二叉树的镜像
递归解法:
(1)如果二叉树为空,返回空
(2)如果二叉树不为空,求左子树和右子树的镜像,然后交换左子树和右子树
参考代码如下:
[cpp] view plaincopy
  1. BinaryTreeNode * Mirror(BinaryTreeNode * pRoot)  
  2. {  
  3.     if(pRoot == NULL) // 返回NULL  
  4.         return NULL;  
  5.     BinaryTreeNode * pLeft = Mirror(pRoot->m_pLeft); // 求左子树镜像  
  6.     BinaryTreeNode * pRight = Mirror(pRoot->m_pRight); // 求右子树镜像  
  7.         // 交换左子树和右子树  
  8.     pRoot->m_pLeft = pRight;  
  9.     pRoot->m_pRight = pLeft;  
  10.     return pRoot;  
  11. }  
11. 求二叉树中两个节点的最低公共祖先节点
递归解法:
(1)如果两个节点分别在根节点的左子树和右子树,则返回根节点
(2)如果两个节点都在左子树,则递归处理左子树;如果两个节点都在右子树,则递归处理右子树
参考代码如下:
[cpp] view plaincopy
  1. bool FindNode(BinaryTreeNode * pRoot, BinaryTreeNode * pNode)  
  2. {  
  3.     if(pRoot == NULL || pNode == NULL)  
  4.         return false;  
  5.   
  6.     if(pRoot == pNode)  
  7.         return true;  
  8.   
  9.     bool found = FindNode(pRoot->m_pLeft, pNode);  
  10.     if(!found)  
  11.         found = FindNode(pRoot->m_pRight, pNode);  
  12.   
  13.     return found;  
  14. }  
  15.   
  16. BinaryTreeNode * GetLastCommonParent(BinaryTreeNode * pRoot,   
  17.                                      BinaryTreeNode * pNode1,   
  18.                                      BinaryTreeNode * pNode2)  
  19. {  
  20.     if(FindNode(pRoot->m_pLeft, pNode1))  
  21.     {  
  22.         if(FindNode(pRoot->m_pRight, pNode2))  
  23.             return pRoot;  
  24.         else  
  25.             return GetLastCommonParent(pRoot->m_pLeft, pNode1, pNode2);  
  26.     }  
  27.     else  
  28.     {  
  29.         if(FindNode(pRoot->m_pLeft, pNode2))  
  30.             return pRoot;  
  31.         else  
  32.             return GetLastCommonParent(pRoot->m_pRight, pNode1, pNode2);  
  33.     }  
  34. }  
递归解法效率很低,有很多重复的遍历,下面看一下非递归解法。
非递归解法:
先求从根节点到两个节点的路径,然后再比较对应路径的节点就行,最后一个相同的节点也就是他们在二叉树中的最低公共祖先节点
参考代码如下:
[cpp] view plaincopy
  1. bool GetNodePath(BinaryTreeNode * pRoot, BinaryTreeNode * pNode,   
  2.                  list<BinaryTreeNode *> & path)  
  3. {  
  4.     if(pRoot == pNode)  
  5.     {     
  6.         path.push_back(pRoot);  
  7.         return true;  
  8.     }  
  9.     if(pRoot == NULL)  
  10.         return false;  
  11.     path.push_back(pRoot);  
  12.     bool found = false;  
  13.     found = GetNodePath(pRoot->m_pLeft, pNode, path);  
  14.     if(!found)  
  15.         found = GetNodePath(pRoot->m_pRight, pNode, path);  
  16.     if(!found)  
  17.         path.pop_back();  
  18.     return found;  
  19. }  
  20. BinaryTreeNode * GetLastCommonParent(BinaryTreeNode * pRoot, BinaryTreeNode * pNode1, BinaryTreeNode * pNode2)  
  21. {  
  22.     if(pRoot == NULL || pNode1 == NULL || pNode2 == NULL)  
  23.         return NULL;  
  24.     list<BinaryTreeNode*> path1;  
  25.     bool bResult1 = GetNodePath(pRoot, pNode1, path1);  
  26.     list<BinaryTreeNode*> path2;  
  27.     bool bResult2 = GetNodePath(pRoot, pNode2, path2);  
  28.     if(!bResult1 || !bResult2)   
  29.         return NULL;  
  30.     BinaryTreeNode * pLast = NULL;  
  31.     list<BinaryTreeNode*>::const_iterator iter1 = path1.begin();  
  32.     list<BinaryTreeNode*>::const_iterator iter2 = path2.begin();  
  33.     while(iter1 != path1.end() && iter2 != path2.end())  
  34.     {  
  35.         if(*iter1 == *iter2)  
  36.             pLast = *iter1;  
  37.         else  
  38.             break;  
  39.         iter1++;  
  40.         iter2++;  
  41.     }  
  42.     return pLast;  
  43. }  

在上述算法的基础上稍加变化即可求二叉树中任意两个节点的距离了。
12. 求二叉树中节点的最大距离
即二叉树中相距最远的两个节点之间的距离。
递归解法:
(1)如果二叉树为空,返回0,同时记录左子树和右子树的深度,都为0
(2)如果二叉树不为空,最大距离要么是左子树中的最大距离,要么是右子树中的最大距离,要么是左子树节点中到根节点的最大距离+右子树节点中到根节点的最大距离,同时记录左子树和右子树节点中到根节点的最大距离。

参考代码如下:

[cpp] view plaincopy
  1. int GetMaxDistance(BinaryTreeNode * pRoot, int & maxLeft, int & maxRight)  
  2. {  
  3.     // maxLeft, 左子树中的节点距离根节点的最远距离  
  4.     // maxRight, 右子树中的节点距离根节点的最远距离  
  5.     if(pRoot == NULL)  
  6.     {  
  7.         maxLeft = 0;  
  8.         maxRight = 0;  
  9.         return 0;  
  10.     }  
  11.     int maxLL, maxLR, maxRL, maxRR;  
  12.     int maxDistLeft, maxDistRight;  
  13.     if(pRoot->m_pLeft != NULL)  
  14.     {  
  15.         maxDistLeft = GetMaxDistance(pRoot->m_pLeft, maxLL, maxLR);  
  16.         maxLeft = max(maxLL, maxLR) + 1;  
  17.     }  
  18.     else  
  19.     {  
  20.         maxDistLeft = 0;  
  21.         maxLeft = 0;  
  22.     }  
  23.     if(pRoot->m_pRight != NULL)  
  24.     {  
  25.         maxDistRight = GetMaxDistance(pRoot->m_pRight, maxRL, maxRR);  
  26.         maxRight = max(maxRL, maxRR) + 1;  
  27.     }  
  28.     else  
  29.     {  
  30.         maxDistRight = 0;  
  31.         maxRight = 0;  
  32.     }  
  33.     return max(max(maxDistLeft, maxDistRight), maxLeft+maxRight);  
  34. }  
13. 由前序遍历序列和中序遍历序列重建二叉树
二叉树前序遍历序列中,第一个元素总是树的根节点的值。中序遍历序列中,左子树的节点的值位于根节点的值的左边,右子树的节点的值位
于根节点的值的右边。
递归解法:
(1)如果前序遍历为空或中序遍历为空或节点个数小于等于0,返回NULL。
(2)创建根节点。 前序遍历的第一个数据就是根节点的数据,在中序遍历中找到根节点的位置,可分别得知左子树和右子树的前序和中序遍

历序列,重建左右子树。

题目描述:

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并输出它的后序遍历序列。

输入:

输入可能包含多个测试样例,对于每个测试案例,

输入的第一行为一个整数n(1<=n<=1000):代表二叉树的节点个数。

输入的第二行包括n个整数(其中每个元素a的范围为(1<=a<=1000)):代表二叉树的前序遍历序列。

输入的第三行包括n个整数(其中每个元素a的范围为(1<=a<=1000)):代表二叉树的中序遍历序列。

输出:

对应每个测试案例,输出一行:

如果题目中所给的前序和中序遍历序列能构成一棵二叉树,则输出n个整数,代表二叉树的后序遍历序列,每个元素后面都有空格。

如果题目中所给的前序和中序遍历序列不能构成一棵二叉树,则输出”No”。

样例输入:
81 2 4 7 3 5 6 84 7 2 1 5 3 8 681 2 4 7 3 5 6 84 1 2 7 5 3 8 6
样例输出:
7 4 2 5 8 6 3 1 No

    采用递归的方式重构二叉树,关键是要考虑到一些特殊情况,比如:只有根节点的二叉树、只有左子树或只有右子树的二叉树以及二叉树根节点为NULL、前序中序序列不匹配导致不能重构二叉树等。

    AC代码如下(一直在如何实现判断能否重构二叉树的地方徘徊,在九度论坛里大致看了下,借鉴了下各位前辈的思路:定义一个全局bool变量,用来跟踪判断能够重构):

[cpp] view plaincopy
在CODE上查看代码片派生到我的代码片
  1. #include<stdio.h>  
  2. #include<stdlib.h>  
  3.   
  4. typedef int ElemType;  
  5. typedef struct BTNode   
  6. {  
  7.     ElemType data;  
  8.     struct BTNode *left;  
  9.     struct BTNode *right;  
  10. }BTNode,*BTree;  
  11.   
  12. bool CanReBuild;    //用来标示是否能够重构二叉树  
  13.   
  14. /* 
  15. pre为前序遍历数组,inv为中序遍历数组,len为数组长度,重构二叉树*ppTree 
  16. */  
  17. void RebuildBinaryTree(BTree *ppTree,int *pre,int *inv,int len)  
  18. {  
  19.     if(p

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

无数踩坑系列(1)--Brightness Controller

Brightness Controller1.尝试找回系统自带亮度调节条1.1 配置grub文件&#xff0c;无效1.2 使用命令调节屏幕亮度&#xff0c;无效2.安装应用程序Brightness Controller2.1许多博文都写出了如下方案&#xff0c;无效&#xff1a;2.2 github 手动安装https://github.com/LordAmi…

springboot2——MyBatis入门

原生缺陷: 数据库dao层操作缺陷: ①jdbc的增删改查代码的冗余过大&#xff0c;查询的时候需要遍历。 ②Sql语句和数据库相关参数和代码的耦合性过高。 解决:使用Mybatis 业务层缺陷: ①业务层和数据…

Linux(4)-资源-du,top,free,gnome

Linux终端命令1.磁盘资源1.1 df -hl1.2 du1.3 统计文件数量2.缓存资源2.1 top2.2 free -m3.Gnome3.1系统监视器-gnome-system-monitor3.2 截屏--screenshot查看文件系统资源的一些命令1.磁盘资源 1.1 df -hl 查看分区磁盘使情况 硬盘空间不够时&#xff0c;跑程序会报错&…

redis——Java整合

redis官网 微软写的windows下的redis 我们下载第一个 额案后基本一路默认就行了 安装后&#xff0c;服务自动启动&#xff0c;以后也不用自动启动。 出现这个表示我们连接上了。 redis命令参考链接 Spring整合Redis 引入依赖 - spring-boot-starter-data-redis <depend…

一文理解KMP算法

一文理解KMP算法 作者&#xff1a;July 时间&#xff1a;最初写于2011年12月&#xff0c;2014年7月21日晚10点 全部删除重写成此文&#xff0c;随后的半个多月不断反复改进。后收录于新书《编程之法&#xff1a;面试和算法心得》第4.4节中。 1. 引言 本KMP原文最初写于2年多前的…

小猫的java基础知识点汇总(下)

1、线程和进程有什么区别&#xff1f; 进程是操作系统资源分配的基本单位&#xff0c;而线程是任务调度和执行的基本单位 线程是进程的子集&#xff0c;一个进程可以有很多线程&#xff0c;每条线程并行执行不同的任务。 不同的进程使用不同的内存空间&#xff0c;而所有的线…

小猫的java基础知识点汇总(上)

1、一个".java"源文件中是否可以包括多个类&#xff08;不是内部类&#xff09;&#xff1f;有什么限制&#xff1f; 可以有多个类&#xff0c;但只能有一个public的类&#xff0c;并且public的类名必须与文件名相一致。 2、short s1 1; s1 s11; 有没有错&#xff…

后端 分页组件实例

/*** 分页相关信息*/ public class Page {//当前页码private int current1;//显示的上限private int limit10;//数据总数//用于计算页数private int rows;//路径private String path;public int getCurrent() {return current;}public void setCurrent(int current) {if (curre…

大数据学习(07)--MapReduce

文章目录目录1.MapReduce介绍1.1 什么是分布式并行编程&#xff1f;1.2 MapReduce模型介绍1.3 map和reduce函数2.MapReduce体系架构3.MapReduce工作流程3.1 概述3.2 MapReduce各个阶段介绍3.3 shuffle过程介绍3.3.1 shuffle过程简介3.3.2 map中的shuffle过程3.3.3 reduce中的sh…

Pytorch(4)-模型保存-载入-eval()

模型保存与提取1. 整个模型 保存-载入2. 仅模型参数 保存-载入3. GPU/CPU模型保存与导入4. net.eval()--固定模型随机项神经网络模型在线训练完之后需要保存下来&#xff0c;以便下次使用时可以直接导入已经训练好的模型。pytorch 提供两种方式保存模型:方式1&#xff1a;保存整…

大数据学习(08)--Hadoop中的数据仓库Hive

文章目录目录1.什么是数据仓库&#xff1f;1.1数据仓库概念1.2传统数据仓库面临的挑战1.3 Hive介绍1.4 Hive与传统数据库的对比1.5 Hive在企业中的部署与应用2.Hive系统架构3.Hive工作原理3.1 SQL转换为MapReduce作业的基本原理3.2 Hive中SQL查询转换MapReduce作业的过程4.Hive…

dubbo知识点总结 持续更新

Dubbo 支持哪些协议&#xff0c;每种协议的应用场景&#xff0c;优缺点&#xff1f;  dubbo&#xff1a; 单一长连接和 NIO 异步通讯&#xff0c;适合大并发小数据量的服务调用&#xff0c; 以及消费者远大于提供者。传输协议 TCP&#xff0c;异步&#xff0c;Hessian 序列化…

无限踩坑系列(6)-mySQL数据库链接错误

mySQL数据库链接错误错误1错误2长链接短连接应用场景需要一直访问mySQL数据库&#xff0c;遇到如下错误&#xff1a;错误1 释放已经释放的数据库链接conn.&#xff0c;或者&#xff0c;操作已经释放的数据库链接conn.或者失去链接后再操作数据库都可能会报这个错误 aise err.I…

初探函数式编程和面对对象式编程

文章目录目录1.函数式编程和面向对象编程概念1.1 函数式编程1.2 面向对象编程2.函数式编程和面向对象编程的优缺点2.1 函数式编程优点缺点2.2 面对对象编程优点缺点3.为什么在并行计算中函数式编程比较好3.1 什么是并行计算3.2 函数式编程兴起原因目录 1.函数式编程和面向对象…

搜索详解

搜索 一.dfs和bfs简介 深度优先遍历(dfs) 本质&#xff1a; 遍历每一个点。 遍历流程&#xff1a; 从起点开始&#xff0c;在其一条分支上一条路走到黑&#xff0c;走不通了就往回走&#xff0c;只要当前有分支就继续往下走&#xff0c;直到将所有的点遍历一遍。 剪枝&a…

特征工程总结

目录1 特征工程是什么&#xff1f; 2 数据预处理   2.1 无量纲化     2.1.1 标准化     2.1.2 区间缩放法     2.1.3 标准化与归一化的区别   2.2 对定量特征二值化   2.3 对定性特征哑编码   2.4 缺失值计算   2.5 数据变换 3 特征选择   3.1 Filter …

Jmeter测试并发https请求成功了

Jmeter2.4 如何测试多个并发https请求&#xff0c;终于成功了借此机会分享给大家 首先要安装jmeter2.4版本的&#xff0c;而且不建议大家使用badboy&#xff0c;因为这存在兼容性问题。对于安装&#xff0c;我就不讲了&#xff0c;我就说说如何测试https&#xff0c;想必大家都…

关系数据库——sql基础1定义

关系数据库标准语言SQL 基本概念 SQL语言是一个功能极强的关系数据库语言。同时也是一种介于关系代数与关系演算之间的结构化查询语言&#xff08;Structured Query Language&#xff09;&#xff0c;其功能包括数据定义、数据查询、数据操纵和数据控制。 SQL的特点&#xff…

大数据学习(09)--Hadoop2.0介绍

文章目录目录1.Hadoop的发展与优化1.1 Hadoop1.0 的不足与局限1.2 Hadoop2.0 的改进与提升2.HDFS2.0 的新特性2.1 HDFS HA2.2 HDFS Federation3. 新一代的资源管理器YARN3.1 MapReduce1.0 缺陷3.2 YARN的设计思路3.3 YARN 体系结构3.4 YARN工作流程3.5 YARN框架与MapReduce1.0框…

Java多线程常用方法

start()与run() start() 启动线程并执行相应的run()方法 run() 子线程要执行的代码放入run()方法 getName()和setName() getName() 获取此线程的名字 setName() 设置此线程的名字 isAlive() 是判断当前线程是否处于活动状态。活动状态就是已经启动尚未终止。 curren…