二叉树算法算法【二叉树的创建、插入、删除、查找】 ...

万有斥力  金牌会员 | 2024-8-28 18:35:25 | 来自手机 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 546|帖子 546|积分 1638

一、原理



1.1、二叉排序树的插入





1.2、二叉树的删除


(1)删除度为0的节点,就是末了的叶子节点,直接删除就可以了.
(2)删除度为1的节点,就是爷爷节点接收孙子节点。

(3)删除度为2的节点就是找到该节点的前驱和后继,然后降当前节点与前驱节点的值交换,就酿成了前面两度为0或者1的节点删除的情况,然后在进行删除就可以了。


二、代码

  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4. using namespace std;
  5. /* 对二叉树的的操作 */
  6. /* 二叉树的节点 */
  7. typedef struct Node
  8. {
  9.         int key;
  10.         struct Node* Lchild, * Rchild;
  11. }g_Node;
  12. /* 创建一个节点 */
  13. g_Node* getNewNode(int key)
  14. {
  15.         g_Node* node = (g_Node*)malloc(sizeof(g_Node));
  16.         node->key = key;
  17.         node->Lchild = NULL;
  18.         node->Rchild = NULL;
  19.         return node;
  20. }
  21. /* 向树中某个节点后插入如一个随机数节点:采用递归的方式插入树中元素 */
  22. //g_Node* insert(g_Node* root, int key)
  23. //{
  24. //        if (NULL == root)  return getNewNode(key);
  25. //        //随机插入树的左边或者右边
  26. //        if (rand() % 2)  root->Lchild = insert(root->Lchild, key);
  27. //        else root->Rchild = insert(root->Rchild, key);
  28. //        return root;
  29. //}
  30. /* 向树中插入顺序树:创建二叉树 */
  31. g_Node* insert(g_Node* root, int key)
  32. {
  33.         if (NULL == root)  return getNewNode(key);
  34.         //随机插入树的左边或者右边
  35.         if (key < root->key)  root->Lchild = insert(root->Lchild, key);
  36.         else root->Rchild = insert(root->Rchild, key);
  37.         return root;
  38. }
  39. /* 从根节点清理掉一个树:采用递归深入清理的方式 */
  40. void clear(g_Node* root)
  41. {
  42.         if (NULL == root) return;
  43.         clear(root->Lchild);
  44.         clear(root->Rchild);
  45.         free(root);
  46.         return;
  47. }
  48. /* 二叉树打印函数:采用递归的方式,向内打印 */
  49. int tot = 0;
  50. void displayTree_V2(g_Node* root) {
  51.         if (root == NULL) return;
  52.         int start, end;
  53.         tot += 1;
  54.         start = tot;
  55.         if (root->Lchild) displayTree_V2(root->Lchild);
  56.         if (root->Rchild) displayTree_V2(root->Rchild);
  57.         tot += 1;
  58.         end = tot;
  59.         printf("%d : [%d, %d]\n", root->key, start, end);
  60.         return;
  61. }
  62. #define MAX_NODE 20
  63. void displayTree_V1(g_Node* root) {
  64.         g_Node* queue[MAX_NODE + 5];
  65.         int head, tail;
  66.         head = tail = 0;
  67.         queue[tail++] = root;
  68.         while (head < tail) {
  69.                 g_Node* node = queue[head];
  70.                 printf("\nnode : %d\n", node->key);
  71.                 if (node->Lchild) {
  72.                         queue[tail++] = node->Lchild;
  73.                         printf("\t%d->%d (left)\n", node->key, node->Lchild->key);
  74.                 }
  75.                 if (node->Rchild) {
  76.                         queue[tail++] = node->Rchild;
  77.                         printf("\t%d->%d (right)\n", node->key, node->Rchild->key);
  78.                 }
  79.                 head++;    //如果打印到了结尾了,tail索引就不会在增加,但是head还是增加的,最终就会跳出循环
  80.         }
  81.         return;
  82. }
  83. /* 二叉树的查找:递归的方式向下查找 */
  84. bool findBinaryTree(g_Node* root, int key)
  85. {
  86.         bool ret;
  87.         if (NULL == root) return false;
  88.         if (key == root->key) return true;
  89.         if (key < root->key) ret = findBinaryTree(root->Lchild, key);
  90.         else ret = findBinaryTree(root->Rchild, key);
  91.         return ret;
  92. }
  93. /* 找到节点的前驱节点 */
  94. g_Node* getProNode(g_Node* root)
  95. {
  96.         if (NULL == root) return root;
  97.         root = root->Lchild;
  98.         while (root) root = root->Rchild;
  99.         return root;
  100. }
  101. /*
  102. * 二叉树删除节点:
  103. * (1)删除度为0的节点
  104. * (2)删除度为1的节点
  105. * (3)删除度为2的节点:找到节点的前驱,之后与前驱节点交换,
  106. *                                             降为删除度为0和度为1的节点。
  107. */
  108. g_Node* deleteNodeTree(g_Node* root, int key)
  109. {
  110.         if (NULL == root) return root;
  111.         if (key < root->key) root->Lchild = deleteNodeTree(root->Lchild, key);
  112.         else if(key>root->key) root->Rchild = deleteNodeTree(root->Rchild, key);
  113.         else {
  114.                 //删除度为0的节点
  115.                 if (root->Lchild == NULL && root->Rchild == NULL)   
  116.                 {
  117.                         free(root);   //直接删除
  118.                         return NULL;
  119.                 }    //删除度为1的节点
  120.                 else if (root->Lchild == NULL || root->Rchild == NULL)
  121.                 {   //root的子节点由root的父节点承接
  122.                         g_Node* temp = root->Lchild ? root->Lchild : root->Rchild;
  123.                         free(root);
  124.                         return temp;
  125.                 }
  126.                 else  //删除度为2的节点
  127.                 {
  128.                         g_Node* temp = getProNode(root);   //找到节点的前驱
  129.                         root->key = temp->key;   //与前驱交换key数值
  130.                         //继续递归调用,删除掉交换值后的节点,变成度为0、1的节点删除问题。
  131.                         root->Lchild = deleteNodeTree(root->Lchild, temp->key);
  132.                 }
  133.         }
  134.         return root;
  135. }
  136. int main()
  137. {
  138.         g_Node* root = NULL;
  139.         for (int i = 0; i < MAX_NODE; i++)      //创建二叉树
  140.         {
  141.                 root = insert(root, rand() % 100);
  142.         }
  143.         displayTree_V1(root);
  144.         displayTree_V2(root);
  145.         int data = rand() % 100;
  146.         bool ret = findBinaryTree(root, data);
  147.         printf("find:%d, %d\r\n", ret, data);
  148.         deleteNodeTree(root, data);
  149.         displayTree_V2(root);
  150.         clear(root);
  151.         return 0;
  152. }
复制代码
终极的运行效果如下所示:




免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

万有斥力

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表