数据结构简单分析

1.数据的存储结构
  1. 顺序存储结构:借助元素在存储器中的相对位置来表示数据元素之间的逻辑关系,可用一位数据描述。
  2. 链式存储结构:借助指示元素存储地址的指针来表示数据源是之间的逻辑关系。可用指针描述,数据元素不一定存在地址的存储单元,存储处理的灵活性较大。
  3. 索引存储:是在原有存储数据结构的基础上,附加建立一个索引表,索引表中的每一项都由关键字和地址组成。采用索引存储的主要作用是为了提高数据的检索速度。
  4. 散列存储:是通过构造散列函数来确定数据存储地址或查找地址的。

2.算法效率

1、  时间复杂度(Time Complexity) 
        一般情况下,算法中的基本操作重复执行次数是问题规模n的某个函数 f(n) ,算法的时间度量记作:
                T(n) = O(f(n))
        它表示随问题规模n的增大,算法执行时间的增长率和 f(n) 的增长率相同,称做算法的逐渐时间复杂度,简称时间复杂度。
      
        在下列的三个程序中 
        (a)  x=0   
        (b)  for (i=1;i<=n;i++) x=x+1  
        (c)  for (i=1;i<=n;i++)          
                for(j=1;j<=n;j++) X=X+i*j

        上述三个语句的频度分别为 1,n, n^2


2.空间复杂度(Space ComPlexity)
   
        一个程序的空间复杂度是指程序运行从开始到结束所需要的存储空间。包括算法本身所占用的存储空间、输入数据占用的存储空间以及算法在运    行过程中的工作单元和实现算法所需辅助空间。

3.链表
1.线性链表或单链表
    线性表的链式存储结构是用一组地址任意的存储单元存放线性表中的数据元素。
    为了表示每个数据元素ai与其直接后继数据元素ai+1之间的逻辑关系,对数据元素ai来说,除了存储其本身的值之外,还必须有一个指示该元素直接后继存储位置的信息,即指出后继元素的存储位置。
    这两部分信息组成数据元素ai的存储映像,称为结点(node)。每个结点包括两个域:一个域存储数据元素信息,称为 数据域;另一个存储直接后继存储位置的域称为 指针域。指针域中存储的信息称做指针或链。N个结点链结成一个链表,由于此链表的每一个结点中包含一个指针域,故又称线性链表或单链表。

2.线性表的单链表存储结构
a)非空表
1.H是一个指向LNode类型的指针变量,称为头指针。
2.第一个结点(a1)之前还附设一个结点,称之为头结点,头结点的数据域可以不存储任何信息,也可存储如线性表的长度等附加信息,单链表的头指针指向头结点,头结点的指针域指向第一个结点的指针。
3.最后一个结点没有后继结点,它的指针域为空,用“∧”表示。

b)空表
    
3.双向链表


4.数组
数组在计算机内是用一批 连续的存储单元来表示的,称为数组的顺序存储结构。

1.稀疏矩阵
是指矩阵中大多数元素为零的矩阵。一般的,当非零元的个数占元素总数的比例低于20%时,称这样的矩阵为稀疏矩阵。

顺序结构:其中每一个非零元素所在的行号、列号和值组成一个三元组 (i,j,aij)


5.广义表
广义表是线性表的推广,也称为列表(List)。
广义表的深度是指该广义表展开后所含括号的层数。
由于广义表的元素类型不一定相同,因此,很难用顺序结构存储表中元素,通常采用链存储方法来存储广义表中元素,并称之为广义链表。

1.广义表中有两类结点:一类是原子结点,另一类是子表结点。为了将两者统一,用了一个标志tag,当其为0时,表示是原子结点,其data域存储结点值,link域指向下一个结点;当其tag为1时表示是子表结点,其sublist为指向子表的指针:

2.广义表有两种类型的存储结构,第一种是将广义表分为表头和表尾存储,第二种是在同层存储所有的兄弟。




6.栈
限定仅在表尾进行插入或删除操作的线性表。
表尾具有特殊的含义,是允许插入和删除的一端,称为栈顶(Top),表头端为固定的一端,称为栈底(Bottom)。
栈是一种后进先出(Last In First Out)的线性表,简称为LIFO表。

栈的顺序存储结构简称为顺序栈,它类似于线性表的顺序存储结构,是利用一批 地址连续的存储单元依次存放自栈底到栈顶的数据元素,同时设一栈顶指针top指向栈顶元素的下一个位置。

1.链栈
用链式存储结构实现的栈称为链栈。链栈的结点结构与单链表的结点结构相同,通常就用单链表来表示。

2.算术表达式的求值
a)中缀表达式:
    1)10/5+8 
    2)28-9*(4+3)
b)后缀表达式:
    1)10 5 / 8 + 
    2)28 9 4 3 + * -
中缀表达式变成等价的后缀表达式的算法:
    设立一个栈,存放运算符,首先栈为空,编译程序从左到右扫描中缀表达式,若遇到操作数,直接输出,并输出一个空格作为两个操作数的分隔符;若遇到运算符,则必须与栈顶比较,运算符级别比栈顶级别高则进栈,否则退出栈顶元素并输出,然后输出一个空格作分隔符;若遇到左括号,进栈;若遇到右括号,则一直退栈输出,直到退到左括号止。当栈变成空时,输出的结果即为后缀表达式。

例:(2+1)*((8-2)/(7-4))变成等价的后缀表达式
步骤
栈中元素
输出结果
主要操作
1
(
 
( 进栈
2
(
2
输出 2
3
(+
2
+ 进栈  
4
(+
2 1
输出 1
5
 
2 1 +
+ 退栈输出,退栈到 (
6
*
2 1 +
* 进栈
7
* (
2 1 +
( 进栈
8
* ((
2 1 +
( 进栈
9
* ((
2 1 + 8
输出 8
10
* ((
2 1 + 8
进栈
11
* ((-
2 1 + 8 2
输出 2
12
* (
2 1 + 8 2 -
- 退栈输出,退栈到 (
13
* (/
2 1 + 8 2 -
进栈
14
* (/(
2 1 + 8 2 -
进栈
15
* (/(
2 1 + 8 2 - 7
输出
16
* (/(-
2 1 + 8 2 - 7
- 进栈
17
* (/(-
2 1 + 8 2 - 7 4
输出 4
18
* (-
2 1 + 8 2 - 7 4 -
- 退栈输出,退栈到 (
19
*
2 1 + 8 2 - 7 4 - /
/ 退栈输出,退栈到 (
20
 
2 1 + 8 2 - 7 4 - / *
* 退栈并输出


7. 队列
只允许在表的一端进行插入,而在另一端进行删除的运算受限的线性表。
所有的插入均限定在表的一端进行,该端称为 队尾(Rear);所有的删除则限定在表的另一端进行,该端则称为 队头(Front)
先进先出(First In First Out,简称FIFO)


1.顺序队列
     队列的顺序存储结构称为顺序队列,顺序队列实际上是运算受限的顺序表,和顺序表一样,顺序队列也是必须用一个数组来存放当前队列中的元素。
易造成“假溢出”,要克服“假溢出”,会引起大量元素的移动,花费大量的时间,所以在实际应用中很少采用,一般采用下面的循环队列形式。

2.循环队列


3.链队列
在队列中,用线性链表表示的队列称为链队列。




8.树
树(Tree)是n(n≥0)个结点的有限集合。
(1)有且仅有一个特定的称为根(Root)的结点;
(2)当n>1时,其余结点分成m(m>0)个互不相交的有限集T1,T2,...,Tm,其中每一个集合本身又是一棵树,并且称为根的子树。

树的基本术语
  1. 树的结点 
    1. 数据元素的内容及其指向其子树的分支统称为结点。
  2. 结点的度  
    1. 在树中,结点拥有的子树的个数称为结点的度。例如,在图(b)中,结点A,B,C的度分别为2,2,3。
  3. 树的度 
    1. 树的度是树内各结点的度的最大值。例如,在图(b)中,树的度为3。
  4. 叶子或终端结点  度为0的结点称为叶子或终端结点。例如,在图(b)中,结点E,F,G,H,M,均为叶子。
  5. 非终端结点或分支结点  
    1. 度不为0的结点称为非终端结点或分支结点。除根结点之外,分支结点也称为内部结点。
  6. 孩子、双亲、兄弟、祖先、子孙 
    1. 结点的子树的根称为该结点的孩子,相应地,该结点称为孩子的双亲。同一个双亲的孩子之间互称兄弟。
    2. 结点的祖先是从根到该结点所经分支上的所有结点。以某结点为根的子树中的任一结点都称为该结点的子孙。
    3. 例如,在图(a)中,B,C互为兄弟,它们都是A的孩子,而A是它们的双亲,M结点的祖先是A,B,D,B的子孙为D,M,E。
  7. 结点的层次
    1. 结点的层次,从根开始定义起,根为第一层,根的孩子为第二层。其余结点的层次值为双亲结点层次值加1,若某结点在第i层,则其子树的根就在第i+1层。其双亲在同一层的结点互为堂兄弟。例如,在图(b)中,A,B,D,M的层次值分别为1,2,3,4。
  8. 树的深度
    1. 树中结点的最大层次称为树的深度或高度。图(b)所示的树的深度为4
  9. 有序树和无序树
  10. 森林
    1. 森林是m(m≥0)棵互不相交的树的集合。对树中每个结点而言,其子树的集合即为森林。由此,也可以用森林和树相互递归的定义来描述树。    
    2. 就逻辑结构而言,任何一棵树是一个二元组 Tree=(root, F),其中,root是数据元素,称作树的根结点;F是m(m≥0)棵树的森林,F=(T1,T2,…,Tm),其中Ti=(ri,Fi),称作根root的第i棵子树;当m≠0时,在树根和子树森林之间存在下列关系:          RF={<root,ri>| i=1,2,..., m,m>0}   
    3.  对树而言,删去其根结点,就得到一个森林。对森林而言,加上一个结点作为根,就变为一棵树。    
    4. 树形结构的逻辑特征可以描述如下:树中的任一结点都可以有0个或多个后继(即孩子)结点,但至多只能有一个前驱(即双亲)结点。树中只有根结点无前驱,叶结点无后继。

1.二叉树
二叉树是由n(n≥0)个结点的有限集合。
(1)当n=0时,称为空二叉树; 
(2)当n>0时,有且仅有一个结点为二叉树的根,其余结点被分成两个互不相交的子集,一个作为左子集,另一个作为右子集,每个子集又是一个二叉树。
    它的特点是每个结点至多只有二棵子树(即二叉树中不存在度大于2的结点),并且,二叉树的子树有左右之分,其次序不能任意颠倒,即若将其左、右子树颠倒,就成为另外一棵不同的二叉树。即使树中结点只有一棵子树,也要区分它是左子树还是右子树。因此二叉树具有五种基本形态,如下图所示。
(a)空二叉树;
(b)仅有根结点的二叉树;
(c)右子树为空的二叉树;
(d)左子树为空的二叉树;
(e)左、右子树均非空的二叉树。

2.满二叉树
    1.在一棵二叉树中,如果所有分支结点都同时具有左孩子和右孩子,并且所有叶子结点都在同一层上,即如果一棵深度为k并且含有2k-1个结点的            二叉树称为满二叉树。
    2.这种树的特点是每层上的结点数是最大的结点数。
    

3.完全二叉树
特点是:叶子结点只能出现在最下层和次下层, 且最下层的叶子结点集中在树的左部。显然,一棵满二叉树必定是一棵完全二叉树,而完全二叉树未必是满二叉树。
在满二叉树的最下面的一层上,从最右边开始连续删去若干结点后得到的二叉树仍然是一棵完全二叉树 。

4.二叉树的性质
1.性质1 非空二叉树的第i(i≥1)层上至多有2i-1个结点。
2.性质2 一棵深度为k的二叉树中,最多具有2^k-1个结点。

3.性质3 对任意非空的二叉树,如果叶子结点数为n0,度为1的结点数为n1,度数为2的结点数为n2,则n0=n2+1。
        证明  设n为二叉树的结点总数,则有:          
                         n=n0+n1+n2                               (1)   
                在二叉树中,除根结点外,其余结点都有惟一的一个分支 (连线)进入。设B为二叉树中的分支总数,则有:          
                         B=n-1                                    (2)   
                这些分支是由度为1和度为2的结点发出的,一个度为1的结点发出一个分支,一个度为2的结点发出两个分支,则有:          
                         B=n1+2n2                                (3)  
                综合(1)、(2)、(3)式可以得到:                  n0=n2+1
4.性质4  具有n个结点的完全二叉树的深度为k; k-1≤log2n<k =>  [log2n] +1。
5.性质5  对于具有n个结点的完全二叉树,如果按照从上至下和从左到右的顺序对二叉树中的所有结点从1开始顺序编号,则对于任意的序号为i(1≤i≤n)的结点,有: 
(1)如果i=1,则序号为i的结点是根结点,无双亲结点。  
(2)如果i>1,则序号为i的结点的双亲结点的序号为[ i/2 ]。   
(3)如果2i≤n,则序号为i的结点的左孩子结点的序号为2i;否则序号为i的结点无左孩子(该结点i为叶结点)。   
(4)如果2i+1≤n,则序号为i的结点的右孩子结点的序号为2i+1;否则序号为i的结点无右孩子。

5.二叉树的存储结构
二叉树可以采用顺序存储结构和链式存储结构。
链式存储结构:由于用顺序方式存储一般二叉树将浪费存储空间,并且若在树中需要经常插入和删除结点时,要大量地移动结点,因此,一般二叉树较少采用顺序存储方式。
(1)二叉链表存储
    二叉链表中每个结点由一个数据域,两个指针域组成,一个指针指向左孩子,另一个指向右孩子。结点的存储结构为

data域存放某结点的数据信息,lchild与rchild分别存放左孩子和右孩子的指针,当左孩子或右孩子不存在时,相应指针域值为空(用符号∧或NULL表示)。
(2)三叉链表存储:(上图C)
    在实际操作中,如果需要在二叉树中寻找某结点的双亲时,可在每个结点中再加上一个指向其双亲的指针域,形成一个三叉链表。
    三叉链表存储结构相对于二叉链表存储结构而言,它增加了空间开销,尽管在二叉链表中无法由结点直接找到其双亲,但由于二叉链表结构灵活,操作方便,对于一般的二叉树,甚至比顺序存储结构还节省空间。因此,二叉链表是最常用的二叉树存储方式。

6.二叉树的遍历
 1.由二叉树的定义可知,一棵二叉树由根结点、根结点的左子树和根结点的右子树三部分组成。因此,只要依次遍历这三部分,就可以遍历整个二叉树。
    2.若以D、L、R分别表示访问根结点、遍历根结点的左子树、遍历根结点的右子树,则二叉树的遍历方式有六种:DLR、LDR、LRD、DRL、RDL和RLD。
    3.如果限定先左后右,再把访问根结点穿插其中,则只有三种不同的遍历方式,即DLR(称为先序遍历)、LDR(称为中序遍历)和LRD(称为后序遍历)。

7.哈夫曼(Huffman)树,又称最优二叉树,在实际问题中有着广泛的应用 .
1.路径和路径长度   
        若树中存在一个结点序列k1,k2,…,kj,使得ki是ki+1的双亲(l≤i<j=,则称该结点序列是从k1到kj的一条路径(Path)。因树中每个结点只有一个双亲结点,所以它也是这两个结点之间的惟一路径。从k1到kj所经过的分支数称为这两点之间的路径长度,它等于路径上的结点数减1。

2.树的路径长度:从根结点到每一个结点的路径长度之和。

3.结点的权 
    在许多应用中,常常将树中的结点赋予一个有某种意义的实数,称为该结点的权。

4. 结点的带权路径长度。是该结点到树根结点之间的路径长度与该结点上权的乘积。

5.树的带权路径长度    
    树的带权路径长度定义为树中所有叶子结点的带权路径长度之和,通常记为:其中n表示叶子结点的数目,wi和li分别表示叶结点ki的权值和根结点到叶结点ki之间的路径长度。

6.哈夫曼树   
在权为w1,w2,…,wn的n个叶子结点的所有二叉树中,带权路径长度WPL最小的二叉树称为最优二叉树或哈夫曼树。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值