`
jaesonchen
  • 浏览: 309892 次
  • 来自: ...
社区版块
存档分类
最新评论

数据结构之二叉树

 
阅读更多

 



 

    二叉树存储结构结点定义:

public class BinaryTreeNode implements Node {
	private Object data; //数据域
	private BinaryTreeNode parent; //父结点
	private BinaryTreeNode lChild; //左孩子
	private BinaryTreeNode rChild; //右孩子
	private int height; //以该结点为根的子树的高度
	private int size; //该结点子孙数(包括结点本身)

	public BinaryTreeNode() { this(null); }
	public BinaryTreeNode(Object e) {
		data = e; height = 0; size = 1;
		parent = lChild = rChild = null;
	}
	
	/******Node 接口方法******/
	public Object getData() { return data; }
	public void setData(Object obj) { data = obj;}
	/******辅助方法,判断当前结点位置情况******/
	//判断是否有父亲
	public boolean hasParent() { return parent != null;}
	//判断是否有左孩子
	public boolean hasLChild() { return lChild ! =null;}
	//判断是否有右孩子
	public boolean hasRChild() { return rChild != null;}
	//判断是否为叶子结点
	public boolean isLeaf() { return !hasLChild() && !hasRChild();}
	//判断是否为某结点的左孩子
	public boolean isLChild() { return (hasParent() && this == parent.lChild);}
	//判断是否为某结点的右孩子
	public boolean isRChild() { return (hasParent() && this == parent.rChild);}
	/******与height 相关的方法******/
	//取结点的高度,即以该结点为根的树的高度
	public int getHeight() { return height; }
	//更新当前结点及其祖先的高度
	public void updateHeight() {
		int newH = 0;//新高度初始化为0,高度等于左右子树高度加1 中的大者
		if (hasLChild()) newH = Math.max(newH, 1 + getLChild().getHeight());
		if (hasRChild()) newH = Math.max(newH, 1 + getRChild().getHeight());
		if (newH == height) return; //高度没有发生变化则直接返回
		height = newH; //否则更新高度
		if (hasParent()) getParent().updateHeight(); //递归更新祖先的高度
	}
	/******与size 相关的方法******/
	//取以该结点为根的树的结点数
	public int getSize() { return size; }
	//更新当前结点及其祖先的子孙数
	public void updateSize() {
		size = 1; //初始化为1,结点本身
		if (hasLChild()) size += getLChild().getSize(); //加上左子树规模
		if (hasRChild()) size += getRChild().getSize(); //加上右子树规模
		if (hasParent()) getParent().updateSize(); //递归更新祖先的规模
	}
	/******与parent 相关的方法******/
	//取父结点
	public BinaryTreeNode getParent() { return parent; }
	//断开与父亲的关系
	public void sever() {
		if (!hasParent()) return;
		if (isLChild()) parent.lChild = null;
		else parent.rChild = null;
		parent.updateHeight(); //更新父结点及其祖先高度
		parent.updateSize(); //更新父结点及其祖先规模
		parent = null;
	}
	/******与lChild 相关的方法******/
	//取左孩子
	public BinaryTreeNode getLChild() { return lChild; }
	//设置当前结点的左孩子,返回原左孩子
	public BinaryTreeNode setLChild(BinaryTreeNode lc) {
		BinaryTreeNode oldLC = this.lChild;
		if (hasLChild()) { lChild.sever();} //断开当前左孩子与结点的关系
		if (lc != null){
			lc.sever(); //断开lc 与其父结点的关系
			this.lChild = lc; //确定父子关系
			lc.parent = this;
			this.updateHeight(); //更新当前结点及其祖先高度
			this.updateSize(); //更新当前结点及其祖先规模
		}
		return oldLC; //返回原左孩子
	}
	/******与rChild 相关的方法******/
	//取右孩子
	public BinaryTreeNode getRChild() { return rChild; }
	//设置当前结点的右孩子,返回原右孩子
	public BinaryTreeNode setRChild(BinaryTreeNode rc) {
		BinaryTreeNode oldRC = this.rChild;
		if (hasRChild()) { rChild.sever();} //断开当前右孩子与结点的关系
		if (rc != null){
			rc.sever(); //断开lc 与其父结点的关系
			this.rChild = rc; //确定父子关系
			rc.parent = this;
			this.updateHeight(); //更新当前结点及其祖先高度
			this.updateSize(); //更新当前结点及其祖先规模
		}
		return oldRC; //返回原右孩子
	}
}

 


 

    二叉树遍历:

public class BinaryTree { 
	private BinaryTreeNode root;
	private Strategy strategy;
	
	public BinaryTree() { this(null, null); }
	public BinaryTree(BinaryTreeNode root, Strategy strategy) {
		this.root = root;
		this.strategy = strategy;
	}
	
	//先序遍历二叉树
	public Iterator preOrder() {
		LinkedList list = new LinkedListDLNode();
		preOrderRecursion(this.root, list);
		//preOrderTraverse (root,list);
		return list.elements();
	}
	//先序遍历的递归算法
	private void preOrderRecursion(BinaryTreeNode rt, LinkedList list) {
		if (rt == null) return; //递归基,空树直接返回
		list.insertLast(rt); //访问根结点
		preOrderRecursion(rt.getLChild(), list); //遍历左子树
		preOrderRecursion(rt.getRChild(), list); //遍历右子树
	}
	//先序遍历的非递归算法
	private void preOrderTraverse(BinaryTreeNode rt, LinkedList list) {
		if (rt == null) return;
		BinaryTreeNode p = rt;
		Stack s = new StackLinked();
		while (p != null) {
			while (p != null) { //向左走到尽头
				list.insertLast(p);	//当前遍历节点
				if (p.hasRChild())
					s.push(p.getRChild()); //右子树根结点入栈
				p = p.getLChild();
			}
			if (!s.isEmpty()) p = (BinaryTreeNode) s.pop(); //右子树根退栈遍历右子树
		}
	}
	//中序遍历二叉树
	public Iterator inOrder() {
		LinkedList list = new LinkedListDLNode();
		inOrderTraverse(this.root, list);
		return list.elements();
	}
	//中序遍历的非递归算法
	private void inOrderTraverse(BinaryTreeNode rt, LinkedList list) {
		if (rt == null) return;
		BinaryTreeNode p = rt;
		Stack s = new StackLinked();
		while (p != null || !s.isEmpty()) {
			while (p != null) { //一直向左走
				s.push(p); //将根结点入栈
				p = p.getLChild();
			}
			if (!s.isEmpty()) {
				p = (BinaryTreeNode) s.pop();//取出栈顶根结点访问之
				list.insertLast(p);
				p = p.getRChild(); //转向根的右子树进行遍历
			}//if
		}//out while
	}
	//后序遍历二叉树
	public Iterator postOrder() {
		LinkedList list = new LinkedListDLNode();
		postOrderTraverse (this.root,list);
		return list.elements();
	}
	//后序遍历的非递归算法
	private void postOrderTraverse(BinaryTreeNode rt, LinkedList list) {
		if (rt == null) return;
		BinaryTreeNode p = rt;
		Stack s = new StackLinked();
		while(p != null || !s.isEmpty()) {
			while (p != null){ //先左后右不断深入
				s.push(p); //将根节点入栈
				if (p.hasLChild()) 
					p = p.getLChild();
				else 
					p = p.getRChild();
			}
			if (!s.isEmpty()) {
				p = (BinaryTreeNode) s.pop(); //取出栈顶根结点访问之
				list.insertLast(p);
			}
			//满足条件时,说明栈顶根节点右子树已访问,应出栈访问之
			while (!s.isEmpty() && ((BinaryTreeNode) s.peek()).getRChild() == p) {
				p = (BinaryTreeNode)s.pop();
				list.insertLast(p);
			}
			//转向栈顶根结点的右子树继续后序遍历
			if (!s.isEmpty()) 
				p = ((BinaryTreeNode) s.peek()).getRChild();
			else 
				p = null;
		}
	}
	//按层遍历二叉树
	public Iterator levelOrder() {
		LinkedList list = new LinkedListDLNode();
		levelOrderTraverse(this.root, list);
		return list.elements();
	}
	//使用队列完成二叉树的按层遍历
	private void levelOrderTraverse(BinaryTreeNode rt, LinkedList list) {
		if (rt == null) return;
		Queue q = new QueueArray();
		q.enqueue(rt); //根结点入队
		while (!q.isEmpty()) {
			BinaryTreeNode p = (BinaryTreeNode) q.dequeue(); //取出队首结点p 并访问
			list.insertLast(p);
			if (p.hasLChild()) 
				q.enqueue(p.getLChild());//将p 的非空左右孩子依次入队
			if (p.hasRChild()) 
				q.enqueue(p.getRChild());
		}
	}
	//在树中查找元素e,返回其所在结点
	public BinaryTreeNode find(Object e) {
		return searchElement(this.root, e);
	}
	//递归查找元素e
	private BinaryTreeNode searchElement(BinaryTreeNode rt, Object e) {
		if (rt == null) 
			return null;
		if (strategy.equal(rt.getData(), e)) 
			return rt; //如果是根结点,返回根
		BinaryTreeNode result = searchElement(rt.getLChild(), e); //否则在左子树中找
		if (result == null)
			result = searchElement(rt.getRChild(), e); //没找到,在右子树中找
		return result;
	}
}

 

 

  • 大小: 35.3 KB
  • 大小: 41.7 KB
分享到:
评论

相关推荐

    数据结构之二叉树【很好】

    数据结构之二叉树 二叉树是一种非常有用的非线性结构,它具有两个特点:非空二叉树只有一个根结点,每一个结点最多有两棵子树,且分别称为该结点的左子树与右子树。根据二叉树的概念可知,二叉树的度可以为 0(叶...

    数据结构之二叉树.rar

    本资料“数据结构之二叉树.rar”深入探讨了如何使用数组来实现二叉树的各种操作,包括插入、删除以及遍历,采用C++语言进行编程,并体现了面向对象的设计思想。 首先,我们要理解二叉树的基本概念。二叉树是由节点...

    数据结构之二叉树链表.rar

    本项目“数据结构之二叉树链表”着重探讨了如何在C++环境中实现链表形式的二叉树,以及相关的操作。 二叉树是一种非线性数据结构,每个节点最多有两个子节点,通常称为左子节点和右子节点。在数组存储的二叉树中,...

    编程数据结构之二叉树讲义

    【二叉树】是数据结构中的重要组成部分,它是一种特殊的树形结构,每个节点最多有两个子节点,分别称为左子节点和右子节点。二叉树的定义包括以下几个要点: 1. **根节点**:二叉树中只有一个特殊的节点,称为根...

    笔记7-数据结构之二叉树

    笔记7-数据结构之二叉树

    数据结构之二叉树和树(实验)

    数据结构之二叉树和树(实验)

    数据结构之二叉树实验

    /*1、建立二叉树; 2、实现该二叉树的先序遍历、中序遍历和后序遍历递归算法,输出各遍历序列; 3、统计出该二叉树中叶子结点个数; 4、实现该二叉树的中序遍历非递归算法; 5、实现交换该二叉树所有结点左右...

    数据结构之二叉树的C++实现源码

    在IT领域,数据结构是计算机科学的基础,而二叉树作为一种重要的数据结构,广泛应用于算法设计和程序开发中。本文将深入探讨如何使用C++语言实现二叉树,并结合提供的压缩包文件“PracticalTraining_Exam2_1_12_24”...

    c语言数据结构之二叉树实验

    1、参考P66建立二叉树的算法,建立图4-13(a)所示二叉树; 2、实现对该二叉树的先、中、后序遍历并输出遍历序列; 3、实现该二叉树的中序遍历非递归算法; 4、实现对该二叉树交换其左右子女的算法。

    C#语言实现数据结构之二叉树

    二叉树是一种特殊的数据结构,属于非线性的树形结构,由有限个节点组成。每个节点最多有两个子节点,分别称为左子节点和右子节点。这种特性使得二叉树在计算机科学中有着广泛的应用,如搜索、排序、文件系统等。...

    数据结构之二叉树ppt

    讲解非常详细,而且很容易理解!!!,并且在课件的后面还附加了课题,可以让你对上面的内容跟熟练。

    C语言数据结构实现二叉树的建立与遍历.cpp

    C语言数据结构实现二叉树的建立与遍历.cpp

    数据结构之二叉树(c语言描述)

    二叉树是一种特殊的树形数据结构,其中每个节点最多有两个子节点,分别称为左子节点和右子节点。这种结构在计算机科学中有着广泛的应用,例如在文件系统的目录结构、数据库索引、编译器语法分析等方面。二叉树的一个...

    数据结构之二叉树c语言代码

    一棵深度为k,且有2^k-1个结点的二叉树,称为满二叉树。这种树的特点是每一层上的结点数都是最大结点数。而在一棵二叉树中,除最后一层外,若其余层都是满的,并且或者最后一层是满的,或者是在右边缺少连续若干结点...

    合工大数据结构实验 二叉树

    本实验的主题是“二叉树”,这是数据结构中一个基础且重要的概念。二叉树是一种非线性的数据结构,由节点(或称为顶点)组成,每个节点最多有两个子节点,通常称为左子节点和右子节点。这个实验旨在帮助学生深入理解...

    数据结构之二叉树PPT学习教案.pptx

    二叉树是数据结构中的重要概念,是一种特殊的树形结构,每个节点最多有两个子节点,分别称为左子节点和右子节点。以下是对二叉树的深入解析: 1. **二叉树的基本定义**: - 二叉树可以为空,或者由一个根节点和...

    数据结构--二叉树--思维导图.pdf

    "数据结构--二叉树--思维导图" 二叉树是一种常见的数据结构,它是一种树形结构,每个节点最多有两个孩子节点,分别是左子树和右子树。二叉树可以用来存储大量数据,并且可以快速地查找、插入和删除数据。 二叉树的...

    数据结构程序之二叉树

    在IT领域,数据结构是计算机科学的基础,它研究如何有效地组织和存储数据,以便于算法的执行。...通过分析“数据结构之二叉树”这个压缩包中的内容,你将有机会亲手实现这些概念,并通过实践加深理解。

Global site tag (gtag.js) - Google Analytics