随笔分类 -  算法/数据结构

一步一步写平衡二叉树(AVL树)
摘要:原文地址:http://www.cppblog.com/cxiaojia/archive/2012/08/20/187776.html平衡二叉树(Balanced Binary Tree)是二叉查找树的一个进化体,也是第一个引入平衡概念的二叉树。1962年,G.M. Adelson-Velsky 和 E.M. Landis发明了这棵树,所以它又叫AVL树。平衡二叉树要求对于每一个节点来说,它的左右子树的高度之差不能超过1,如果插入或者删除一个节点使得高度之差大于1,就要进行节点之间的旋转,将二叉树重新维持在一个平衡状态。这个方案很好的解决了二叉查找树退化成链表的问题,把插入、查找、删除的时间复 阅读全文

posted @ 2012-11-13 23:17 zhuyf87 阅读(5761) 评论(1) 推荐(1)

AVL树
摘要:AVL(Adelson-Velskii and Landis)树是带有平衡条件(balance condition)的二叉查找树。这个平衡条件必须容易保持,而且必须保证树的深度是O(logN)。AVL树规定其每个结点的左子树和右子树的高度最多差1。如下图,左边的树是AVL树,右边的则不是。AVL树的每个结点(在其结点结构中)保留高度信息。可以证明,一般情况下,一棵AVL树的高度最多为1.44log(N+2) – 1.328,并且实际上的高度只比logN稍微多一点。下图显示了一棵具有最少结点(143)高度为9的AVL树。这棵树的左子树是高度为7且结点数最少的AVL树,右子树是高度为8且结点数最少 阅读全文

posted @ 2012-11-12 22:22 zhuyf87 阅读(4304) 评论(0) 推荐(1)

二叉排序树
摘要:二叉排序树又称“二叉查找树”、“二叉搜索树”。二叉排序树:或者是一棵空树,或者是具有下列性质的二叉树:1. 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;2. 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;3. 它的左、右子树也分别为二叉排序树。二叉排序树通常采用二叉链表作为存储结构。中序遍历二叉排序树可得到一个依据关键字的有序序列,一个无序序列可以通过构造一棵二叉排序树变成一个有序序列,构造树的过程即是对无序序列进行排序的过程。每次插入的新的结点都是二叉排序树上新的叶子结点,在进行插入操作时,不必移动其它结点,只需改动某个结点的指针,由空变为非空即可。搜索、插 阅读全文

posted @ 2012-11-09 18:12 zhuyf87 阅读(72047) 评论(4) 推荐(6)

Huffman 编码压缩算法
摘要:原文地址:http://coolshell.cn/articles/7459.html/comment-page-1前两天发布那个rsync算法后,想看看数据压缩的算法,知道一个经典的压缩算法Huffman算法。相信大家应该听说过 David Huffman 和他的压缩算法—— Huffman Code,一种通过字符出现频率,Priority Queue,和二叉树来进行的一种压缩算法,这种二叉树又叫Huffman二叉树 —— 一种带权重的树。从学校毕业很长时间的我忘了这个算法,但是网上查了一下,中文社区内好像没有把这个算法说得很清楚的文章,尤其是树的构造,而正好看到一篇国外的文章《A Simp 阅读全文

posted @ 2012-11-06 07:17 zhuyf87 阅读(1312) 评论(0) 推荐(0)

赫夫曼树及其应用
摘要:美国数学家赫夫曼(David Huffman)1952年发明了一种压缩编码方法,并得到广泛应用。为了纪念他的成就,人们把他在编码中用到的特殊的二叉树叫做赫夫曼树,他的编码方法叫做赫夫曼编码。下面一段程序用来给学生考试成绩划分等级:if (a < 60) b = "不及格";else if (a < 70) b = "及格";else if (a < 80) b = "中等";else if (a < 90) b = "良好";else b = "优秀";这段程序的判断过程 阅读全文

posted @ 2012-11-06 06:57 zhuyf87 阅读(4228) 评论(0) 推荐(1)

树、森林和二叉树的转换
摘要:树转换为二叉树(1)加线。在所有兄弟结点之间加一条连线。(2)去线。树中的每个结点,只保留它与第一个孩子结点的连线,删除它与其它孩子结点之间的连线。(3)层次调整。以树的根节点为轴心,将整棵树顺时针旋转一定角度,使之结构层次分明。(注意第一个孩子是结点的左孩子,兄弟转换过来的孩子是结点的右孩子)森林转换为二叉树(1)把每棵树转换为二叉树。(2)第一棵二叉树不动,从第二棵二叉树开始,依次把后一棵二叉树的根结点作为前一棵二叉树的根结点的右孩子,用线连接起来。二叉树转换为树是树转换为二叉树的逆过程。(1)加线。若某结点X的左孩子结点存在,则将这个左孩子的右孩子结点、右孩子的右孩子结点、右孩子的右孩子 阅读全文

posted @ 2012-11-04 17:04 zhuyf87 阅读(102970) 评论(5) 推荐(23)

二叉树的三叉链表存储和基本操作
摘要:三叉链表存储表示改进于二叉链表,增加指向父节点的指针,能更好地实现结点间的访问。存储结构/* 二叉树的三叉链表存储表示 */ typedef struct BiTPNode { TElemType data; struct BiTPNode *parent,*lchild,*rchild; /* 双亲、左右孩子指针 */ }BiTPNode,*BiPTree;基本操作(基于C/C++的实现算法)/* 二叉树的三叉链表存储的基本操作(21个) */ #define ClearBiTree DestroyBiTree /* 清空二叉树和销毀二叉树的操作一样 */ void InitBiTr... 阅读全文

posted @ 2012-11-03 23:46 zhuyf87 阅读(14405) 评论(1) 推荐(0)

推导二叉树遍历结果
摘要:已知一棵二叉树的先序遍历序列为:ABCDEF,中序遍历序列为CBAEDF,求后序遍历结果。先序为:ABCDEF,所以A为根结点。又中序为:CBAEDF,所以C、B为A的左子树结点,E、D、F是A的右子树的结点。再看先序:ABCDEF,打印A之后接着打印B,所以B是A的左孩子。再看中序:CBAEDF,C于B之前打印,所以C是B的左孩子。看先序:ABCDEF,结合上图可知D是A的右孩子。再看中序:CBAEDF,所以E是D的左孩子,F是D的右孩子。最终得到的二叉树如下:为避免推导失误,可以检查一遍所得二叉树的先序和中序遍历。最后由所得二叉树得到后序遍历:CBEFDA。二叉树遍历有如下性质:已知先序和 阅读全文

posted @ 2012-11-03 21:54 zhuyf87 阅读(1018) 评论(0) 推荐(0)

线索二叉树
摘要:线索二叉树 (threaded binary tree)上图所示的二叉链表,存在多个空指针域。假设一个二叉链表的结点数为n,则共有2n个指针域。而n个结点的二叉树共有n-1条分支。所以空指针域的个数为:2n - (n-1) = n+1。可以在这n+1个空指针域中保存结点的(以先序、中序或后序遍历的)前驱和后继指针,这样在下次遍历时,可以大大提高速度。将所有空指针域中的rchild指向它的后继。将所有空指针域中的lchild指向它的前驱。线索二叉树(保留遍历时结点在任一串行的前驱和后继的信息):若结点有左子树,则其lchild域指示其左孩子,否则令lchild域指示其前驱;若结点有右子树,则其r 阅读全文

posted @ 2012-11-03 16:04 zhuyf87 阅读(8696) 评论(1) 推荐(1)

二叉树的遍历
摘要:二叉树的遍历(traversing binary tree)是指从根节点触发,按照某种次序依次访问二叉树中的所有结点,使得每个结点都被访问一次且仅被访问一次。1 先(前)序遍历若二叉树为空,则空操作返回;否则(1)访问根节点;(2)先序遍历左子树;(3)先序遍历右子树。void PreOrderTraverse(BiPTree T,void(*Visit)(BiPTree)) { /* 先序递归遍历二叉树T */ if(T) { Visit(T); /* 先访问根结点 */ PreOrderTraverse(T->lchild,Visit); /* 再先序遍历左子树 *... 阅读全文

posted @ 2012-11-03 08:36 zhuyf87 阅读(742) 评论(0) 推荐(0)

二叉树的定义、性质、存储
摘要:二叉树的定义二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。 特殊二叉树1. 斜树所有结点都只有左子树的二叉树叫左斜树,所有结点都只有右子树的二叉树叫右斜树。斜树的每一层都只有一个结点,结点的个数与斜树的深度相同。2. 满二叉树在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子结点都在同一层上,这样的二叉树称为满二叉树。(上图中所示的二叉树... 阅读全文

posted @ 2012-11-01 18:17 zhuyf87 阅读(15373) 评论(0) 推荐(1)

稀疏矩阵的十字链表存储
摘要:稀疏矩阵的压缩存储有几种方式,如:三元组顺序表、行逻辑链接的顺序表和十字链表。使用链表存储的好处是:便于矩阵中元素的插入和删除。例如:“将矩阵B加到矩阵A上”,那么矩阵A存储的元素就会有变动。比如会增加一些非零元,或者删除一些元素(因为bij+aij=0)。下图是矩阵M和M的十字链表存储:十字链表及其结点可用如下结构体表示:typedef struct OLNode{ int i, j; // 非零元的行列下标 ElemType e; struct OLNode *right, *down; // 向右域和向下域} OLNode, *OLink;typedef struct{... 阅读全文

posted @ 2012-10-22 11:32 zhuyf87 阅读(5957) 评论(1) 推荐(1)

导航