数据结构与算法分析 四、树

4.1 基本知识

树叶、深度、高度

树叶:没有儿子的节点
深度:从根到该节点的长度
高度:从该节点到一片树叶的最长路径的长

树的实现

兄弟法

struct TreeNode{
datatype data;
TreeNode *FirstChild;	//第一个孩子
TreeNode *NextSibling;	//下一兄弟
}

数组法

class Node {
public:
    int val;
    vector<Node*> children;
    Node() {}
    Node(int _val) {
        val = _val;
    }
    Node(int _val, vector<Node*> _children) {
        val = _val;
        children = _children;
    }
};

树的遍历及应用

目录
 UNIX,VAX/VMX和DOS内的许多常用操作系统中的目录结构。
在这里插入图片描述
遍历目录(先序遍历)
在这里插入图片描述

4.2 二叉树

定义

二叉树是一棵树,每个节点都不能有多于两个的儿子。

实现

struct TreeNode {
      int val;
      TreeNode *left;
      TreeNode *right;
      TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

表达式数

 因为很多操作都是二元的。所以刚好用二叉树来表示。
在这里插入图片描述

4.3 二叉查找树

定义

 每个节点的左子树中所有值小于该节点的值,右子树所有关键字值大于该节点的值。

实现

 重点关注insert和delete的实现

#include<iostream>
using namespace std;

class TreeNode {
public:
	int val;
	TreeNode *left;
	TreeNode *right;
	TreeNode(int num):val(num), left(NULL), right(NULL){}
};

class BST {
public:
	BST():m_root(NULL){}
	void insert(int val);	
	void remove(int val);	
	TreeNode* findMin();
	TreeNode* findMax();
	
	void _insert(TreeNode *&root, int val);
	void _remove(TreeNode *&root, int val);	
	TreeNode* _findMin(TreeNode *root);
	TreeNode* _findMax(TreeNode *root);
private:
	TreeNode* m_root;
};

void BST::insert(int val) {
	_insert(m_root, val);
}

//这里需要传入指针的引用,当我们把一个指针做为参数传一个函数时,其实是把指针的副本传递给了函数,
//需要改变传入的指针指向的地址,所以需要引用
void BST::_insert(TreeNode *&root, int val) {
	if (root == NULL) {
		root = new TreeNode(val);
		return;
	}
	if (val > root->val) 
		_insert(root->right, val);
	else if (val < root->val) 
		_insert(root->left, val);
	//相等则不变
}
void BST::remove(int val) {
	_remove(m_root, val);
}

void BST::_remove(TreeNode *&root, int val) {
	if (root == NULL) {
		cerr << "二叉搜索树为空" << endl;
		exit(1);
	}
	if (val < root->val) 
		_remove(root->left, val);
	else if(val > root->val)
		_remove(root->right, val);
	//等于根节点时
	else {
		//如果左右节点都在,用右节点的最小值代替
		if (root->left && root->right) {
			TreeNode *tmp = _findMin(root->right);
			root->val = tmp->val;
			_remove(root->right, root->val);
		}
		//1/0个孩子
		else {
			//要保存
			TreeNode* tmp = root;
			if (root->left == NULL)
				root = root->right;
			if (root->right == NULL)
				root = root->left;
			delete(tmp);
		}
	}
}

TreeNode* BST::findMax() {
	return _findMax(m_root);
}

TreeNode* BST::_findMax(TreeNode *root) {
	if (root == NULL) {
		cerr << "二叉搜索树为空" << endl;
		exit(1);
	}
	//要保证root->right存在,如果while(root)会返回空
	while (root->right) {
		root = root->right;
	}
	return root;
}

TreeNode* BST::findMin() {
	return _findMin(m_root);
}

TreeNode* BST::_findMin(TreeNode *root) {
	if (root == NULL) {
		cerr << "二叉搜索树为空" << endl;
		exit(1);
	}
	//要保证root->left存在,如果while(root)会返回空
	while (root->left) {
		root = root->left;
	}
	return root;
}
int main() {
	BST my_bst;
	int i = 10;
	while (i--) {
		my_bst.insert(i);
	}
	my_bst.remove(9);
	cout << my_bst.findMax()->val << endl;
}

缺点

 容易失去平衡,操作耗时增加。可以添加“平衡”作为附加条件来解决这个问题,即任何节点的深度均不得过深。

4.4 AVL树

定义

左右子树高度最多差1的二叉搜索树。

单旋转双旋转

见书

4.6 树的遍历

见整理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值