本文参考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 false
- if(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 tree
- int size(struct node* node) {
- if(node == NULL)
- return 0;
- else
- return 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 node
- int maxDepth(struct node* node) {
- if(node == NULL)
- return 0;
- else {
- int lDepth = maxDepth(node->left);
- int rDepth = maxDepth(node->right);
- // use the larger one
- if(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 searched
- int 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 order
- void 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 node
- void mirror(struct node* node) {
- if(node==NULL)
- return;
- else {
- struct node* temp;
- mirror(node->left);
- mirror(node->right);
- // swap the pointers in this node
- temp = 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));
- }
- else
- return 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版代码实现的朋友,可以看: