1 / 41

第二次直播

第二次直播. 清华大学 殷人昆. 中央电大 徐孝凯. 本次要讲的问题. 第五章 递归与广义表 第六章 树与二叉树. 第五章 递归与广义表. 学习目的 掌握递归问题求解方法 运用递归方法求解应用问题. 需要掌握的知识点 递归概念 : 什么是递归? 递归的函数定义 递归的数据结构 递归问题的解法 链表是递归的数据结构 可用递归过程求解有关链表的问题. 递归实现时栈的应用 递归求解思路 递归过程与递归工作栈:递归过程实现的机制及递归工作栈的引用 递归的分层 ( 树形 ) 表示 : 递归树 递归深度 ( 递归树的深度 ) 与递归工作栈的关系

laird
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. 本次要讲的问题 • 第五章 递归与广义表 • 第六章 树与二叉树

  3. 第五章 递归与广义表 • 学习目的 • 掌握递归问题求解方法 • 运用递归方法求解应用问题

  4. 需要掌握的知识点 • 递归概念: • 什么是递归? • 递归的函数定义 • 递归的数据结构 • 递归问题的解法 • 链表是递归的数据结构 • 可用递归过程求解有关链表的问题

  5. 递归实现时栈的应用 • 递归求解思路 • 递归过程与递归工作栈:递归过程实现的机制及递归工作栈的引用 • 递归的分层(树形)表示 :递归树 • 递归深度(递归树的深度)与递归工作栈的关系 • 单向递归与尾递归的迭代实现

  6. 广义表 • 广义表定义 • 广义表长度、深度、表头、表尾 • 广义表的表示及操作 • 用图形表示广义表的存储结构 • 广义表的递归算法

  7. 递归举例 • 求解斐波那契数列的递归算法 long Fib ( longn ) { if ( n <= 1 ) returnn; else returnFib (n-1) + Fib (n-2); }

  8. 考虑使用递归算法求解的思路 • 递归算法的一般形式 void p ( 参数表 ) if ( 递归结束条件) 可直接求解步骤;基本项 else p ( 较小的参数 ); 递归项

  9. 例 求数组 A 中 n 个整数的和 int sum ( int n ) { if ( n == 0 ) return A[0]; //直接求解 else return A[n] + sum(n-1); //求n-1个整数的和, 再加A[n] }

  10. 递归与回溯常用于搜索过程 • 例 n皇后问题 在n行 n列的国际象棋棋盘上,若两个皇后位于同一行、同一列、同一对角线上,则称为它们为互相攻击。n皇后问题是指找到这n个皇后的互不攻击的布局。

  11. k = n+i-j-1 0#次对角线 2#次对角线 4#次对角线 6#次对角线 1#次对角线 3#次对角线 5#次对角线 0 1 2 3 0 1 2 3    0#主对角线 2#主对角线 4#主对角线 6#主对角线 1#主对角线 3#主对角线 5#主对角线  k = i+j

  12. 解题思路 • 安放第 i行皇后时,需要在列的方向从 1 到 n试探 ( j = 1, …, n ) • 在第 j 列安放一个皇后: • 如果在列、主对角线、次对角线方向有其它皇后,则出现攻击,撤消在在第 j 列安放的皇后。 • 如果没有出现攻击,安放第 i+1行皇后。

  13. 设置 4 个数组 • col [n]:col[i] 标识第 i 列是否安放了皇后 • md[2n-1] : md[k] 标识第 k 条主对角线是否安放了皇后 • sd[2n-1] : sd[k] 标识第 k 条次对角线是否安放了皇后 • g[n] : g[i] 记录第 i 行皇后在第几列

  14. void green( int i ) { for ( int j = 1; j <= n; j++ ) { if ( 第 i行第 j列没有攻击 ) { 在第 i行第 j列安放皇后; if ( i == n ) 输出一个布局; else green ( i+1 ); } 撤消第 i行第 j列的皇后; } }

  15. 算法求精 void green( int i ) { for ( int j = 1; j <= n; j++ ) { if ( !col[j] && !md[n+i-j-1] && !sd[i+j] ) { /*第 i 行第 j 列没有攻击 */ col[j] = md[n+i-j-1] = sd[i+j] = 1; g[i] = j; /*在第 i行第 j列安放皇后*/

  16. if ( i == n ) { /*输出一个布局*/ for ( j = 0; j <= n; j++ ) cout << g[j] << ‘,’; cout << endl; } else green ( i+1 ); } col[j] = md[n+i-j-1] = sd[i+j] = 0; g[i] = 0; /*撤消第i行第j列的皇后*/ } }

  17. 第六章 树与二叉树 • 学习目的 • 理解树与二叉树的结构特点 • 掌握树与二叉树的特定应用(如堆、霍夫曼树等)

  18. 需要掌握的知识点 • 树 树的定义、树的基本运算 • 树的分层定义是递归的 • 树中结点个数与高度的关系 • 二叉树 二叉树定义、基本运算 • 二叉树性质 • 二叉树结点个数与高度的关系 • 不同二叉树的棵数

  19. 完全二叉树的顺序存储 • 完全二叉树的双亲、子女和兄弟的位置 • 二叉树的前序 · 中序 · 后序 · 层次遍历 • 前序 · 中序 · 后序的线索化二叉树中前驱与后继的查找方法 • 应用二叉树遍历的递归算法

  20. 霍夫曼树 • 霍夫曼树的构造方法 • 霍夫曼编码 • 带权路径长度的计算 • 树的存储 • 树的广义表表示与双亲表示 • 树与二叉树的对应关系 • 树的先根 · 后根 · 层次遍历

  21. 堆堆的定义、堆的插入与删除 • 形成堆时用到的向下调整算法 • 形成堆时比较次数的上界估计 • 堆插入时用到的向上调整算法 • 堆的插入与删除算法

  22. 【例1】在结点个数为n (n > 1)的各棵树中,高度最小的树的高度是多少?它有多少叶结点?多少分支结点?高度最大的树的高度是多少?它有多少叶结点?多少分支结点?

  23. 【解答】结点个数为 n 时, 高度最小的树的高度为 1, 有 2层;有 n-1 个叶结点,1 个分支结点; 高度最大的树的高度为 n-1, 有 n 层;它有 1 个叶结点, n-1个分支结点

  24. 【例2】已知一棵二叉树的前序遍历的结果序列是【例2】已知一棵二叉树的前序遍历的结果序列是 ABECDFGHIJ 中序遍历的结果序列是 EBCDAFHIGJ 试画出这棵二叉树。

  25. 【解答】前序序列ABECDFGHIJ,中序序列 EBCDAFHIGJ时: A A B F EBCD FHIGJ E CD HIGJ

  26. 前序序列ABECDFGHIJ 中序序列 EBCDAFHIGJ A A B F B F E C G E C G D H J D HI J I

  27. 【例3】若用二叉链表作为二叉树的存储表示,试针对以下问题编写递归算法:【例3】若用二叉链表作为二叉树的存储表示,试针对以下问题编写递归算法: (1) 统计二叉树中叶结点个数。 (2) 以二叉树为参数, 交换每个结点的左子女和右子女。

  28. 【解答】 (1) 定义二叉树结构 template <class Type> classBinaryTree; //二叉树 template <class Type> classBinTreeNode //二叉树结点 leftChild data rightChild

  29. 3 (2) 统计二叉树中叶结点个数 2 1 0 1 1 1 0 1

  30. template <class Type> int leaf ( BinTreeNode<Type>*t ) { if ( !t ) return 0; else if ( !t→leftChild && !t→rightChild ) return 1; else return leaf ( t→leftChild ) + leaf ( t→rightChild ); }

  31. (3) 交换每个结点的左子女和右子女

  32. template <class Type> void exchange ( BinTreeNode<Type>*t ) { BinTreeNode<Type>*p; if ( t→leftChild || t→rightChild ) { //非叶结点,交换左、右子女 p = t→leftChild; t→leftChild = t→rightChild ; t→rightChild = p;

  33. exchange ( t→leftChild ); exchange ( t→rightChild ); } }

  34. 【例4】假定用于通信的电文仅由 8 个字母 c1, c2, c3, c4, c5, c6, c7, c8组成, 各字母在电文中出现的频率分别为 5, 25, 3, 6, 10, 11, 36, 4。试为这 8 个字母设计不等长 Huffman 编码, 并给出该电文的总码数。

  35. 【解答】

  36. 则Huffman编码为 c1 c2 c3 c4 c5 c6 c7 c8 1110 00 1100 1111 100 101 01 1101 电文总码数为 4 * 5 + 2 * 25 + 4 * 3 + 4 * 6 + 3 * 10 + 3 * 11 + 2 * 36 + 4 * 4 = 257

  37. 【例5】下面是对二叉树进行中序遍历的递归算法。【例5】下面是对二叉树进行中序遍历的递归算法。 template <class Type> void inorder ( BinTreeNode<Type>*t ) { if ( t ) { inorder ( t→leftChild); cout << t→data; inorder ( t→rightChild); } }

  38. 将算法中的第二个递归语句消去, 这相当于尾递归,可用循环实现 template <class Type> void inorder ( BinTreeNode<Type>*t ) { while ( t ) { inorder ( t→leftChild); cout << t→data; t = t→rightChild; } }

  39. 接着, 将算法中的第一个递归语句消去, 这必须借助于栈, 记忆回退的路径. template <class Type> void InOrder( BinTreeNode<Type>* t) { StackTypeS; BinTreeNode<Type>*p = t; S.makeEmpty( );//初始化

  40. do{ while ( p ) {S.Push(p);p = p→leftChild; } if ( !S.IsEmpty( ) ) { p = S.getTop( ); S.Pop( ); cout << p→data << endl; p = p→rightChild; } } while ( p || !S.IsEmpty( ) ); }

  41. 下一次直播时间:5月10号 同学们:再见!

More Related