树和森林

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2014-7-15 9
二叉树的基本操作
(1)初始化操作——一般由构造函数实现 (2)建立一棵二叉树 (3)撤销一棵二叉树 ——可以由析构函数实现 (4)插入一个新结点 (5)删除一个结点 (6)查找 (7)判树空 (8)读取结点数据 (9)修改结点数据 (10)求二叉树的某一或某些性能(如结点数、高度、平衡度等) (11)求根结点、父结点、左子结点、右子结点等结点的指针 (12)调整一棵二叉树,优化某一或某些性能 (13)二叉树遍历操作 (14)其他操作
2014-7-15 5
6.3.2 二叉树的链式存储结构——二叉(三叉)链表结构
二叉链表结构: 左子指针 Байду номын сангаас据元素 右子指针
leftChild
data
rightChild
三叉链表结构:
左子指针 数据元素
leftChild data father
右子指针
rightChild
父指针
2014-7-15
6
二叉链表结构的二叉树结点(简称二叉树结点)的类定义: template <class Type> class BinaryTree;//二叉树类声明 template <class Type> class BinTreeNode//二叉树结点类定义 { friend class BinaryTree<Type>;//二叉树类是二叉树结点类的友元 public: BinTreeNode( ): leftChild(NULL),rightChild(NULL) { } //构造函数 BinTreeNode( Type item,BinTreeNode<Type> * left = NULL, BinTreeNode<Type> * right = NULL):data(item), leftChild(left),rightChild(right) { }//构造函数 … //其他成员函数 private: BinTreeNode<Type> * leftChild , * rightChild ; //左子指针、右子指针 Type data;//数据元素 }
2014-7-15 4
完全二叉树的性质和顺序存储结构 (1)具有 n 个结点的完全二叉树的高度 = log2 ( n + 1 ) – 1 (2)若将一棵按前述原则编号的完全二叉树,按其编号顺序存入一 个一维数组中,则有: 结点 i 的左子结点下标 = 2* i + 1 < n 结点 i 的右子结点下标 = 2* i + 2 < n 结点 i 的父结点下标 = ( i – 1 ) / 2 的下取整值 另外注意:根结点(下标为0)无父结点 由上可知,完全二叉树的父——左子、父——右子之间的 关系可以通过相应结点的下标之间的简单数学关系完全地表示 出来,因此可以采用顺序存储结构来存储完全二叉树。(参见 教材 6.3.1 数组表示) 顺序存储结构用于动态性较小的完全二叉树的存储不失为 一种简单有效的方法,但不通用。树型数据结构一般采用链式存 储方式来存储。
2014-7-15
10
根据所定义的操作不同,可以有不同性能的二叉树 (1)线索化二叉树( Threaded Binary Tree ):在二叉树结点中增加前 驱指针和后继指针,使得在二叉树中查找当前结点的在某种遍 历方式下的前驱和后继结点很方便 (2)堆( Heap ):用来实现高效率的优先级队列的二叉树,采用顺序 存储结构。其特点是:树中任一结点的关键码均小(大)于或 等于它的左子结点和右子结点的关键码,称为最小(大)堆。 (3)霍夫曼树(Huffman Tree ) :带权路径长度 WPL 最小的(扩充) 二叉树。WPL----Weighted Path Length (4)二叉排序树(Binary Sorting Tree ) 二叉搜索树(Binary Search Tree ) 中序遍历为严格递增的二叉树。这种树可以提高搜索(查找) 效率。 (5)最优二叉搜索树:平均搜索长度最小的二叉搜索树。 (6)AVL 树:高度平衡的二叉搜索树,可以提高搜索效率,减小平 均搜索长度 (7)其他
先序遍历(NLR) 中序遍历(LNR) 后序遍历(LRN)
访问根结点 先序遍历左子树 先序遍历右子树
中序遍历左子树 访问根结点 中序遍历右子树
后序遍历左子树 后序遍历右子树 访问根结点
可以看出,上述三种顺序的二叉树遍历操作都是递归定义的, 因此用递归算法实现很容易。
2014-7-15
12
二叉树的先序遍历操作递归算法
2014-7-15 8
virtual int Insert( const Type & item );//插入值为 item 的新结点 virtual int Find( const Type & item ) const ;//查找值为 item 的结点 const BinTreeNode<Type> * GetRoot( ) const { return root ; } //求根结点的指针 friend istream & operator >> ( istream & in , BinTreeNode<Type> & Tree ); //重载操作:输入数据元素并建立一棵二叉树 Tree friend ostream & operator << ( ostream & out , BinTreeNode<Type> & Tree ) ; //重载操作:输出一棵二叉树 Tree Private: BinTreeNode<Type> * root;//根结点指针 Type RefValue;//数据输入结束标志,仅用于输入 BinTreeNode<Type> * Parent( BinTreeNode<Type> * start, BinTreeNode<Type> * current ); //求 start 树中 *current 结点的父结点指针 int Insert( BinTreeNode<Type> * & current, const Type & item ); //在 current 树中插入值为 item 的新结点 void Traverse(BinTreeNode<Type> * current ,ostream & out ) const; //遍历输出 current 二叉树 int Find ( BinTreeNode<Type> * current, const Type & item ) const ; //在 current 树中查找值为 item 的结点 void destroy(( BinTreeNode<Type> * current ); //删除 current 树的所有结点 }
2014-7-15 3
6.2 二叉树( Binary Tree )
二叉树是树的基础,一般的树可以转化为二叉树来处理。 6.2.1 二叉树的定义 一棵二叉树是一有限结点的集合,该集合或者为空(空二叉 树),或者是由一个根结点及其下的两棵互不相交的子二叉树构 成,其中左边的称为左子树,右边的称为右子树。 二叉树是一棵度数 <= 2 的有序树。 6.2.2 二叉树的性质 i (1)二叉树的第 i 层的结点数 <= 2 k+1 (2)高度为 k 的二叉树的最大结点数= 2 - 1 ( k >= -1) 满二叉树( Full Binary Tree ):叶结点在同一层,非叶结点的度数均 为 2 的二叉树(参见图6.3a ) 完全二叉树( Complete Binary Tree ): 按从上到下、从左到右顺序 编号一棵满二叉树,并按从大到小的顺序连续删除 该满二叉树的若干个结点后剩下的二叉树称为一棵 完全二叉树(参见图6.3b )
2014-7-15 1
树的示意图: 根结点 根 结 叶结点 点 分支结点 结点的层次 Level 0 子树 Level 1
Level 2
子树 子树 Level 3
2
2014-7-15
树的基本术语
结点的度( degree ):结点所拥有的子树数目 子女( child ) 结点:简称子结点 双亲( parent) 结点:简称父结点( father ) 兄弟( sibling)结点:具有同一个父结点的结点 根( root ) 结点: 分支( branch )结点:又称非终端结点 叶( leaf ) 结点:又称终端结点 结点的层次( level ):根结点的层次为0,子结点的层次等于其父结 点的层次加一 树的高度( depth ):等于树中最大的结点层次数。空树的高度为-1 树的度( degree ):等于树中最大的结点度数 有序树:树中结点的各子树之间的先后次序是有意义的,不能互换, 否则就成为另一棵树了。 无序树:树中结点的各子树之间的先后次序无意义,可以互换 森林( forest ):若干棵树的集合
template <class Type> void BinaryTree<Type>:: PreOrder ( ) //公共函数:先序遍历二叉树,通过调用私有函数 PreOrder 实现 { PreOrder ( root ); } template <class Type> void BinaryTree<Type> :: PreOrder ( BinTreeNode<Type> * current ) //私有函数:先序遍历根结点指针为 current 的二叉树 { if ( current ! = NULL ) {//若二叉树不空,则先序遍历之 Visit ( current ); //访问根结点 *current PreOrder ( current -> leftChild ); //先序遍历左子树 PreOrder ( current -> rightChild ); //先序遍历右子树 } }
2014-7-15 7
二叉链表结构的二叉树的类定义 template <class Type> class BinaryTree { public: BinaryTree( ) : root(NULL) { }//创建一棵空二叉树 BinaryTree( Type value ) : RefValue(value) , root(NULL) { } virtual ~ BinaryTree( ) { destroy ( root ) }//删除一棵二叉树 virtual int IsEmpty( ) { return root == NULL ;}//判树空 virtual BinTreeNode<Type> * Parent( BinTreeNode<Type> *current ) { return root == NULL || root == current ?NULL : Parent( root , current ) ;}//求 *current 结点的父结点指针 virtual BinTreeNode<Type> * LeftChild( BinTreeNode<Type> * current ) { return current != NULL ? Current ->leftChild :NULL ; } //求 *current 结点的左子结点指针 virtual BinTreeNode<Type> * RightChild( BinTreeNode<Type> * current ) { return current != NULL ? Current ->rightChild :NULL ; } //求*current 结点的右子结点指针
2014-7-15 11
6.4 二叉树遍历(Binary Tree Traversal ) 操作
遍历:按照某种顺序不重复地访问遍二叉树中的所有结点。此处的 访问可以是输出、修改等操作,根据实际需要而定。 遍历操作可以从一种非线性结构中得到相应的线性序列。 有不同顺序的遍历操作,对于二叉树有三种遍历操作:
第6章 树和森林
非线性数据结构 实际中有许多树型结构的问题,用树型数据结构来解决非常自然 树型结构在计算机领域的应用非常广泛 6.1 树和森林的概念 树的定义: 树是由 n ( n>=0 ) 个结点组成的有限集合。若 n = 0 则称为空树, 否则: (1)有一个特定的称之为根( root )的结点,它只有直接后继, 但没有直接前驱; (2)除根以外的其他结点可划分为若干个互不相交的有限集合, 每个集合又是一棵树,并且称之为根的子树( subTree )。每 棵子树的根结点有且仅有一个直接前驱,但可以有0个或多 个直接后继。
相关文档
最新文档