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

来源:互联网 发布:淘宝拔草少年真货假货 编辑:程序博客网 时间:2024/06/05 21:07

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

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


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

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



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


结构定义:

struct node {int data;struct node* left;struct node* right;};



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

int lookup(struct node* root, int target) {// base case == empty tree// in this case, the target is not found so return falseif(root == NULL)return 0;else {if(target == root->data) return 1;else {if(target < root->data) return (lookup(root->left, target));else return(lookup(root->right, target));}}}



生成一个新节点
struct node* newNode(int data) {struct node* node = malloc(sizeof(struct node));node->data = data;node->left = NULL;node->right = NULL;return node;}



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

struct node* insert(struct node* node, int data) {if(node == NULL)return newNode(data);else {if(data <= node->data) node->left = insert(node->left, data);else node->right = insert(node->right, data);return node;}}


返回二叉树中的节点个数

// compute the number of nodes in a treeint size(struct node* node) {if(node == NULL)return 0;elsereturn size(node->left)+1+size(node->right);}



返回二叉树的最大深度

比如

                         4

                      /       \

                    3         5

                  /   \

                 1     2

这棵树的最大深度就是3

// compute the maxDepth of a tree// the longest path from the root node down to the farthest leaf nodeint maxDepth(struct node* node) {if(node == NULL)return 0;else {int lDepth = maxDepth(node->left);int rDepth = maxDepth(node->right);// use the larger oneif(lDepth > rDepth) return lDepth+1;else return rDepth+1;}}



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

比如

                          4

                      /       \

                    3         5

                  /   \

                 1     2

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

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

// given a non-empty binary search tree// return the minimum data value found in that tree// note that the entire tree does not need to be searchedint minValue(struct node* node) {struct node* current = node;while(current->left != NULL)current = current->left;return current->data;}int maxValue(struct node* node) {struct node* current = node;while(current->right != NULL)current = current->right;return current->data;}


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

// given a binary search tree, print out its data elements in // increasing ordervoid printTree(struct node* node) {if(node == NULL) return;printTree(node->left);printf("%d ",node->data);printTree(node->right);}



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

比如,给定整数为9

                          4

                      /       \

                    3         5

                  /   \

                 1     2

路径 1: 4 3 1

路径 2: 4 3 2

路径 3: 4 5

因为 4+3+2 = 9

所以返回1

// given a tree and a sum, return true if there is a path from the// root down to a leaf, such that adding up all the values along the path// equals the given sum.// strategy: subtract the node value from the sum when recurring down// and check to see if the sum is 0 when you run out of tree.int hasPathSum(struct node* node, int sum) {if(node == NULL)return (sum==0)?1:0;else {int subSum = sum - node->data;return (hasPathSum(node->left, subSum) || hasPathSum(node->right, subSum));}}



打印二叉树的路径

void printPaths(struct node* node) {int path[1000];printPathsRecur(node, path, 0);}// recursive helper funciton -- given a node, and an array containing the// path from the root node up but not including this node, print out// all the root-leaf paths//void printPathsRecur(struct node* node, int path[], int pathLen) {if(node == NULL) return;path[pathLen] = node->data;pathLen++;if(node->left==NULL && node->right==NULL)printArray(path, pathLen);else {printPathsRecur(node->left, path, pathLen);printPathsRecur(node->right, path, pathLen);}}void printArray(int ints[], int len) {int i;for(i=0; i<len; i++)printf("%d ", ints[i]);printf("\n");}


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

比如

                         4

                      /       \

                    3         5

                  /   \

                 1     2

镜像操作之后:

                       

                          4

                      /       \

                    5         3

                  /   \

                 2     1

      


                         

// change a tree so that the roles of the left and right pointers// are swapped at every nodevoid mirror(struct node* node) {if(node==NULL)return;else {struct node* temp;mirror(node->left);mirror(node->right);// swap the pointers in this nodetemp = node->left;node->left = node->right;node->right = temp;}}


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

比如

                 2

               /     \

              1       3

变为:

                  2

                /     \

              2        3

            /           /

          1           3

          /

         1

void doubleTree(struct node* node) {struct node* oldLeft;if(node == NULL) return;doubleTree(node->left);doubleTree(node->right);oldLeft = node->left;node->left = newNode(node->data);node->left->left = oldLeft;}



判断两棵二叉树是否相等

// given two trees, return true if they are structurelly identical//int sameTree(struct node* a, struct node* b) {if(a==NULL && b==NULL) return 1;else if (a!=NULL && b!=NULL) {return(a->data == b->data && sameTree(a->left,b->left) && sameTree(a->right,b->right));}elsereturn 0;}



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

// return true if a binary tree is a binary search tree//int isBST(struct node* node) {if(node == NULL) return 1;if(node->left!=NULL && minValue(node->left) > node->data)return 0;if(node->right!=NULL && maxValue(node->right) <= node->data)return 0;if(!isBST(node->left) || !isBST(node->right))return 0;return 1;}



很多经典的递归啊!


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

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

原创粉丝点击