二叉树详解 binary tree && binary search tree


本文参考stanford大学一位计算机教授所写的关于二叉树的文章:

http://download.csdn.net/detail/stevemarbo/4097865


二叉树,一个经典的数据结构,它包含一个指向左子树的指针,一个指向右指数的指针,和一个数据元素

二叉搜索树,在二叉树的基础上,它的左子树的值都小于它,它的右子树的值都大于它



树本身就是一个递归定义的数据结构,所以,只要是有关树的问题,都要考虑递归


结构定义:

[cpp]  view plain copy
  1. struct node {  
  2.     int data;  
  3.     struct node* left;  
  4.     struct node* right;  
  5. };  



给定一棵二叉树,查找这棵树中是否包含有值为target的节点

[cpp]  view plain copy
  1. int lookup(struct node* root, int target) {  
  2.     // base case == empty tree  
  3.     // in this case, the target is not found so return false  
  4.       
  5.     if(root == NULL)  
  6.         return 0;  
  7.     else {  
  8.         if(target == root->data) return 1;  
  9.         else {  
  10.             if(target < root->data) return (lookup(root->left, target));  
  11.             else return(lookup(root->right, target));  
  12.         }  
  13.     }  
  14. }  



生成一个新节点
[cpp]  view plain copy
  1. struct node* newNode(int data) {  
  2.     struct node* node = malloc(sizeof(struct node));  
  3.     node->data = data;  
  4.     node->left = NULL;  
  5.     node->right = NULL;  
  6.   
  7.     return node;  
  8. }  



向二叉搜索树中插入一个新节点

[cpp]  view plain copy
  1. struct node* insert(struct node* node, int data) {  
  2.     if(node == NULL)  
  3.         return newNode(data);  
  4.     else {  
  5.         if(data <= node->data) node->left = insert(node->left, data);  
  6.         else node->right = insert(node->right, data);  
  7.   
  8.         return node;  
  9.     }  
  10. }  


返回二叉树中的节点个数

[cpp]  view plain copy
  1. // compute the number of nodes in a tree  
  2. int size(struct node* node) {  
  3.     if(node == NULL)  
  4.         return 0;  
  5.     else  
  6.         return size(node->left)+1+size(node->right);  
  7. }  



返回二叉树的最大深度

比如

                         4

                      /       \

                    3         5

                  /   \

                 1     2

这棵树的最大深度就是3

[cpp]  view plain copy
  1. // compute the maxDepth of a tree  
  2. // the longest path from the root node down to the farthest leaf node  
  3. int maxDepth(struct node* node) {  
  4.     if(node == NULL)  
  5.         return 0;  
  6.     else {  
  7.         int lDepth = maxDepth(node->left);  
  8.         int rDepth = maxDepth(node->right);  
  9.   
  10.         // use the larger one  
  11.         if(lDepth > rDepth) return lDepth+1;  
  12.         else return rDepth+1;  
  13.     }  
  14. }  



求二叉搜索树的最小值节点和最大值节点

比如

                          4

                      /       \

                    3         5

                  /   \

                 1     2

上面这棵二叉搜索树的最小值节点是1,最大值节点是5

根据二叉搜索树性质,最小值节点一定是左子树的尽头,最大值节点一定是右子树的尽头

[cpp]  view plain copy
  1. // given a non-empty binary search tree  
  2. // return the minimum data value found in that tree  
  3. // note that the entire tree does not need to be searched  
  4.   
  5. int minValue(struct node* node) {  
  6.     struct node* current = node;  
  7.   
  8.     while(current->left != NULL)  
  9.         current = current->left;  
  10.   
  11.     return current->data;  
  12. }  
  13.   
  14. int maxValue(struct node* node) {  
  15.     struct node* current = node;  
  16.   
  17.     while(current->right != NULL)  
  18.         current = current->right;  
  19.   
  20.     return current->data;  
  21. }  


中序遍历,按照升序打印二叉搜索树

[cpp]  view plain copy
  1. // given a binary search tree, print out its data elements in   
  2. // increasing order  
  3. void printTree(struct node* node) {  
  4.     if(node == NULL) return;  
  5.   
  6.     printTree(node->left);  
  7.     printf("%d ",node->data);  
  8.     printTree(node->right);  
  9. }  



给定一个整数,如果有某条二叉树的路径之和等于这个数,返回1,否则返回0

比如,给定整数为9

                          4

                      /       \

                    3         5

                  /   \

                 1     2

路径 1: 4 3 1

路径 2: 4 3 2

路径 3: 4 5

因为 4+3+2 = 9

所以返回1

[cpp]  view plain copy
  1. // given a tree and a sum, return true if there is a path from the  
  2. // root down to a leaf, such that adding up all the values along the path  
  3. // equals the given sum.  
  4. // strategy: subtract the node value from the sum when recurring down  
  5. // and check to see if the sum is 0 when you run out of tree.  
  6. int hasPathSum(struct node* node, int sum) {  
  7.     if(node == NULL)  
  8.         return (sum==0)?1:0;  
  9.   
  10.     else {  
  11.         int subSum = sum - node->data;  
  12.         return (hasPathSum(node->left, subSum) || hasPathSum(node->right, subSum));  
  13.     }  
  14. }  



打印二叉树的路径

[cpp]  view plain copy
  1. void printPaths(struct node* node) {  
  2.     int path[1000];  
  3.   
  4.     printPathsRecur(node, path, 0);  
  5. }  
  6.   
  7. // recursive helper funciton -- given a node, and an array containing the  
  8. // path from the root node up but not including this node, print out  
  9. // all the root-leaf paths  
  10. //  
  11.   
  12. void printPathsRecur(struct node* node, int path[], int pathLen) {  
  13.     if(node == NULL) return;  
  14.   
  15.   
  16.     path[pathLen] = node->data;  
  17.     pathLen++;  
  18.     if(node->left==NULL && node->right==NULL)  
  19.         printArray(path, pathLen);  
  20.     else {  
  21.         printPathsRecur(node->left, path, pathLen);  
  22.         printPathsRecur(node->right, path, pathLen);  
  23.     }  
  24. }  
  25.   
  26.   
  27. void printArray(int ints[], int len) {  
  28.     int i;  
  29.     for(i=0; i<len; i++)  
  30.         printf("%d ", ints[i]);  
  31.     printf("\n");  
  32. }  


镜像操作,把每一个节点上的左子树和右子树交换位置

比如

                         4

                      /       \

                    3         5

                  /   \

                 1     2

镜像操作之后:

                       

                          4

                      /       \

                    5         3

                  /   \

                 2     1

      


                         

[cpp]  view plain copy
  1. // change a tree so that the roles of the left and right pointers  
  2. // are swapped at every node  
  3. void mirror(struct node* node) {  
  4.     if(node==NULL)  
  5.         return;  
  6.     else {  
  7.         struct node* temp;  
  8.         mirror(node->left);  
  9.         mirror(node->right);  
  10.   
  11.         // swap the pointers in this node  
  12.         temp = node->left;  
  13.         node->left = node->right;  
  14.         node->right = temp;  
  15.     }  
  16.   
  17. }  


复制二叉搜索树中的每一个节点,并把新节点插入到左子树中

比如

                 2

               /     \

              1       3

变为:

                  2

                /     \

              2        3

            /           /

          1           3

          /

         1

[cpp]  view plain copy
  1. void doubleTree(struct node* node) {  
  2.     struct node* oldLeft;  
  3.     if(node == NULL) return;  
  4.     doubleTree(node->left);  
  5.     doubleTree(node->right);  
  6.   
  7.     oldLeft = node->left;  
  8.     node->left = newNode(node->data);  
  9.     node->left->left = oldLeft;  
  10. }  



判断两棵二叉树是否相等

[cpp]  view plain copy
  1. // given two trees, return true if they are structurelly identical  
  2. //  
  3.   
  4. int sameTree(struct node* a, struct node* b) {  
  5.     if(a==NULL && b==NULL) return 1;  
  6.   
  7.     else if (a!=NULL && b!=NULL) {  
  8.         return(a->data == b->data && sameTree(a->left,b->left) && sameTree(a->right,b->right));  
  9.       
  10.     }  
  11.     else  
  12.         return 0;  
  13. }  



判断一棵二叉树是否为二叉搜索树

[cpp]  view plain copy
  1. // return true if a binary tree is a binary search tree  
  2. //  
  3. int isBST(struct node* node) {  
  4.     if(node == NULL) return 1;  
  5.     if(node->left!=NULL && minValue(node->left) > node->data)  
  6.         return 0;  
  7.   
  8.     if(node->right!=NULL && maxValue(node->right) <= node->data)  
  9.         return 0;  
  10.   
  11.     if(!isBST(node->left) || !isBST(node->right))  
  12.         return 0;  
  13.   
  14.     return 1;  
  15. }  



很多经典的递归啊!


想要看java版代码实现的朋友,可以看:

http://download.csdn.net/detail/stevemarbo/4097865

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值