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

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

http://download.youkuaiyun.com/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版代码实现的朋友,可以看:

http://download.youkuaiyun.com/detail/stevemarbo/4097865

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值