二叉樹詳解 binary tree && binary search tree

本文參考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版代碼實現的朋友,可以看:

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

發佈了36 篇原創文章 · 獲贊 17 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章