二叉树C语言实现递归的进一步提升确定不来肝一篇?_c语言假设二叉树采用二叉链表存储结构存放,结点值为int类型,设计一个递归算法-程序员宅基地

技术标签: 算法  c语言  二叉树  后端  数据结构  

在这里插入图片描述

前言

由于二叉树是数据结构中偏难的一块,这里我们先熟悉二叉树的结构,再具体来实现一颗二叉树,采用手动构建二叉树的方式,帮助大家进一步理解

构建一颗二叉树

呈现的是一个树型结构
在这里插入图片描述

BTNode *BinaryTreeCreate(char ch) 
{
    
	BTNode *newNode = (BTNode *)malloc(sizeof(BTNode));
	newNode->data = ch;
	newNode->left = NULL;
	newNode->right = NULL;

	return newNode;
}

void func() 
{
    
	BTNode* A = BinaryTreeCreate('A');
	BTNode* B = BinaryTreeCreate('B');
	BTNode* C = BinaryTreeCreate('C');
	BTNode* D = BinaryTreeCreate('D');
	BTNode* E = BinaryTreeCreate('E');
	BTNode* F = BinaryTreeCreate('F');
	

	A->left = B;
	A->right = C;
	B->left = D;
	C->left = E;
	C->right = F;
	
}

构建了结点与结点之间的父子关系,从代码中可以看到A的左右子树是B和C,B的左子树是D,C的左右子树是E和F,剩余的默认给NULL值,在创建结点的时候就已经初始化好了,那如果想要呈现出遍历顺序呢。

声明

#pragma once
#include<memory.h>
#include<stdbool.h>
#include<stdlib.h>
#include<stdio.h>
#include"Queue.h"

typedef char BTDataType;
typedef struct BTNode 
{
    
	struct BTNode *left;
	struct BTNode *right;
	BTDataType data;
}BTNode;

//创建结点
BTNode *BinaryTreeCreate(char ch);
//后序遍历	
void PrevOrder(BTNode *root);
//中序遍历
void Inorder(BTNode *root);
//后序遍历
void Postorder(BTNode *root);
//树结点的个数
int BinaryTreeSize(BTNode *root);
//求叶子结点的个数
int BinaryleafSize(BTNode* root);
//求二叉树的第k层结点个数
int BinaryKSize(BTNode* root,int k);
//查找值为val的结点
BTNode* BinaryFind(BTNode* root,char ch);
//广度优先遍历二叉树
void TreeLevelorder(BTNode* root);
//二叉树的销毁
void BinaryTreeDestroy(BTNode* root);
//判断一颗树是不是完全二叉树
bool BinaryTreecomp(BTNode* root);

实现

#include"BinaryTree.h"

BTNode *BinaryTreeCreate(char ch) 
{
    
	
	BTNode *newNode = (BTNode *)malloc(sizeof(BTNode));
	assert(newNode);
	newNode->data = ch;
	newNode->left = NULL;
	newNode->right = NULL;

	return newNode;
}


//后序遍历	
void PrevOrder(BTNode *root) 
{
    
	if (root == NULL) 
	{
    
		printf("NULL ");
		return;
	}
	else 
	{
    
		PrevOrder(root->left);
		PrevOrder(root->right);
		printf("%c ",root->data);
	}
	
}

//中序遍历
void Inorder(BTNode *root) 
{
    
	if (root == NULL)
	{
    
		printf("NULL ");
		return;
	}
	else
	{
    
		PrevOrder(root->left);
		printf("%c ", root->data);
		PrevOrder(root->right);
		
	}
}
//后序遍历
void Postorder(BTNode *root) 
{
    
	if (root == NULL)
	{
    
		printf("NULL ");
		return;
	}
	else
	{
    
		printf("%c ", root->data);
		PrevOrder(root->left);
		PrevOrder(root->right);
	}
}

//树结点的个数
int BinaryTreeSize(BTNode *root) 
{
    
	return root == NULL ? 0 : BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}

//求叶子结点的个数
int BinaryleafSize(BTNode *root)
{
    
	if (root == NULL) 
	{
    
		return 0;
	}
	else if(!root->left && !root->right)
	{
    
		return 1;
	}
	else 
	{
    
		return BinaryleafSize(root->left) + BinaryleafSize(root->right);
	}
}

//求二叉树的第k层结点个数
int BinaryKSize(BTNode* root,int k) 
{
    
	if (!root)
	{
    
		return 0;
	}	
	else if (k == 1) 
	{
    
		return 1;
	}
	else 
	{
    
		return BinaryKSize(root->left, k - 1) 
			+ BinaryKSize(root->right, k - 1);
	}
}
//查找值为val的结点
BTNode* BinaryFind(BTNode* root,char ch) 
{
    
	if (!root) 
	{
    
		return NULL;
	}
	
	if (root->data == ch) 
	{
    
		return root;
	}
	BTNode* leftNode = BinaryFind(root->left,ch);
	BTNode* rightNode = BinaryFind(root->right, ch);
	if (leftNode ) 
	{
    
		return leftNode;
	}	
	if(rightNode)
	{
    
		return rightNode;
	}

	return NULL;
}

void TreeLevelorder(BTNode* root)
{
    
	assert(root);
	Queue q;
	QueueInit(&q);
	QueuePush(&q,root);
	while (!QueueEmpty(&q)) 
	{
    
		//取出队头的数据
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		printf("%c ",front->data);
		//接着入,出一层父亲结点,带进去子节点
		if (front->left != NULL) 
		{
    
			QueuePush(&q, front->left);
		}
		if (front->right != NULL)
		{
    
			QueuePush(&q, front->right);
		}
	}
	printf("\n");
	QueueDestroy(&q);
}

//二叉树的销毁
void BinaryTreeDestroy(BTNode* root) 
{
    
	if (!root) 
	{
    
		return;
	}
	BinaryTreeDestroy(root->left);
	BinaryTreeDestroy(root->right);
	free(root);
}

//判断一颗树是不是完全二叉树
bool BinaryTreecomp(BTNode* root) 
{
    
	Queue q;
	QueueInit(&q);
	QueuePush(&q, root);
	while (!QueueEmpty(&q)) 
	{
    
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		if (!front) 
		{
    
			break;
		}
		QueuePush(&q, front->left);
		QueuePush(&q, front->right);
	}
	while (!QueueEmpty(&q))
	{
    
		BTNode* front = QueueFront(&q);
		if (front)
		{
    
			return false;
		}
	}
	return true;
	
}

二叉树的遍历

我们知道二叉树有三种遍历方式,为了遍历前面构建出来的树型结构这三种遍历方式我们都采用

按照规则,二叉树的遍历有:前序/中序/后序的递归结构遍历:

  1. 前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点的操作发生在遍历其左右子树之前。
  2. 中序遍历(Inorder Traversal)——访问根结点的操作发生在遍历其左右子树之中(间)。
  3. 后序遍历(Postorder Traversal)——访问根结点的操作发生在遍历其左右子树之后。由于被访问的结点必是某子树的根,所以N(Node)、L(Left subtree)和R(Right subtree)又可解释为根、根的左子树和根的右子树。NLR、LNR和LRN分别又称为先根遍历、中根遍历和后根遍历。

总结:

  • 前序遍历
    根 --> 左子树 -->右子树
  • 中序遍历
    左子树 --> 根 --> 右子树
  • 后序遍历
    左子树 --> 右子树 --> 根
//后序遍历	
void PrevOrder(BTNode *root) 
{
    
	if (root == NULL) 
	{
    
		printf("NULL ");
		return;
	}
	else 
	{
    
		PrevOrder(root->left);
		PrevOrder(root->right);
		printf("%d ",root->data);
	}
}

//中序遍历
void Inorder(BTNode *root) 
{
    
	if (root == NULL)
	{
    
		printf("NULL ");
		return;
	}
	else
	{
    
		PrevOrder(root->left);
		printf("%d ", root->data);
		PrevOrder(root->right);
		
	}
}
//前序遍历
void Postorder(BTNode *root) 
{
    
	if (root == NULL)
	{
    
		printf("NULL ");
		return;
	}
	else
	{
    
		printf("%d ", root->data);
		PrevOrder(root->left);
		PrevOrder(root->right);
	}
}

在这里插入图片描述

求一颗二叉树的结点个数

int BinaryTreeSize(BTNode *root) 
{
    
	return root == NULL ? 0 : BinaryTreeSize(root->left)
	 + BinaryTreeSize(root->right) + 1;
}

后序思想,递归左右子树,如果该结点为空就返回0,不为空就返回左右子树的结点个数相加的和值 + 1,这里的+ 1 操作是用作计数根结点的(每一个真实结点),其实看作是一个二叉树的后序遍历也不为过

求二叉树叶子结点的个数

//求叶子结点的个数
int BinaryleafSize(BTNode *root)
{
    
	if (root == NULL) 
	{
    
		return 0;
	}
	else if(!root->left && !root->right)
	{
    
		return 1;
	}
	else 
	{
    
		return BinaryleafSize(root->left) 
		+ BinaryleafSize(root->right);
	}
}

叶子结点表示的是没有孩子的结点,当遍历一颗树不断的往下递归,总会遇到度为0的结点,而这个结点的就是作为这颗树的叶子结点,在这里可以将一颗大树看成是多颗小树,计算出多颗小树的叶子结点个数就是整个大树的叶子结点
在这里插入图片描述

求二叉树第K层结点的个数

//求二叉树的第k层结点个数
int BinaryKSize(BTNode* root,int k) 
{
    
	if (!root)
	{
    
		return 0;
	}	
	else if (k == 1) 
	{
    
		return 1;
	}
	else 
	{
    
		return BinaryKSize(root->left, k - 1) 
			+ BinaryKSize(root->right, k - 1);
	}
}

在这里插入图片描述

想求出第k层的结点的个数只需要将这一层的结点相加得到的结果就是这一层的结点个数

查找

BTNode* BinaryFind(BTNode* root,char ch) 
{
    
	if (!root) 
	{
    
		return NULL;
	}
	
	if (root->data == ch) 
	{
    
		return root;
	}
	BTNode* leftNode = BinaryFind(root->left,ch);
	BTNode* rightNode = BinaryFind(root->right, ch);
	if (leftNode ) 
	{
    
		return leftNode;
	}	
	if(rightNode)
	{
    
		return rightNode;
	}
	return NULL;
}

到树的左右子树中去查找该结点如果找到就返回该节点,否则继续查找,直到走到NULL的位置,那就返回NULL

在这里插入图片描述

数的层序遍历广度优先

英文缩写为BFS即Breadth FirstSearch。其过程检验来说是对每一层节点依次访问,访问完一层进入下一层,而且每个节点只能访问一次。这里用队列来实现这个遍历方式,还是由于队列先进先出的特性,
实现思路:
先将根入队列,将父亲pop出去后再入孩子,打印父亲的值,那么这一层就已经遍历完了,紧接着就可以继续入下一层,父亲每次pop出去的时让父亲的孩子入队,
在这里插入图片描述

void TreeLevelorder(BTNode* root)
{
    
	assert(root);
	Queue q;
	QueueInit(&q);
	QueuePush(&q,root);
	while (!QueueEmpty(&q)) 
	{
    
		//取出队头的数据
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		printf("%c ",front->data);
		//接着入,出一层父亲结点,带进去子节点
		if (front->left != NULL) 
		{
    
			QueuePush(&q, front->left);
		}
		if (front->right != NULL)
		{
    
			QueuePush(&q, front->right);
		}
	}
	QueueDestroy(&q);
}

销毁

实现思路:后序遍历,从最后一个NULL位置开始边回退,返回它的上一层,释放这个结点

//二叉树的销毁
void BinaryTreeDestroy(BTNode* root) 
{
    
	if (!root) 
	{
    
		return;
	}
	BinaryTreeDestroy(root->left);
	BinaryTreeDestroy(root->right);
	free(root);
}

判断完全二叉树

在这里插入图片描述
首先我们得有完全二叉树的概念,完全二叉树的最后一层结点个数可以不满,但是必须是从左到右连续的,那么看上面的图,你觉得他会是完全二叉树吗,左边是,右边不是,原因不是连续的,如果接着采用层序遍历的思路搞定这个,还是比较简单的,

//判断一颗树是不是完全二叉树
/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 *	TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 * };
 */
class Solution {
    
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param root TreeNode类 
     * @return bool布尔型
     */
    bool isCompleteTree(TreeNode* root) {
    
        // write code here
        if(!root) return false;
        queue<TreeNode *> q;
        q.push(root);
        while(!q.empty()){
    
            auto node = q.front();
            q.pop();
            if(!node) break;
            if(node->left)  q.push(node->left); 
            else q.push(nullptr);
            if(node->right) q.push(node->right);
            else q.push(nullptr); 
        }
        while(!q.empty()){
    
            auto node = q.front();
            if(node != nullptr) return false;
            q.pop();
          
        }
        return true;
    }
};

oj练习

  1. 单值二叉树
    链接: link.
    题目描述:

如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树。只有给定的树是单值二叉树时,才返回 true;否则返回 false
在这里插入图片描述

实现思路:
如果左孩子跟右孩子的值都与父亲的值相等,那么他就是单值二叉树,再往下递归的过程中只需要将值不等就直接返回false,否则就继续递归下去直到整个树遍历完了,那么就是单值二叉树

bool isUnivalTree(struct TreeNode* root){
    

    if(!root)
    {
    
        return true;
    }
	//判断左孩子跟父亲是否相等,不等返回false
    if(root->left && root->left->val != root->val)
    {
    
        return false;
    }
    //判断右孩子是否和父亲相等,不等返回false
    else if(root->right && root->right->val != root->val)
    {
    
        return false;
    }
    //相等继续往下递归,
    else
    {
    
        return isUnivalTree(root->left) 
        	&& isUnivalTree(root->right);
    }
}
  1. 二叉树的前序遍历
    链接: link.
    原题描述:

给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

实现接口

int* preorderTraversal(struct TreeNode* root, 
						int* returnSize)
{
    

}

实现思路:

前序遍历这颗二叉树,将二叉树每个结点的值存放进数组中,最后返回该数组,值得注意的是这个接口的参数,*returnsize,到底需要开辟多大的空间来存放二叉树的值,可以通过遍历二叉树求出它的结点个数,malloc出等大的数组出来,存放结点的值

	//计算结点的个数
 int TreeSize(struct TreeNode* root)
 {
    
     return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
 }
//以前序遍历的方式,将树的值存放到数组中
void _preoder(struct TreeNode* root,int *retArr, int *pi)
{
    
    if(!root)
    {
    
        return;
    }
    else
    {
    
        retArr[(*pi)++] = root->val;
        _preoder(root->left,retArr,pi);
        _preoder(root->right,retArr,pi);
    }
}       

int* preorderTraversal(struct TreeNode* root, int* returnSize){
    
    *returnSize = TreeSize(root);
    int *retArr = (int *)malloc(sizeof(int) * (* returnSize));
    int i = 0;
    _preoder(root,retArr,&i);
    return retArr;
}
  1. 相同的树
    链接: link.
    题目描述:

给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
在这里插入图片描述
实现思路:
能先想到的就是这两颗树都是空树,那么他们就是相同的,还有一种情况就是一个树的结点多,一个树的结点少,少的先被遍历完,所以他们肯定不相同,剩下的就是判断值了,比较两颗树的左右子树的值是否是相等的

bool isSameTree(struct TreeNode* p, struct TreeNode* q){
    
    if(p == NULL && q == NULL)
    {
    
        return true;
    }
    if(p == NULL || q == NULL)
    {
        
        return false;
    }
    else if(p->val != q->val)
    {
    
        return false;
    }
    else
    {
    
        return isSameTree(p->left,q->left) && isSameTree(p->right,q->right);
    }
}
  1. 对称二叉树
    链接: link.
    题目描述:
    给定一个二叉树,检查它是否是镜像对称的。
    在这里插入图片描述
    实现思路:

从树的第二层开始,将每一层的根划分出两颗左右子树,比较根再分别将两颗子树的左孩子和右孩子比较,右孩子和左孩子比较,如果相同就返回true

bool _issymmetry(struct TreeNode *Treeleft, struct TreeNode* Treeright)
{
    
	
    if(!Treeleft && !Treeright) 
    {
    
        return true;
    }
    if(!Treeleft || !Treeright)
    {
    
        return false;
    }
    else if(Treeleft->val != Treeright->val)
    {
    
        return false;
    }
   
    return _issymmetry(Treeleft->left,Treeright->right) 
    && _issymmetry(Treeleft->right,Treeright->left) ;
}

bool isSymmetric(struct TreeNode* root){
    
    if(!root)
    {
    
        return true;
    }
    return _issymmetry(root->left,root->right);
}
  1. 翻转二叉树
    链接: link.

题目描述:
翻转一棵二叉树。
在这里插入图片描述
实现思路:

递归到最后一层开始再往回返的过程,备份根的左右孩子,回退到根的时候交换左右孩子的位置

struct TreeNode* invertTree(struct TreeNode* root){
    
    if(!root)
    return NULL;

    struct TreeNode* left = invertTree(root->left);
    struct TreeNode* right = invertTree(root->right);
    root->left = right;
    root->right = left;
    return root;
}
  1. 另一棵树的子树
    链接: link.

给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false。

二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。

在这里插入图片描述

实现思路:
从root中选出每一个根看作一颗子树去和subroot这颗子树比较,如果他们,左右子树都相等了就返回true,如果不相等继续从root中找下一个根

bool _issymmetry(struct TreeNode *root, 
struct TreeNode* subRoot)
{
    

    if(!root && !subRoot)
        return true;
    if(!root || !subRoot)   
        return false;
  
    else if(root->val != subRoot->val)
        return false;
    
    return _issymmetry(root->left,subRoot->left)
     && _issymmetry(root->right,subRoot->right);
}

bool isSubtree(struct TreeNode* root, 
struct TreeNode* subRoot){
    

   if(!root)
   return false;

   if(_issymmetry(root,subRoot))
   return true;
   //寻找下一个根比较是否与subRoot相等
   return isSubtree(root->left,subRoot)
    || isSubtree(root->right,subRoot);
}
  1. 平衡二叉树
    链接: link.
    给定一个二叉树,判断它是否是高度平衡的二叉树。

题目描述:

本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。

实现思路:
大问题化成小问题的思路,要想判断是不是平衡二叉树,就得把整个树拆分成多颗子树,去判断左右子树的高度差是否 < 2,分别求出n颗左右子树的深度,如果他们的差距 < 2 就满足,直到把整个树遍历完就返回true,这里采用的遍历方式是后序遍历

bool isbalance(struct TreeNode* root, int *pi)
{
    
    if(!root)
    {
    
        *pi = 0;
        return true;
    }
    int leftheight = 0;
    if(isbalance(root->left,&leftheight) == false)
    return false;

    int rightheight = 0;
    if(isbalance(root->right,&rightheight) == false)
    return false;

    *pi = fmax(leftheight,rightheight) + 1;

    return abs(leftheight - rightheight) < 2;
}

bool isBalanced(struct TreeNode* root){
    
    if(!root)
    return true;

    int i = 0;
    return isbalance(root,&i);
}

KY11 二叉树遍历
链接: link.
原题描述:
编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后,再对二叉树进行中序遍历,输出遍历结果。

在这里插入图片描述
根据题意手动还原出来的二叉树应该是这样的,满足先序遍历的结构

实现思路:
把字符串存放进一个数组中,每次遍历这个数组,取出一个字符创建结点,从上往下递归,不断创建左右孩子,当遇到#的时候就表示这个结点是叶子,那就返回它的上一层,它的上一层就是根,把叶子当作根的孩子,往上返回,不断创建父子关系,当左子树递归完了就去递归右子树,直到整个树创建出来。

#include<stdio.h>
typedef char BTNodeType;
typedef struct BTNode
{
    
   struct BTNode *left;
   struct BTNode *right;
   BTNodeType data;
    
}BTNode;

BTNode *BTNodecreate(char *str,int *pi)
{
    
    if(str[*pi] == '#')
    {
    
        (*pi)++;
        return NULL;
    }
    //取字符创建结点
    BTNode* root = (BTNode *)malloc(sizeof(BTNode));
    root->data = str[(*pi)++];
    //创建左右孩子
    root->left = BTNodecreate(str, pi);
    root->right = BTNodecreate(str, pi);
    return root;
}
//中序遍历
void inorder(BTNode *root)
{
    
    if(!root)
    {
    
        return ;
    }
    
    inorder(root->left);
    printf("%c ",root->data);
 
    inorder(root->right);
}

int main()
{
    
    int i = 0;
    char arr[100] = {
    0};
    scanf("%s",arr);
    BTNode *root = BTNodecreate(arr,&i);
    
    inorder(root);
   
    return 0;
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_53421868/article/details/120750178

智能推荐

VSCode跳出右括号_vscode跳出括号-程序员宅基地

文章浏览阅读2w次,点赞26次,收藏18次。VSCode自动完成功能会在我们打左括号的时候自动完成右括号,可是,非常郁闷的是,在这个编辑状态下,却无法像其他编辑器一样通过按Tab或Enter键跳出右括号到行尾。 虽然VSCode有强大的按键自定义功能,但初学者看起来还是头晕。 而且居然百度不到,故起此贴。在这个Issue下找到相对简单的解决方法,就是安装Tabout插件。 https://github.com/Microso......_vscode跳出括号

tftp工具使用说明-程序员宅基地

文章浏览阅读8k次。tftp工具使用说明1.tftp工具使用说明  FTP的意思是文件传输协议,而TFTP中的第一个T是Trivial,意思是简单的,所以TFTP用来做简单的文件传输是比较适合的。  在PXE简介及使用说明中已经介绍过TFTPD64,它就是一个简单好用的TFTP工具。这里在Windows上打开一个TFTPD64应用,并作为服务器,然后在另外的一台电脑上与该服务器进行交互来获取文件。2. 命令使用操作   如果Ubuntu上没有此工具,需要安装一下,   查看是否有此工具:tftp   安装此工_tftp工具

lda主题模型困惑度_nlp中的主题模型-程序员宅基地

文章浏览阅读755次。本文对nlp中一个极为重要的模型——主题模型LDA(Latent Dirichlet Allocation)从宏观理解与数学解释两个维度进行介绍。1、LDA的宏观理解谈起LDA,自然需要引入pLSA。pLSA是用一个生成模型来建模文章的生成过程。假设有K个主题,M篇文章;对语料库中的任意文章d,假设该文章有N个词,则对于其中的每一个词,我们首先选择一个主题z,然后在当前主题的基础上生成一个词w。生..._查看lda困惑度

汉诺塔问题详解--递归实现_汉诺塔用递归工具计算算法 han-程序员宅基地

文章浏览阅读1.1w次,点赞141次,收藏331次。汉诺塔问题详解--递归实现汉诺塔问题来源:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。思考:有三根柱子(A,B,C)。A柱子上面套着n个圆盘。这些圆盘..._汉诺塔用递归工具计算算法 han

Abaqus&CST仿真软件功能对比简介-程序员宅基地

文章浏览阅读878次,点赞12次,收藏13次。并拥有各种类型的材料模型库,可以模拟典型工程材料的性能,其中包括金属、橡胶、高分子材料、复合材料、钢筋混凝土、可压缩超弹性泡沫材料以及土壤和岩石等地质材料,作为通用的模拟工具, ABAQUS 除了能解决大量结构(应力 / 位移)问题,还可以模拟其他工程领域的许多问题,例如热传导、质量扩散、热电耦合分析、声学分析、岩土力学分析(流体渗透 / 应力耦合分析)及压电介质分析。用户自定义功能,用户界面的定制,这些灵活的手段可以更好地加入用户的想法,使得用户有更多的选择以减少分析时间。和设计工具提供了链接接口。

ICMP 协议_qt实现icmp协议-程序员宅基地

文章浏览阅读547次。首先,向目的服务器上执行ping命令,主机会构建一个 ICMP 回显请求消息数据包(类型是8,代码是0),在这个回显请求数据包中,除了类型和代码字段,还被追加了标识符和序号字段。所以在 IP 数据包中如果协议类型字段的值是 1 的话,就表示 IP 数据是 ICMP 报文。当10.0.0.1送到 回显请求数据包后,10.0.0.3就会向发送方10.0.0.1发送回显应答(类型是0,代码是0),这个 ICMP 回显应答数据包在 IP 层来看,与被送来的回显请求数据包基本上一样。ICMP协议的类型分为两大类,_qt实现icmp协议

随便推点

键盘VK键值(java键盘监听)_java键盘 vk-程序员宅基地

文章浏览阅读4.7k次,点赞2次,收藏16次。键盘VK键值列表/* Virtual Keys, Standard Set*/VK_LBUTTON 0x01VK_RBUTTON 0x02VK_CANCEL 0x03VK_MBUTTO..._java键盘 vk

大学十年-程序员宅基地

文章浏览阅读2.3k次。 我要对年轻的朋友们说两句肺腑之言:  一、主动去创造环境,否则你无法设计人生。  二、生活和工作要充满激情,否则你无法体会到淋漓尽致的欢乐与痛苦。    写此文使我很为难,一是担心读者误以为我轻浮得现在就开始写自传,二是担心朋友们误以为我得了绝症而早早留下遗作。   不论是落俗套还是不落俗套地评价,我在大学十年里都是出类拔萃的好学生。并且一直以来我对朋友们和一些低年级的学生们都有_大学十年

基于鲸鱼算法优化ElM神经网络实现数据分类附matlab代码_一种全局搜索策略的鲸鱼优化算法elm-程序员宅基地

文章浏览阅读49次。在当今信息时代,数据分类是一项重要的任务,对于许多领域的研究和应用都具有关键性的作用。为了实现高效准确的数据分类,许多机器学习算法被提出和应用。其中,鲸鱼算法和极限学习机(ElM)神经网络是两个备受关注的技术。本文将介绍鲸鱼算法优化ElM神经网络在数据分类中的应用。鲸鱼算法是一种启发式优化算法,灵感来源于鲸鱼的觅食行为。鲸鱼通过个体行为和社会行为的相互作用,在复杂环境中寻找最佳的食物来源。这种行为启发了鲸鱼算法的设计,使其能够在搜索空间中高效地寻找全局最优解。_一种全局搜索策略的鲸鱼优化算法elm

5G NR QC-LDPC简介(一)_ldpc编码-程序员宅基地

文章浏览阅读4.3w次,点赞19次,收藏129次。LDPC码即低密度奇偶校验码(Low Density Parity Check Code,LDPC),它由Robert G.Gallager博士于1963年提出的一类具有稀疏校验矩阵的线性分组码,不仅有逼近Shannon限的良好性能,而且译码复杂度较低, 结构灵活,是近年信道编码领域的研究热点,已广泛应用于深空通信、光纤通信、卫星数字视频和音频广播等领域。LDPC码由一个包含少量非零元素的m∗nm*nm∗n校验矩阵HHH的零空间定义。如果矩阵HHH中的非零元素仅为“1”,则将矩阵HHH的零空间所定义的LDP_ldpc编码

cipher java 长度不变_RSA加解密的java实现(及中途的各种异常情况分析)-程序员宅基地

文章浏览阅读1.2k次。RSA加密算法是一种非对称的加密算法,主要包括以下知识点:1、密钥对的获取:主要涉及到两个参数:秘钥格式、秘钥长度(1)常见秘钥格式:PKCS8(java适用)、PKCS1(其他),如果不是java平台生成的秘钥,有可能报以下错误:java.security.InvalidKeyException: invalid key format //秘钥格式不合法(2)秘钥长度:1024、2048(越长越..._javax.crypto.badpaddingexception: message is larger than modulus

电源模块自动测试系统| 电源冷热冲击测试方法是什么?-程序员宅基地

文章浏览阅读139次。电源冷热冲击测试是指将被测品在极端热、冷环境间反复转移,模拟被测品在剧烈环境变化下的变化情况,用来评估电源的耐热性和耐寒性,进而评估电气设备的性能和稳定性。

推荐文章

热门文章

相关标签