基础闯关记-二叉搜索树

基础闯关记-二叉搜索树

树的定义

树:n(n>=0)个节点构成的有限集合。
当n=0是称为空树

对于任何一棵非空树(n>0),它具备以下性质:

  1. 树种有一个称为的特殊节点
  2. 其余节点又可分为m个互不相交的有限集合,其中每个集合本身又是一棵树,称为原来树的子树

比如下面就是一棵典型的树

image

注意,上面这幅图可以看出,树可以是多叉的,也可是有时二叉的,而二叉树因为独特的性质而被单独拿出来研究。

二叉树的定义

二叉树:一个有穷的节点的集合。

这个集合可以为空。

若不为空,则它由根节点和称其为左子树右子树两个互不相交的二叉树构成,相当于一个递归的定义。

一个非空二叉树可以有下面4中形态

image

值得一提的是,如果一个二叉树只有左子树或者只有右子树,那么这个二叉树将退化成链表。

树的主要应用场景

树可以分为二叉树和多叉树,它们的主要应用场景和对应的树的名称可以用下图表示

image

可以看出,树有非常多的应用场景,每个应用场景下树都有特定的名字。如果对数据库感兴趣的话,那么研究B+树将变得很有必要。但是这里,我们只研究二叉树。

二叉搜索树

我们解决一个实际问题:查找。试想一下,如果我们使用在链表里寻找一个元素,那么寻找时间将随着链表的长度线性增长。而二叉搜索树就可以解决这个问题

二叉搜索树的定义

二叉搜索树:首先,它必须是一棵二叉树,在二叉树的基础上满足以下性质

  1. 非空左子树所有键值小于其根节点键值
  2. 非空右子树所有键值大于其根节点键值
  3. 左右子树都是二叉搜索树(递归)

比如下面就是一棵二叉搜索树

image

从二叉搜索树的结构上来看,我们很容易完成以下操作

  1. 找出最大值和最小值
  2. 查找某一个元素是否存在

二叉搜索树存储结构定义

二叉搜索树存储和二叉树的存储没有区别,虽然二叉树可以用连续的空间存储(二叉堆可以用数组存储)。但是大多数情况下,为了空间的充分利用,我们使用链式存储。二叉树的存储结构体

struct Node{
        int Data;//键值
        struct Node *Left;//指向左子树
        struct Node *Right;//指向右子树
};

我们再定义二叉搜索树的需要支持的操作

#include <stdio.h>
#include <stdlib.h>

struct Node{
        int Data;//键值
        struct Node *Left;//指向左子树
        struct Node *Right;//指向右子树
};

typedef struct Node *BinTree;

BinTree InitBinTree(int a[], int len);//将数组初始化成二叉搜索树
BinTree Insert(BinTree Root, int Data);//二叉搜索树的插入单个节点
int Find(BinTree, int X);//查找一个元素是否存在
int FindMax(BinTree);//找出最大值

二叉搜索树的实现

#include "binTree.h"
BinTree InitBinTree(int a[], int len){

	//首先创建根节点并存放第一个元素
	BinTree Root = malloc(sizeof(struct Node));
	Root->Data = a[0];

	//其他元素依次插入
	int i;
	for(i=1; i<len; i++){
		Insert(Root, a[i]);
	}

	return Root;
}

BinTree Insert(BinTree Root, int Data){

	//生成换一个二叉树节点
	BinTree BinNode = malloc(sizeof(struct Node));
        BinNode->Data = Data;

	//如果当前元素小于根节点元素,则节点需要放在左边,注意这里需要考虑递归的往左边移动
	if(Data < Root->Data){
		if(Root->Left == NULL){
			Root->Left = BinNode;
		}else{
			//没有插入位置的情况下递归插入
			Insert(Root->Left, Data);
		}
	}else{
		if(Root->Right == NULL){
			Root->Right = BinNode;
		}else{
			Insert(Root->Right, Data);
		}
	}
	
	return Root;
	
}

int Find(BinTree BT, int X){
	if(BT == NULL){
		return -1;	
	}
	
	if(X > BT->Data){
		printf("%d > %d \n", X, BT->Data);
		Find(BT->Right, X);
	}else if(X < BT->Data){
		printf("%d < %d \n", X, BT->Data);
		Find(BT->Left, X);
	}else{
		printf("%d == %d", X, BT->Data);
		return BT->Data;
	}
}

int FindMax(BinTree BT){
	if(BT->Right == NULL){
		return BT->Data;
	}

	return FindMax(BT->Right);
}

测试二叉搜索树

#include "binTree.h"
void main(){
	int a[] = {5, 3, 7, 1, 4, 6, 8};
	BinTree BT = InitBinTree(a, 7);
	int val = Find(BT, 1);
	printf("\nfind result is :%d", val);
	int max = FindMax(BT);
	printf("\nmax is :%d", max);
}
posted @ 2017-08-07 01:32  一路既往  阅读(233)  评论(0)    收藏  举报