C语言代码实现平衡二叉树|图解+详细代码

点击蓝字

5f01ec8b0fa66055206ef507242d7e62.png

关注我们

来源于网络,侵删

1. 什么是平衡二叉树

平衡二叉树,我们也称【二叉平衡搜索树/AVL】,树中任何节点的两个子树的高度最大差别为1,巴拉巴拉。。。(https://baike.baidu.com/item/AVL树/10986648?fr=aladdin)

但是有个注意的点: 平衡二叉树的前提是 二叉排序树(https://baike.baidu.com/item/二叉搜索树/7077855?fr=aladdin)

这篇博客主要总结平衡二叉树,所以,二叉排序树知识不会提及,但是会用到。

如果想要看 排序二叉树调整为 平衡二叉树 旋转相关内容的,调整至 第5节。

平衡二叉树

1f1b0eb0cf3db6cebf9d043fec51f377.png

非平衡二叉树

最小不平衡子树节点为 130

左子树深度为 1,右子树深度为3 ,其差值大于1,所以不平衡

ffebd85adcca7150055e5ec31091cd10.png

2. 如何判断二叉树最小不平衡子树

最小不平衡子树为 130 这颗子树(黄色标注)

7929540b208fe50b047f404bb9e18e31.png

判定最小不平衡子树的关键就在于,判断 这棵树的左子树 和 右字数 深度之差是否大于1,若大于1 ,则证明该树不平衡

检查二叉树是否平衡函数代码实现

typedef struct {int data; // 数据节点struct TreeNode *left; // 指向左子树struct TreeNode *right; // 指向右子树
} TreeNode , *PTreeNode;// 记录平衡二叉树
bool BalanceTrue = false;
// 最小不平衡子树地址
TreeNode *rjt = NULL;// 检查二叉树是否平衡,若不平衡 BalanceTrue 为 true
int checkTreeBalance(TreeNode *root) {if (NULL == root) { return 0; }int x = checkTreeBalance(root->left);int y = checkTreeBalance(root->right);// 若检测到最小不平衡二叉树后,不进行后面的检查if (BalanceTrue) return 0;int xx = abs(x-y);if (xx > 1) {// 左子树 和 右子树 相差大于1 , 二叉树不平衡BalanceTrue = true;rjt = root;}return (x>y?x+1:y+1);
}

程序执行结果

# gcc -w -g -std=c11 BalanceTree.c 
# 
# ./a.out 
当前二叉树遍历
前序遍历: 580    130     80      160     150     158     210     1590    900     2100    1900
中序遍历: 80     130     150     158     160     210     580     900     1590    1900    2100
二叉树不平衡,不平衡子树根节点为: 130
#

3. 二叉树不平衡情况

在一颗平衡二叉树的前提下,插入和删除一个节点,都有可能会引起二叉树不平衡,不平衡的情况主要有以下四种

左左更高

8279873b9a4e5161337f7286782c2dce.png

左右更高

94ad5fc7d361c88a4e31be832e75a32f.png

右左更高

f37ceab58585edebeee2b42073c143f9.png

右右更高

62b977f9b1feb3efe1845896b1b2e496.png

4. 判断不平衡二叉树哪边高

dc395beb6a68febd034d59ca23f76976.png

b946942fdff1ab338554665e3ea49115.png

如上图红色所示,可以先根据最小不平衡二叉树左子树或者右子树高,上图所示,为右子树高,则将最小不平衡二叉树的右子树作为树根节点,继续判断子树的左子树或者右子树高。
比如上图的结果是右左较高,若进行调整的话,为 先让不平衡子树右节点的树先向右旋转,然后再向左旋转

判断不平衡二叉树哪边高代码实现

typedef struct {int data; // 数据节点struct TreeNode *left; // 指向左子树struct TreeNode *right; // 指向右子树
} TreeNode , *PTreeNode;// 记录平衡二叉树
bool BalanceTrue = false;
// 最小不平衡子树地址
TreeNode *rjt = NULL;// 返回二叉树树高
int treeHeight(TreeNode *root) {if (NULL == root) return 0;int ll = treeHeight(root->left);int rr = treeHeight(root->right);return (ll>rr?ll+1:rr+1);
}int main() {/*  构建二叉树判断平衡,获取最小不平衡子树, 将数据存入 rjt 中输出二叉树 前序/中序*/if (BalanceTrue) {printf("二叉树不平衡,不平衡子树根节点为: %d\n",rjt->data);} else {return 0;};int ll = treeHeight(rjt->left);int rr = treeHeight(rjt->right);if (1 < ll - rr) {printf("左子树高\n");TreeNode *rjt_ll = rjt->left;int child_ll = treeHeight(rjt_ll->left);int child_rr = treeHeight(rjt_ll->right);if (child_ll > child_rr) {printf("左子树更高\n");} else if (child_rr > child_ll) {printf("右字数更高");}} else if (1 <  rr - ll) {printf("右子数高\n");TreeNode *rjt_rr = rjt->right;int child_ll = treeHeight(rjt_rr->left);int child_rr = treeHeight(rjt_rr->right);if (child_ll > child_rr) {printf("左子树更高\n");} else if (child_rr > child_ll) {printf("右字数更高");}}return 0;
}

输出

# gcc BalanceTree.c -w -g -std=c11
# 
# ./a.out 
当前二叉树遍历
前序遍历:130    80      160     150     158     210
中序遍历:80     130     150     158     160     210
二叉树不平衡,不平衡子树根节点为: 130
右子数高
左子树更高
#

5. 如何调整平衡二叉树

所谓的旋转,其实是修改指针指向的值,仅此而已。

二叉树不平衡有四种情况

左左更高

原始二叉树,若要调整为平衡二叉树,需要整棵树向右旋转

323b53f8b0297e13838c7298307c0282.png

调整1:整棵树向右旋转

5f218013331f2d107c5ee57ee7126773.png

左右更高

原始二叉树,若要调整为平衡二叉树,需要 先让不平衡子树左节点先向左旋转,然后再向右旋转

f39ec78d9bda4c4a912c0f178352c0cf.png

调整1: 先让不平衡子树左节点的树先向左旋转

4f20a7d97c675477391833c51df7f436.png

调整2: 整棵树向右

89e9efb6fdbe19fea0031139164e08e4.png

右左更高

原始二叉树,若要调整为平衡二叉树,需要 先让不平衡子树右节点的树先向右旋转,然后再向左旋转

159a71b70d395808ff8f7f2565f9cafc.png

调整1: 先让不平衡子树右节点的树先向右旋转

ccac41be511d89341ead1815d01cb268.png

调整2: 整棵树向左

ff005e2da2bd49995a6efb876bbf0d9a.png

右右更高

原始二叉树,若要调整为平衡二叉树,需要 整棵树向左旋转

1b61156bb6d8fe69739ceb2c284a150b.png

调整1: 整棵树向左旋转

b1a9149a2fa94b37e7e790741aab65ec.png

全部代码

# include <stdio.h>
# include <stdbool.h>
# include <stdlib.h>
# include <math.h>typedef struct {int data; // 数据节点struct TreeNode *left; // 指向左子树struct TreeNode *right; // 指向右子树
} TreeNode , *PTreeNode;// 记录平衡二叉树
bool BalanceTrue = false;
// 最小不平衡子树地址
TreeNode *rjt = NULL;// 检查二叉树是否平衡,若不平衡 BalanceTrue 为 true
int checkTreeBalance(TreeNode *root) {if (NULL == root) { return 0; }int x = checkTreeBalance(root->left);int y = checkTreeBalance(root->right);// 若检测到最小二叉树后,不进行后面的检查if (BalanceTrue) return 0;int xx = abs(x-y);if (xx > 1) {// 左子树 和 右子树 相差大于1 , 二叉树不平衡BalanceTrue = true;rjt = root;}return (x>y?x+1:y+1);
}// 返回二叉树树高
int treeHeight(TreeNode *root) {if (NULL == root) return 0;int ll = treeHeight(root->left);int rr = treeHeight(root->right);return (ll>rr?ll+1:rr+1);
}// 父节点查询
TreeNode* queryTopData(TreeNode *root,int data) {// 空地址异常抛出if (NULL == root) return NULL;// top: 父节点 ,如果为Null, 该节点为父节点// tmp: 遍历查询节点 TreeNode *top = NULL;TreeNode *tmp = root;while (tmp != NULL) {if (data == tmp->data) {// 节点为 返回Nullif (NULL == top) return NULL;return top;}top = tmp;if (data > tmp->data) {tmp = tmp->right;} else if (data < tmp->data) {tmp = tmp->left;}}return NULL;
}// 左左旋转
//
// 不平衡二叉树
//       70
//      /   \
//    50    80
//   /  \    
//  40  60
//  /
// 30
//
// 旋转后平衡二叉树(向右旋转)
//
//    50
//  /   \
// 40    70
// /     /  \
//30   60    80
//
bool turnLL(TreeNode **root , TreeNode *notBalanceRoot) {if ((*root) != notBalanceRoot) {printf("左左旋转,非根节点\n");// 非根节点TreeNode *lleft = notBalanceRoot->left;TreeNode *lright = lleft->right;// 查找父节点TreeNode *fdata = queryTopData((*root),notBalanceRoot->data);if (NULL == fdata) return false;lleft->right = notBalanceRoot;notBalanceRoot->left = lright;if (notBalanceRoot == fdata->left) {fdata->left = lleft;} else if (notBalanceRoot == fdata->right) {fdata->right = lleft;}return true;} else {// 根节点printf("左左旋转,是根节点\n");TreeNode *lleft = notBalanceRoot->left;TreeNode *absroot = lleft;TreeNode *lright = lleft->right;lleft->right = notBalanceRoot;notBalanceRoot->left = lright;(*root) = absroot;return true;}}// 左右旋转
//不平衡二叉树
//      70
//     /   \
//    50    80
//    / \    
//   40 60
//  /   
// 55
//
//左子树向左
//      70
//     /   \
//    60    80
//    /
//   50
//  /  \    
// 40  55
//                                                           
//                                                                   
// 整棵树向右
// 
//     60
//    /   \
//   50    70
//  /  \     \
// 40  55    80
//
bool turnLR(TreeNode **root , TreeNode *notBalanceRoot) {if ((*root) != notBalanceRoot) {printf("左右旋转,非根节点");TreeNode *lleft = notBalanceRoot->left;TreeNode *leftRight = lleft->right;TreeNode *leftRightLeft = leftRight->left;// 第一次调整leftRight->left = lleft;lleft->right = leftRightLeft;notBalanceRoot->left = leftRight;// 查找父节点TreeNode *fdata = queryTopData((*root),notBalanceRoot->data);//if (NULL != fdata) printf("fdata: %d\n",fdata->data);// 第二次调整lleft = notBalanceRoot->left;leftRight = lleft->right;lleft->right = notBalanceRoot;notBalanceRoot->left = leftRight;if (notBalanceRoot == fdata->left) {fdata->left = lleft;} else if (notBalanceRoot == fdata->right) {fdata->right = lleft;}} else {printf("左右旋转,是根节点\n");TreeNode *lleft = notBalanceRoot->left;TreeNode *leftRight = lleft->right;TreeNode *leftRightLeft = leftRight->left;// 第一次调整leftRight->left = lleft;lleft->right = leftRightLeft;notBalanceRoot->left = leftRight;// 第二次调整lleft = notBalanceRoot->left;leftRight = lleft->right;lleft->right = notBalanceRoot;notBalanceRoot->left = leftRight;(*root) = lleft;}
}// 右左旋转
//不平衡二叉树
//   70
//  /  \
// 50   80
//     /  \
//    75  88
//     \
//     77
//
//左子树向右
//   70
//  /  \
// 50   75
//     /  \
//    77  80
//         \
//         88
//                                                                                                           
//                                                                                                                  
//                                                                                                                      
//整棵树向左
//     75
//    /  \
//   70  80
//  /  \   \ 
// 50  77  88 
//
bool turnRL(TreeNode **root , TreeNode *notBalanceRoot) {TreeNode *rright = notBalanceRoot->right;TreeNode *rightLeft = rright->left;TreeNode *rightLeftRight = rightLeft->right;// 第一次调整rightLeft->right = rright;rright->left = rightLeftRight;notBalanceRoot->right = rightLeft;// 查找父节点TreeNode *fdata = queryTopData((*root),notBalanceRoot->data);//if (NULL != fdata) printf("fdata: %d\n",fdata->data);// 第二次调整rright = notBalanceRoot->right;rightLeft = rright->left;rright->left = notBalanceRoot;notBalanceRoot->right = rightLeft;if ((*root) != notBalanceRoot) {printf("右左旋转,非根节点\n");if (notBalanceRoot == fdata->left) {fdata->left = rright;} else if (notBalanceRoot == fdata->right) {fdata->right = rright;}} else {printf("右左旋转,是根节点\n");(*root) = rright;}
}// 右右旋转
// 
// 不平衡二叉树
//  70
// /  \
//50   80
//    /  \
//   75  88
//      /
//     85
//
//
//
//向左旋转
//    80
//   /  \
//  70   88
// /  \   /  
//50  75 85  
bool turnRR(TreeNode **root , TreeNode *notBalanceRoot) {if ((*root) != notBalanceRoot) {printf("右右旋转,非根节点");TreeNode *rright = notBalanceRoot->right;TreeNode *rleft = rright->left;// 查找父节点TreeNode *fdata = queryTopData((*root),notBalanceRoot->data);if (NULL != fdata) printf("fdata: %d\n",fdata->data);rright->left = notBalanceRoot;notBalanceRoot->right = rleft;if (notBalanceRoot == fdata->left) {fdata->left = rright;} else if (notBalanceRoot == fdata->right) {fdata->right = rright;}				} else {// 右右旋转,是根节点printf("右右旋转,是根节点\n");TreeNode *rright = notBalanceRoot->right;TreeNode *absroot = rright;TreeNode *rleft = rright->left;rright->left = notBalanceRoot;notBalanceRoot->right = rleft;(*root) = absroot;}
}// 二叉树前序遍历
void Print1(TreeNode *root) {if (NULL == root) return;printf("%d\t",root->data);Print1(root->left);Print1(root->right);
}// 二叉树中序遍历
void Print2(TreeNode *root) {if (NULL == root) return;Print2(root->left);printf("%d\t",root->data);Print2(root->right);
}// 二叉树后续遍历
void Print3(TreeNode *root) {if (NULL == root) return;Print3(root->left);Print3(root->right);printf("%d\t",root->data);
}// 插入二叉树节点
TreeNode* addNode(TreeNode *root,int data) {if (NULL == root) {// 头节点插入TreeNode *Node = (TreeNode *)malloc(sizeof(TreeNode));if (NULL == Node) {printf("新节点申请内存失败\n");return NULL;}Node->data = data;return Node;}TreeNode *tmp = root;TreeNode *top = NULL;// 找到合适的最尾巴节点while (NULL != tmp) {top = tmp;if (tmp->data == data) {printf("已经存在该节点,节点地址: %p\n",tmp);return root;}if (tmp->data < data) {tmp = tmp->right;} else if (tmp->data > data) {tmp = tmp->left;}}TreeNode *Node = (TreeNode *)malloc(sizeof(TreeNode));Node->data = data;if (NULL == Node) {printf("申请新节点内存失败\n");return root;}// 链接节点if (data > top->data) {top->right = Node;} else if (data < top->data) {top->left = Node;}return root;
}// 删除二叉排序树节点
bool DeleteTreeNode(TreeNode **TreeRoot,int data) {if (NULL == (*TreeRoot)) return false;printf("删除节点: %d\n",data);TreeNode *tmp = (*TreeRoot);TreeNode *top = NULL;while (tmp != NULL) {if (tmp->data == data) {// 叶子节点if ((NULL == tmp->left) && (NULL == tmp->right)) {// 叶子节点if (NULL == top) {// 仅有根节点的叶子节点free(tmp);return true;} else {// 其他的叶子节点TreeNode *lastNode = top;if (tmp == lastNode->left) {lastNode->left = NULL;} else if (tmp == lastNode->right) {lastNode->right = NULL;}free(tmp);return true;}} else {// 非叶子节点// 算法为: // 默认算法为: 1.  当删除该节点时,获取该树右子树最左子节点//             2.  当右子树为空时,此时应该获取左子树最右端子节点if (NULL != tmp->right) {// 方案 1TreeNode *tmp2 = tmp->right;TreeNode *top2 = NULL;// 找到最后一个节点while (tmp2->left != NULL) {top2 = tmp2;tmp2 = tmp2->left;}// 删除老的节点tmp->data = tmp2->data;// 只有右子树节点 没有左子树节点if (NULL == top2) {tmp->right = NULL;} else {top2->left = NULL;}free(tmp2);} else {// 方案 2TreeNode *tmp2 = tmp->left;TreeNode *top2 = NULL;// 找到最后一个节点while (tmp2->right != NULL) {tmp2 = tmp2->right;}// 删除老的节点tmp->data = tmp2->data;if (NULL == top2) {tmp->left = NULL;} else {top2->right = NULL;}free(tmp2);}}} else {top = tmp;if (data > tmp->data) {tmp = tmp->right;} else {tmp = tmp->left;}}}return false;
}// 二叉树平衡调整
bool treeBalance(TreeNode **root) {checkTreeBalance((*root));while (BalanceTrue) {printf("二叉树不平衡,最小不平衡子树数据结点: %d\n",rjt->data);TreeNode *tmp;if (1 < treeHeight(rjt->left) - treeHeight(rjt->right)) {// 对于不平衡二叉树而言,左子树比右子树高////printf("左\n");if (rjt->left != NULL) {tmp = rjt->left;int ll = treeHeight(tmp->left);int rr = treeHeight(tmp->right);if (ll > rr) {// 对于不平衡子树 左子树 而言, 左子树比右子树高// 左左旋转turnLL(root,rjt);} else {// 对于不平衡子树 左子树 而言, 右子树比左子树高// 左右旋转//turnLR(root ,rjt);}} } else if (1 < treeHeight(rjt->right) - treeHeight(rjt->left)) {// 对于不平衡二叉树而言,右子树比左子树高////printf("右\n");if (rjt->right != NULL) {tmp = rjt->right;int ll = treeHeight(tmp->left);int rr = treeHeight(tmp->right);if (ll > rr) {//右左旋转turnRL(root,rjt);} else {//右右旋转turnRR(root,rjt);}}		}BalanceTrue = false;checkTreeBalance((*root));printf("二叉树调整平衡后数据结点:\n");printf("前序遍历:");Print1(*root);printf("\n");printf("中序遍历:");Print2(*root);printf("\n");printf("\n");}}int main() {TreeNode *root = NULL;printf("平衡二叉树插入测试\n");int nums[] = {65,60,70,55,40,63,69,66,68,77};int i;for (i=0;i<sizeof(nums)/sizeof(int);i++) {printf("插入数据: %d\n",nums[i]);root = addNode(root,nums[i]);if (NULL == root) {printf("首节点申请失败"); return -1;}treeBalance(&root);sleep(1);}printf("\n当前二叉树遍历\n");printf("前序遍历:");Print1(root);printf("\n");printf("中序遍历:");Print2(root);printf("\n");//return 0;printf("\n\n平衡二叉树删除测试\n");for (i=2;i<5;i++) {DeleteTreeNode(&root,nums[i]);treeBalance(&root);sleep(1);}printf("\n当前二叉树遍历\n");printf("前序遍历:");Print1(root);printf("\n");printf("中序遍历:");Print2(root);printf("\n");return 0;
}

程序执行结果

# gcc BalanceTree.c -w -g -std=c11
# 
# ./a.out 
平衡二叉树插入测试
插入数据: 65
插入数据: 60
插入数据: 70
插入数据: 55
插入数据: 40
二叉树不平衡,最小不平衡子树数据结点: 60
左左旋转,非根节点
二叉树调整平衡后数据结点:
前序遍历:65     55      40      60      70
中序遍历:40     55      60      65      70插入数据: 63
二叉树不平衡,最小不平衡子树数据结点: 65
左右旋转,是根节点
二叉树调整平衡后数据结点:
前序遍历:60     55      40      65      63      70
中序遍历:40     55      60      63      65      70插入数据: 69
插入数据: 66
二叉树不平衡,最小不平衡子树数据结点: 70
左左旋转,非根节点
二叉树调整平衡后数据结点:
前序遍历:60     55      40      65      63      69      66      70
中序遍历:40     55      60      63      65      66      69      70插入数据: 68
二叉树不平衡,最小不平衡子树数据结点: 65
右左旋转,非根节点
二叉树调整平衡后数据结点:
前序遍历:60     55      40      66      65      63      69      68      70
中序遍历:40     55      60      63      65      66      68      69      70插入数据: 77
二叉树不平衡,最小不平衡子树数据结点: 60
右右旋转,是根节点
二叉树调整平衡后数据结点:
前序遍历:66     60      55      40      65      63      69      68      70      77
中序遍历:40     55      60      63      65      66      68      69      70      77当前二叉树遍历
前序遍历:66     60      55      40      65      63      69      68      70      77
中序遍历:40     55      60      63      65      66      68      69      70      77平衡二叉树删除测试
删除节点: 70
删除节点: 55
删除节点: 40
二叉树不平衡,最小不平衡子树数据结点: 60
右左旋转,非根节点
二叉树调整平衡后数据结点:
前序遍历:66     63      60      65      69      68      77
中序遍历:60     63      65      66      68      69      77当前二叉树遍历
前序遍历:66     63      60      65      69      68      77
中序遍历:60     63      65      66      68      69      77
#

c9e5b65435ba13ebcd77ee64800d6889.gif

如果你年满18周岁以上,又觉得学【C语言】太难?想尝试其他编程语言,那么我推荐你学Python,现有价值499元Python零基础课程限时免费领取,限10个名额!
▲扫描二维码-免费领取

8faae0a32c1ffa2386b1cf187e2e4e70.gif

戳“阅读原文”我们一起进步

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

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

相关文章

cba比赛比分预测_【CBA直播】深圳vs广东前瞻:深圳战广东再掀反攻?

北京时间4月13日晚19点35分&#xff0c;CBA季后赛半决赛第三回合&#xff0c;深圳队主场迎战广东队。尽管目前双方总比分深圳以0-2落后对手&#xff0c;但他们在第二战的顽强表现给人留下了深刻印象。回归主场作战的他们&#xff0c;将在沈梓捷和贺希宁的带领下&#xff0c;力争…

C语言内存泄漏问题及其检视方法

点击蓝字关注我们来源于网络&#xff0c;侵删通过介绍内存泄漏问题原理及检视方法&#xff0c;希望后续能够从编码检视环节就杜绝内存泄漏导致的网上问题发生。本文通过介绍内存泄漏问题原理及检视方法&#xff0c;希望后续能够从编码检视环节就杜绝此类问题发生。预防内存泄漏…

未定义与 struct 类型的输入参数相对应的函数 fetch_引入鲁棒性作为连续参数,这种新损失函数实现了自适应、随时变换...

编辑&#xff1a;陈萍损失函数是机器学习里最基础也是最为关键的一个要素&#xff0c;其用来评价模型的预测值和真实值不一样的程度。最为常见的损失函数包括平方损失、指数损失、log 对数损失等损失函数。这里回顾了一种新的损失函数&#xff0c;通过引入鲁棒性作为连续参数&a…

清理jdk注册表_JDK 9早期版本安装后的Windows注册表清理

清理jdk注册表在我的上一篇博文中 &#xff0c;我演示了在安装早期版本的JDK 9&#xff08;内部版本68&#xff09;之后围绕Oracle Java符号链接 &#xff08;基于Windows的计算机上的C:\ProgramData\Oracle\Java\javapath\目录&#xff09;的问题的解决方案。这似乎阻止了早期…

汇编语言调用C语言/C++实例:乘法表

点击蓝字关注我们来源于网络&#xff0c;侵删现在编写一个简单的应用程序&#xff0c;提示用户输入整数&#xff0c;通过移位的方式将其与 2 的幕 (2〜2ⁿ) 相乘&#xff0c;并用填充前导空格的形式再次显示每个乘积。输入-输出使用 C。汇编模块将调用 3 个 C 编写的函数。程序…

rect函数_R函数不会写,quot;抄quot;总会吧!

前面我们简单的介绍了R函数。有些人可能会说&#xff0c;我现在的R水平有限&#xff0c;还不足以写出很高级的函数&#xff0c;该怎么办&#xff1f;俗话说前人栽树后人乘凉&#xff0c;他山之石可以攻玉&#xff0c;鲁迅同志也提出过“拿来”主义。已经有前人&#xff0c;高手…

10个超赞的C语言开源项目,强烈推荐!

点击蓝字关注我们来源于网络&#xff0c;侵删今天分享10个超赞的C语言开源项目&#xff0c;希望这些内容能对大家有所帮助&#xff01;目录&#xff1a;1. Webbench2. Tinyhttpd3. cJSON4. CMockery5. Libev6. Memcached7. Lua8. SQLite9. UNIX v610. NETBSD1. WebbenchWebbenc…

jboss性能指标_JBoss BRMS复杂事件处理(CEP)性能基准

jboss性能指标技术来了又去&#xff0c;但是一件事保持不变。 在设计企业解决方案时&#xff0c;我们喜欢使我们的生活更轻松的复杂组件&#xff0c;作为建筑师和开发人员&#xff0c;我们一直在寻找使我们的生活更轻松的方法。 一种方法是跟上与感兴趣的技术有关的流行新站点…

C语言经验分享:二维指针与二维数组的两种错误用法

点击蓝字关注我们来源于网络&#xff0c;侵删引子首先看一段代码:void test(int *p) {}int main() {int arr[] {30, 450,14,5};test(arr);return 0; }毫无疑问&#xff0c;上面这段代码是运行OK的。因为C语言标准中有以下规则:在函数参数的声明中&#xff0c;数组名被编译器当作…

camel 使用_使用Camel从WildFly 8向WebLogic 12发送JMS消息

camel 使用系统集成是一个很好的挑战。 特别是当您在寻找通信标准和可靠的解决方案时。 在当今的微服务世界中&#xff0c;每个人都在谈论REST服务和基于http的协议。 实际上&#xff0c;对于大多数通常具有更复杂的需求集的大多数企业项目来说&#xff0c;这是远远不够的。 合…

C++异常处理控制流下的OLLVM混淆

点击蓝字关注我们来源于网络&#xff0c;侵删Inflated!!!C异常化处理OLLVM-控制流平坦化Two PuzzlesException一般碰到C异常逆向&#xff0c;确定了异常分发、处理部分&#xff0c;直接把call throw改为jmp catch块&#xff0c;再F5即可。PS: 多个catch块根据rdx来当为异常处理…

【微服务】springboot整合kafka-stream使用详解

目录 一、前言 二、kafka stream概述 2.1 什么是kafka stream 2.2 为什么需要kafka stream 2.2.1 对接成本低 2.2.2 节省资源 2.2.3 使用简单 2.3 kafka stream特点 2.4 kafka stream中的一些概念 2.5 Kafka Stream应用场景 三、环境准备 3.1 搭建zk 3.1.1 自定义d…

C语言知识总结一:C语言的基本知识汇总

点击蓝字关注我们来源于网络&#xff0c;侵删C语言是一种计算机程序设计语言。它既有高级语言的特点&#xff0c;又具有汇编语言的特点。它可以作 为系统设计语言&#xff0c;编写工作系统应用程序&#xff0c;也可以作为应用程序设计语言&#xff0c;编写不依赖计算机 硬件的应…

jboss8日志级别设置_罐中研讨会:设置JBoss BPM Suite全日研讨会

jboss8日志级别设置是否在寻找一种简单的方法来宣传&#xff0c;展示或演示JBoss业务流程管理套件&#xff08;BPM Suite&#xff09;产品的入门难度&#xff1f; 别无所求&#xff0c;因为我们已经召集了这个研讨会&#xff0c;因此您可以围绕JBoss BPM Suite构建一个晚上&a…

yapi 接口文档_1分钟docker部署顶尖 API 文档管理系统

YApi 是高效、易用、功能强大的 api 管理平台&#xff0c;旨在为开发、产品、测试人员提供更优雅的接口管理服务。可以帮助开发者轻松创建、发布、维护 API&#xff0c;YApi 还为用户提供了优秀的交互体验&#xff0c;开发人员只需利用平台提供的接口数据写入工具以及简单的点击…

微软CTO建议业界弃用C/C++采用Rust,遭C++之父回怼

点击蓝字关注我们来源于网络&#xff0c;侵删近日&#xff0c;Microsoft Azure CTO、Sysinternals 的主要开发者 Mark Russinovich 在其社交账号上发布动态称&#xff0c;开发人员是时候停止使用 C/C 来启动新项目&#xff0c;并建议可在需要使用 non-GC 语言的场景中使用 Rust…

红帽 jboss_红帽峰会2015所需的JBoss BPM内容指南

红帽 jboss明年再见&#xff1f; 今年在Red Hat Summit上&#xff0c;我们在JBoss BRMS和JBoss BPM Suite演讲中获得了很多乐趣。 在DevNation周围也有一些社区会议&#xff0c;重点介绍了使我们的产品成为可能的项目。 您可以在他们的博客上找到此演讲的概述&#xff0c;并…

Python、C、Java 和 C++ 四足鼎立,其他已无胜算? | TIOBE 10 月编程语言排行榜

点击蓝字关注我们来源于网络&#xff0c;侵删技术的千变万化&#xff0c;都是有迹可循的&#xff0c;最新的 TIOBE 十月编程语言榜单重磅发布&#xff0c;快来看看有哪些值得关注的变化吧&#xff01;四大编程语言不断增强其主导地位曾几何时&#xff0c;编程语言界中 Java、C、…

C语言 #define 和 typedef 区别

点击蓝字关注我们来源于网络&#xff0c;侵删在C语言编程中&#xff0c;typedef 和 #define是最常用语句&#xff0c;可能很多工作过几年的工程师都没有去深究过它们的一些用法和区别。typedef的用法在C/C语言中&#xff0c;typedef常用来定义一个标识符及关键字的别名&#xf…

Spring Batch –用JavaConfig替换XML作业配置

最近&#xff0c;我协助一个客户启动并运行了Spring Batch实现。 该团队决定继续使用针对批处理作业的基于JavaConfig的配置&#xff0c;而不是传统的基于XML的配置。 随着这越来越成为配置Java应用程序的一种常用方法&#xff0c;我觉得是时候更新Keyhole的Spring Batch系列了…