平衡二叉树笔记

1.二叉树有几种存储方式,啥样的二叉树适合使用数组来存储?

显然只有数组和链表两种方式,数组更适合于完全二叉树,最典型的应用就是大小顶堆的使用,使用数组我们我们可以为一组数在O(n)的时间内完成对一组数据的建堆操作。记住二叉树的递归遍历前中后序时间复杂度皆为O(n).

2.既然有散列表(hash)为什么设计二叉树

普通二叉查找树(排序树)不是太稳定,最差会达到O(N)而最好时大约为O(logN),这显然不符合我们在工程上的需求,故前辈们提出了性能稳定的平衡二叉树,而其中又以红黑树的使用最为广泛,现在再来看hash与avl应该怎样选择,为何avl更受欢迎?

  • 散列表无序存储,假设要有序数据时必须先排序。
  • hash表阔容耗时多,而且当遇到散列冲突时,性能不稳,查找树则不同。
  • 解决冲突及其耗时,虽然单个查找时间复杂度为O(1),但是实际查找速度不一定有查找树快
  • 散列表构造需要考虑太多因素,比如设计散列函数、冲突解决办法等。
  • 若解决冲突方法不够合理,装填因子太大,会浪费太多空间
3.为什么要使用红黑树?avl不香吗?

平衡二叉树是为了解决二叉查找树在频繁的动态更新中可能出现树的高度远远大于logN的情况,从而导致各个操作的效率下降。而为了解决这个问题,提出了平衡二叉树,其中最具有代表性的就是红黑树,其实最早出现的是avl树,不过尽管avl树是一种高度平衡的二叉树,查找的效率非常高,但是有利就有弊,它为了维护这种高度的平衡就付出了更多的代价。每次插入删除都要做调整,就比较复杂耗时,所以对于频繁的插入删除的数据集合,使用avl树的代价有点高。而红黑树只是大概做到了近似平衡,并不是严格的平衡,所以在维护平衡的成本上,要比avl树低。
红黑树的近似平衡体现在它从根节点到各个叶子节点的最长路径,有可能会比最短路径大一倍。

4.红黑树的定义
  • 根节点是黑色的
  • 每个叶子节点都是黑色的空节点,也就是说叶子节点不存储数据
  • 任何相邻的节点不能都是红节点,即红节点被黑色节点隔开
  • 每个节点到达其可达叶子节点的所有路径都包含相同数目的黑色节点
5.怎样实现一棵红黑树?

显然当我们对红黑树进行插入和删除时势必会造成不满足上面关于红黑树定义3、4点的要求,而如何建树以及调整数是构成一颗二叉树的基础。

  • 红黑树规定,插入的节点必须是红色的。而且,二叉查找树中新插入的节点都是放在叶子节点上
  • 至于红黑树的叶子节点为什么设置为黑色的空节点自然是为了编程实现的简便性,只有这样才可以将插入和删除做成一个套路,不要强记,没意义。了解节点的左右旋转。
6.跳表

调表是一种各方面性能都比较优秀的动态数据结构,它基于链表实现,通过添加多级索引的方式设计,每一级索引以下一级的两个或者更多节点为间隔提取为一个节点设计索引层,层层递进,效率将非常高。

  • 仔细分析跳表的数据结构会发现它的时间复杂度为O(logN),和二分查找的时间复杂度相等。
  • 跳表以空间换时间,那么其是不是真的浪费内存哩?
  • 虽然空间复杂度为O(N)的,但是在实际的软件开发中每一个节点其实保存的是非常复杂的结构,而索引只是一个指针,所以完全不需要担心浪费内存的问题。
  • 跳表这个动态数据结构,不仅支持查找操作,还支持动态的插入、删除操作,而且插入、删除操作的时间复杂度也是 O(logn)。
  • 当不停地往跳表中插入数据时,如果不更新索引,就有可能出现某 2 个索引结点之间数据非常多的情况。极端情况下,跳表还会退化成单链表。所以需要某种手段来维护索引与原始链表大小之间的平衡,也就是说,如果链表中结点多了,索引结点就相应地增加一些,避免复杂度退化,以及查找、插入、删除操作性能下降。如何做哩?
  • 跳表是通过随机函数来维护前面提到的“平衡性”。
7.Linux常用命令

(1) grep: global search regular expression(RE) and print out the line
示例:grep "skip_atoi(" vsprintf.c

-E 将范本样式为延伸的普通表示法来使用,意味着使用能使用扩展正则表达式。
-i 忽略字符大小写的差别。
-R/-r 此参数的效果和指定“-d recurse”参数相同。
-v 反转查找。
-o 只输出文件中匹配到的部分。

(2)find: 用来在指定目录下查找文件
syntax:find(选项)(参数)
任何位于参数之前的字符串都将被视为欲查找的目录名。如果使用该命令时,不设置任何参数,则find命令将在当前目录下查找子目录与文件。并且将查找到的子目录和文件全部进行显示。

-name<范本样式>:指定字符串作为寻找文件或目录的范本样式;
-iname<范本样式>:此参数的效果和指定“-name”参数类似,但忽略字符大小写的差别;
-ls:假设find指令的回传值为Ture,就将文件或目录名称列出到标准输出;
-path<范本样式>:指定字符串作为寻找目录的范本样式;
-regex<范本样式>:指定字符串作为寻找文件或目录的范本样式;

find .  #列出当前目录及子目录下所有文件和文件夹
find /home -name "*.txt"    #在/home目录下查找以.txt结尾的文件名
find /home -iname "*.txt"   #同上,但忽略大小写
find . \( -name "*.txt" -o -name "*.pdf" \)#当前目录及子目录下查找所有以.txt和.pdf结尾的文件
find /usr/ -path "*local*"  #匹配文件路径或者文件
find . -regex ".*\(\.txt\|\.pdf\)$"#基于正则表达式匹配文件路径
find /home ! -name "*.txt"  #找出/home下不是以.txt结尾的文件
find . -type 类型参数   #根据文件类型进行搜索

(3)xargs: 给其他命令传递参数的一个过滤器
是给其他命令传递参数的一个过滤器,也是组合多个命令的一个工具。它擅长将标准输入数据转换成命令行参数,xargs能够处理管道或者stdin并将其转换成特定命令的命令参数。xargs也可以将单行或多行文本输入转换为其他格式,例如多行变单行,单行变多行。

#假设有文件cat test.txt
a b c d e f g
h i j k l m n
o p q
r s t
u v w x y z
1、cat test.txt | xargs    #多行输入单行输出
输出:a b c d e f g h i j k l m n o p q r s t u v w x y z
2、cat test.txt | xargs -n3#-n选项多行输出如下
输出:a b c
    d e f
    g h i
    j k l
    m n o
    p q r
    s t u
    v w x
    y z
3、echo "nameXnameXnameXname" | xargs -dX   #-d选项可以自定义一个定界符
输出:name name name name
4、echo "nameXnameXnameXname" | xargs -dX -n2   #结合-n选项使用
输出:  name name
        name name
5、cat test.txt |xargs -I {} echo "-p {} -l" #读取stdin,将格式化后的参数传递给命令
输出:  -p b c d e f g -l
        -p h i j k l m n -l
        -p o p q -l
        -p r s t -l
        -p u v w x y z -l
6、find . -type f -name "*.log" -print0 | xargs -0 rm -f    #xargs结合find使用
    #用rm 删除太多的文件时候,可能得到一个错误信息:/bin/rm Argument list too long.
    #用xargs去避免这个问题
7、find . -type f -name "*.php" -print0 | xargs -0 wc -l
    #统计一个源代码目录中所有php文件的行数
    #xargs -0将\0作为定界符。

(4)tar: 为linux的文件和目录创建档案
利用tar命令,可以把一大堆的文件和目录全部打包成一个文件,这对于备份文件或将几个文件组合成为一个文件以便于网络传输是非常有用的。注意区分打包和压缩,打包是指将一大堆文件或目录变成一个总的文件;压缩则是将一个大的文件通过一些压缩算法变成一个小文件。区分这两个概念源于Linux中很多压缩程序只能针对一个文件进行压缩,这样当你想要压缩一大堆文件时,你得先将这一大堆文件先打成一个包(tar命令),然后再用压缩程序进行压缩(gzip bzip2命令)。
syntax:tar(选项)(参数)

-c或–create:建立新的备份文件;
-x或–extract或–get:从备份文件中还原文件;
-v:显示操作过程;
-f<备份文件>或–file=<备份文件>:指定备份文件;
-j:支持bzip2解压文件;
-z或–gzip或–ungzip:通过gzip指令处理备份文件;
-t或–list:列出备份文件的内容;

示例程序:

tar -cvf log.tar log2012.log        #仅打包,不压缩! 
tar -zcvf log.tar.gz log2012.log    #打包后,以 gzip 压缩 
tar -jcvf log.tar.bz2 log2012.log   #打包后,以 bzip2 压缩 
tar -ztvf log.tar.gz                #查阅上述tar包内有哪些文件
tar -zxvf /opt/soft/test/log.tar.gz #将tar包解压缩

想要最简单的使用tar只需要记得下面的几个公式就可以了 :
压 缩:tar -jcv -f filename.tar.bz2 要被压缩的文件或目录名称
查 询:tar -jtv -f filename.tar.bz2
解压缩:tar -jxv -f filename.tar.bz2 -C 欲解压缩的目录

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值