1 / 162

树和 二叉树 二叉树遍历 线索二叉树 二叉搜索树 二叉树的计数 堆 树与森林 霍夫曼树及其应用

第六章 树和森林. 树和 二叉树 二叉树遍历 线索二叉树 二叉搜索树 二叉树的计数 堆 树与森林 霍夫曼树及其应用. 一、树和二叉树. 树 tree 的定义 (1) 无结点的树 空树 (2) 非空树 仅有一个 根 结点 其余结点分为若干 互不相交的 子树. A. ········································ 根. 3 度. D. B. C. H. I. J.

rio
Télécharger la présentation

树和 二叉树 二叉树遍历 线索二叉树 二叉搜索树 二叉树的计数 堆 树与森林 霍夫曼树及其应用

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第六章 树和森林 • 树和 二叉树 • 二叉树遍历 • 线索二叉树 • 二叉搜索树 • 二叉树的计数 • 堆 • 树与森林 • 霍夫曼树及其应用

  2. 一、树和二叉树 树tree的定义 (1) 无结点的树 空树 (2) 非空树 仅有一个根结点 其余结点分为若干 互不相交的子树

  3. A ········································根 3度 D B C H I J ·············叶 0度 E F G K L M 2个3度点 A,D 2个2度点 B,E 2个1度点 C,H 7个叶 F,G,I,J,K,L,M

  4. A ·············································第一层 ······························第二层 D B C ···············第三层 H I J E F G K L ····································第四层 M 树的深度为4

  5. 2.二叉树 每个结点至多有两棵子树,1度或2度 A C B F G D E H I J

  6. 设有n2个2度点 则有n2+1个叶片 A C B F G D E H I J 第i层结点至多2i-1个 深度为k,结点至多2k-1个

  7. 满二叉树 深度为k,结点数2k-1,每层结点数都最大 A C B F G D E H J K L M N O I

  8. 满二叉树 完全二叉树 满二叉树去掉最下层最右边若干结点 A C B F G D E H J K L M N O I 满二叉树也是完全二叉树

  9. n个结点,深度 k=[log2n] +1 完全二叉树 n个结点,深度为k: 2k-1-1<n≤2k-1 2k-1 ≤ n <2k k-1 ≤ log2n <k k-1 = [log2n] k = [log2n] +1 A C B F G D E H I J K L M 1个结点深度为1 2-3个结点深度为2 4-7个结点深度为3 8-15个结点深度为4

  10. 完全二叉树 结点i的左子结点是2i 右子结点是2i+1 1 3 2 6 7 4 5 8 9 10 11 12 13 结点i的父结点是[i/2]

  11. 二叉树的存储 • 完全二叉树的顺序存储 #define MaxTreeSize 100 typedef TElemTypeSqBiTree[MaxTreeSize]; SqBiTree bt;

  12. 结点i的父结点是[(i-1)/2] 完全二叉树 结点i的左子结点是2i+1 右子结点是2i+2 0 2 1 5 6 3 4 7 8 9 10 11 12

  13. 二叉树的链式存储 树结点

  14. A C B E F D G H

  15. 二叉树结点类的定义 #ifndef TREENODE_CLASS #define TREENODE_CLASS #ifndef NULL const int NULL = 0; #endif // NULL

  16. template <class T>class BinSTree; template <class T> class TreeNode { protected: TreeNode<T> *left, *right; public: Tdata; TreeNode (const T& item, TreeNode<T> *lptr = NULL, TreeNode<T> *rptr = NULL); virtual ~TreeNode(void); TreeNode<T>* Left(void) const; TreeNode<T>* Right(void) const; void GetLeft(TreeNode<T>*lptr); void GetRight(TreeNode<T>*rptr); friend class BinSTree<T>; };

  17. // the pointer NULL assigns an empty tree template <class T> TreeNode<T>::TreeNode (const T& item, TreeNode<T> *lptr, TreeNode<T> *rptr): data(item), left(lptr), right(rptr) {}

  18. // method Left allows the user// to reference the left child template <class T> TreeNode<T>* TreeNode<T>::Left(void) const { // return the private member value left return left; }

  19. // method Left allows the user //to reference the right child template <class T> TreeNode<T>* TreeNode<T>::Right(void) const { // return the private member value right return right; }

  20. // does nothing. //exists so nodes derived from it will be // destroyed properly by delete. //used in Chapter 13 for AVL trees template <class T> TreeNode<T>::~TreeNode(void) {} #endif

  21. 二叉树结点的操作函数//treelib.h #ifndef TREE_LIBRARY_FUNCTIONS #define TREE_LIBRARY_FUNCTIONS #include <iostream.h> #include <stdlib.h> #include "treenode.h" #ifndef NULL const int NULL = 0; #endif // NULL

  22. 建立一个结点 template <class T> TreeNode<T> *GetTreeNode(T item, TreeNode<T> *lptr= NULL, TreeNode<T> *rptr = NULL) { TreeNode<T> *p; p = new TreeNode<T> (item, lptr, rptr); if (p == NULL) { cerr << "Memory allocation failure!\n"; exit(1); } return p; }

  23. 撤销一个结点 template <class T> void FreeTreeNode(TreeNode<T> *p) { delete p; }

  24. 创建三棵树 void MakeCharTree(TreeNode<char>* &root, int n) { TreeNode<char> *a, *b, *c, *d, *e, *f, *g, *h, *i; switch(n) { case 0: d = GetTreeNode('D'); e = GetTreeNode('E'); b = GetTreeNode('B',(TreeNode<char> *)NULL, d); c = GetTreeNode('C',e, (TreeNode<char> *)NULL); a = GetTreeNode('A',b, c); root = a; break; A C B D E

  25. case 1: g = GetTreeNode('G'); h = GetTreeNode('H'); i = GetTreeNode('I'); d = GetTreeNode('D'); e = GetTreeNode('E',g, (TreeNode<char> *)NULL); f = GetTreeNode('F',h, i); b = GetTreeNode('B',d, e); c = GetTreeNode('C',(TreeNode<char> *)NULL, f); a = GetTreeNode('A',b, c); root = a; break; A C B F D E G H I

  26. case 2: g = GetTreeNode('G'); h = GetTreeNode('H'); i = GetTreeNode('I'); d = GetTreeNode('D',(TreeNode<char> *)NULL, g); e = GetTreeNode('E',h, i); f = GetTreeNode('F'); • b = GetTreeNode('B',d, (TreeNode<char> *)NULL); c = GetTreeNode('C',e, f); a = GetTreeNode('A',b, c); root = a; break;} } A C B F D E G H I

  27. 为代数式 a+b*(c-d)-e/f 建一棵树 使a,b,c,d,e,f为叶,两个数之间的运算符为根. a=GetTreeNode(‘a’,(TreeNode<char>)NULL, (TreeNode<char>)NULL); — p1=GetTreeNode(‘-’,c,d); + / p2=GetTreeNode(‘*’,b,p1); a * e f p3=GetTreeNode(‘+’,a,p2); p4=GetTreeNode(‘/’,e,f); — b p5=GetTreeNode(‘-’,p3,p4); root=p5; c d

  28. 二、二叉树的遍历 先序遍历 PreOrderTraverse 先访问根结点 再访问左子树 后访问右子树 中序遍历 InOrderTraverse 先访问左子树 再访问根结点 后访问右子树 后序遍历 PostOrderTraverse 先访问左子树 再访问右子树 后访问根结点 层次遍历(Level Traverse )

  29. 先序遍历 template <class T> void Preorder (TreeNode<T> *t, void visit(T& item)) { // the recursive scan terminates on a empty subtree if (t != NULL) { visit(t->data); // visit the node Preorder (t->Left( ), visit); // descend left Preorder (t->Right( ), visit); // descend right } } A C B F D E G H I void print(char& itm){cout<<itm;} Preorder(root,print); ABDEGCFHI

  30. 中序遍历 A template <class T> void Inorder (TreeNode<T> *t, void visit(T& item)) { // the recursive scan terminates on a empty subtree if (t != NULL) { Inorder(t->Left( ), visit); // descend left visit(t->data); // visit the node Inorder (t->Right( ), visit); // descend right } } C B F D E G H I DBGEACHFI

  31. 后序遍历 A template <class T> void Postorder (TreeNode<T> *t, void visit(T& item)) { // the recursive scan terminates on a empty subtree if (t != NULL) { Postorder (t->Left( ), visit); // descend left Postorder (t->Right( ), visit); // descend right visit(t->data); // visit the node } } C B F D E G H I DGEBHIFCA

  32. 二叉树的运算 template <class T> void CountLeaf (TreeNode<T> *t, int& count) { if (t != NULL) {CountLeaf(t->Left( ), count); CountLeaf(t->Right( ), count); if (t->Left( ) == NULL && t->Right( ) == NULL) count++; } }

  33. template <class T> int Depth (TreeNode<T> *t) { int depthLeft, depthRight, depthval; if (t == NULL) depthval = 0; else { depthLeft= Depth(t->Left( )); depthRight= Depth(t->Right( )); depthval = 1 + (depthLeft> depthRight?depthLeft:depthRight); } return depthval; }

  34. template <class T> TreeNode<T> *CopyTree(TreeNode<T> *t) { TreeNode<T> *newlptr, *newrptr, *newnode; if (t == NULL) return NULL; if (t->Left( ) = NULL) newlptr = NULL; else newlptr = CopyTree(t->Left( )); if (t->Right( ) = NULL) newrptr = NULL; else newrptr = CopyTree(t->Right()); newnode = GetTreeNode(t->data, newlptr, newrptr); return newnode; }

  35. template <class T> void DeleteTree(TreeNode<T> *t) { if (t != NULL) { DeleteTree(t->Left()); DeleteTree(t->Right()); FreeTreeNode(t); } }

  36. 输入一棵树 A C B 按先序输入一棵树 键盘输入: AB#D##CE### template<class T> void CreateTree(TreeNode<T>*&t ) {TreeNode<T>*l,*r; Tch; cin>>ch; if(ch==‘#’)t=NULL; else{t=GetTreeNode(ch); CreateTree(l); t->GetLeft(l); CreateTree(r);t->GetRight(r);} } D E

  37. template <class T> void ClearTree(TreeNode<T> * &t) { DeleteTree(t); t = NULL; // root now NULL } #endif// TREE_LIBRARY_FUNCTIONS

  38. 层次遍历——广度优先法遍历树 A template <class T> void LevelScan(TreeNode<T>*t,void visit(T& item)) {Queue<TreeNode<T>*> Q; TreeNode<T> * p; Q.Qinsert(t); while(!Q.Qempty( )) { p=Q.Qdelete( ); visit(p->data); if(p->Left( )!=NULL)Q.Qinsert(p->Left( )); if(p->Right( )!=NULL)Q.Qinsert(p->Right( )); } } C B ABCDEFGHI F D E G H I

  39. 测试 #include <iostream.h> #include "treenode.h" #include "treelib.h" void print(char& item) {cout<<item;} void main(void) { TreeNode<char> *root; MakeCharTree(root, 2); int leafCount = 0; CountLeaf(root, leafCount); cout << "Number of leaf nodes is " << leafCount << endl; cout << "The depth of the tree is " << Depth(root) << endl; CreateTree(root); Postorder(root,print); }

  40. 三、线索二叉树 ltag=0 lchild指向左子结点 =1 前驱 rtag=0 rchild指向右子结点 =1 后继 带线索的二叉树,即每个结点都带有指向其前驱和后继的指针的二叉树 优点:遍历查找方便快捷,从任何结点可 以向前向后搜索 用途:需要反复遍历和查找的二叉树

  41. 中序线索化树 A C B D E

  42. 线索二叉树的结点类#include<iostream.h>#include<stdio.h>typedef enum{ Link, Thread //Link==0; Thread==1;}PointerTag;

  43. template <class T>class ThreadNode{ ThreadNode<T> *left, *right; //pointer PointerTag LTag, RTag; // tags for link or thread public:Tdata;ThreadNode(const T item):data(item),left(NULL),right(NULL),LTag(0),RTag(0) { }}

  44. template <class T>void InOrderThreading(ThreadNode<T>*&thrt, ThreadNode<T>* tree){ ThreadNode<T> *pre;thrt=new ThreadNode<T>; if(!thrt) { cerr<<"Memory overflow!"; exit(1); }thrt->LTag=Link;thrt->RTag=Thread;thrt->right=thrt; //right pointer point to its self

  45. if(tree==NULL) thrt->left=thrt;//if "tree" is empty, //left pointer point to its self either else { thrt->left=tree; pre=thrt; InThreading(tree); pre->RTag=Thread; pre->right=thrt; thrt->right=pre;}}

  46. template <class T>void InThreading(ThreadNode<T> *p){ if(p) { InThreading(p->left); if(p->left==NULL) { p->LTag=Thread;p->left=pre; } if(pre->right==NULL) { pre->RTag=Thread;pre->right=p; }pre=p;InThreading(p->rchild); }}

  47. template <class T>void InOrderTravers(ThreadNode<T>*t , void visit(Titem)){ ThreadNode *p;p = t->left; while(p!=t) { while(p->LTag==Link)p=p->left;visit(p->data); while(p->RTag==Thread&&p->right!=t) { p=p->right;visit(p->data); } p = p->right; }}

  48. 四、二叉搜索树 (二叉排序树) 其左非空子树上所有结点的值都小于根结点的值 其右非空子树上所有结点的值都大于根结点的值 左右子树也是二叉搜索树 二叉搜索树的作用:排序,检索 45 57 12 60 50 8 20 3 11 59

  49. 二叉搜索树 #ifndef BINARY_SEARCH_TREE_CLASS #define BINARY_SEARCH_TREE_CLASS #include <iostream.h> #include <stdlib.h> #ifndef NULL const int NULL = 0; #endif // NULL #include "treenode.h"

  50. template <class T> class BinSTree { TreeNode<T> *root, *current; int size; TreeNode<T> *GetTreeNode(const T& item, TreeNode<T> *lptr,TreeNode<T> *rptr); void FreeTreeNode(TreeNode<T> *p); TreeNode<T> *CopyTree(TreeNode<T> *t); void DeleteTree(TreeNode<T> *t); TreeNode<T> *FindNode(const T& item, TreeNode<T>* & parent) const;

More Related