二叉树是n(n>=0) 个节点的有限集合 或者是空集(n=0)
由一个根节点以及两颗互不相交、分别称为左子树和右子树的二叉树组成
二叉树的性质
二叉树第 i (i>=1) 层上的节点最多为 个
深度为 k(k>=1)的二叉树最多有 个节点
满二叉树:深度为 k(k>=1)时有 个节点
完全二叉树:只有最下层有度数小于2的节点,且最下层的叶节点集中在最左边的若干位置上
具有n个节点的完全二叉树的深度为
或者
顺序存储二叉树
顺序存储结构:完全二叉树节点的编号从上到下,从左到右。根为1号节点,设完全二叉树的节点数为n,其节点编号为i。
当 i>1 时,是有父节点的,其父节点编号为 i/2;
当 2*i <= n时,是有左孩子,其编号为2*i,否则没有左孩子,本身就是叶节点。
当 2*i +1 <= n时,是有右孩子,其编号为2*i+1,否则没有右孩子,本身就是叶节点。
当 i 为奇数且不为1时,有左兄弟,其编号为 i-1;
当 i 为偶数且小于n时,有有兄弟,
如何实现顺序存储二叉树(不适用于非完全二叉树)
有n个节点的完全二叉树可以用n+1个元素的数组进行顺序存储,节点号和下标号一一对应,下标为0的元素不使用。
链式存储二叉树
链式存储二叉树适用于非完全二叉树的,既如下图左所示:
如上图右所示,采用链式存储二叉树时,其节点结构由 3 部分构成
- 指向左孩子节点的指针(Lchild);
- 节点存储的数据(data);
- 指向右孩子节点的指针(Rchild);
表示该节点结构的 C 语言代码为:
typedef struct BiTNode{
TElemType data;//数据域
struct BiTNode *lchild,*rchild;//左右孩子指针
struct BiTNode *parent;
}BiTNode,*BiTree;
二叉树的遍历
遍历:沿某条搜索路径周游二叉树,对树中的每一个节点访问一次且只访问一次。
由于二叉树的递归特性,遍历算法也是递归的,三种基本得遍历算法如下:
- 先访问树根,在访问左子树,最后访问右子树 先序遍历(根左右)
- 先访问左子树,在访问树根,最后访问右子树 中序遍历(左根右)
- 先访问左子树,在访问右子树,最后访问树根 后序遍历(左右根)
查找
设记录表L=(R1,R2.....),其中Ri为记录,对给定的某个值K,在表中确定key=K的记录过程,称为查找。若在表中查找到存在的K,则查找成功,返回该记录在表中的位置,否则查找失败返回0。(简单的来说就是当在一个表中查找到所需要的值时,其返回查找到的地址,否则返回0)
查找算法分为:
1、顺序查找 2、折半查找 3、分块查找 4、Hash表查找
查找算法的优势是会影响到计算机的处理效率问题
顺序查找:
既一个一个往后面找,从最开始进行查找查找到最后一个,如果查找到了就返回。对于顺序查找其时间复杂度是比较大的。
折半查找:
对给定值一个区间,每次对剩下的空间进行择半。所以每次所查找都是剩下的一般,如果查找到了就停止。相当于是设两个游标low、high,分别指向所查表的表头与表尾,然后每次用mid来指向中间元素。其原理就是二叉树一样,一半一半的查找。
分块查找:
即将记录表分为N个块,相当于是一个区间一个区间的,相当于是一个数组,每个块都是一个头地址,然后一个一个遍历每个数组,然后查找到内容。
前三种方法都是通过比较的方法来进行查找的,而下面的哈希表则是不经过比较进行查找的。
哈希表
在建立记录表的时候,确定记录的key与其存储地址之间的关系,即使key与记录的存放地址相对应。当要查找记录时,则通过关系就可以得到相应记录的地址从而获取记录。
而这个所谓的关系就是Hash函数(或称散列函数、杂凑函数)
不同的key值可能得到同一个Hash地址,该现象则为“冲突”或者“碰撞”。此时则需要减少冲突或解决冲突
这里等后面用到了,在进行深入学习。
排序
排序分为内排序和外排序(一般内排序较多)
内排序:排序文件在计算机的内存储器中,且排序过程也在内存中进行
外排序:排序文件存入外存储器,排序过程借助内外存数据交换来完成
内排序又分很多种
1、插入排序 2、交换排序 3、选择排序 4、归并排序
插入排序(举例)
1、直接插入排序 2、折半插入排序 3、链表插入排序 4、希尔排序
交换排序
1、“起泡”排序(冒泡法) 2、“快速”排序
快速排序
相当于是将一个数据为基准点,然后比基准点小的放到左边,大的放到右边也相当是折半差不多反过来的结构。