大话数据结构小结1

来源:互联网 发布:mac 无线网络攻击 编辑:程序博客网 时间:2024/05/21 22:45
由于图片看不了,大家可以看这个百度云笔记,我看完大话数据结构整理的,里面有些内容我还不太明白,等过段时间还需要仔细回顾回顾。点击打开链接

一.数据及数据结构的基本概念
  1. 数据结构是一门研究非数值计算的程序设计问题中的操作对象,以及他们之间的关系和操作等相关问题的学科。

  1. 数据:符号集合
  2. 数据元素:组成数据有一定意义的基本单位,也被称作记录。
  3. 数据项:一个数据元素可以由多个数据项组成,是数据不可分割的最小单位。
  4. 数据对象:是性质相同的数据元素的集合,是数据的子集。

2.数据结构:数据元素的特定关系。
  1. 逻辑结构:数据元素之间的相关关系
            集合关系:同属一个集合,没有其他关系
            线性结构:数据元素之间是一对一的关系
     2.物理结构:数据的逻辑结构在计算机中的存储形式

3.数据类型:是指一组性质相同的值的集合,以及此集合上的一些操作。
        原子类型:不可以分割的基本类型:整形。。。
        结构类型:若干个类型组合,可以分割,比如:数组

二、算法
指令的有限序列,每条指令表示一个或多个操作。
1.算法的基本特性:
        输入、输出、有穷性、确定性、可行性
2.算法的设计要求:
        正确性、可读性、健壮性、高效率和低存储量

事后统计方法(不科学,不精确)
3.事前估算方法:时间复杂度,用O()表示——大O记法
                            空间复杂度(用空间来换取时间,一般不怎么用)
O(1):常数阶;O(n):线性阶;O(n2):平方阶

三、线性表
线性表(List):零个或多个数据元素的有限序列。

1.顺序存储结构:一段地址连续存储空间
        数组的长度和线性表的长度区别:数组长度是存放线性表的存储空间的长度,固定的;线性表的长度是线性表中数据元素的个数,随插入删除,长度改变。
    
        存取是O(1):知道地址马上可以取到
        插入、删除:O(n):一个个比较

注:写代码时要注意:程序的健壮性,插入地址适不适合,

2.链式存储结构
一个节点:
                数据域
                指针域

链表的第一个节点的存储位置叫头指针;链表的最后一个节点指针为"NULL";
注:在单链表的第一个节点前附设一个节点,——头结点;


  • 读取:不知道第i个节点在哪,需要从头开始遍历
  • 插入和删除:

都是由两部分组成:1.遍历查找第i个节点;2.插入和删除节点

3.静态链表
用数组描述的链表(为了不使用指针)
数组中每个元素都有两个值,一个代表数据,一个代表游标(相当于指针)——不一定用,但是思想比较巧、

注意游标

4.循环链表
将单链表中的终端节点的只诊断由空指针改为指向头结点
  • 注:循环链表和单链表的区别:在于循环的判断条件上,原来是判断p->next是否为空,现在是p->next是否等于投节点(头结点是那个没有数据的节点)
  • 将两个循环链表合并,需要删掉一个头结点

5.双向链表——用空间来换时间
一个节点包括:
                    数据部分;
                    指向前驱节点的指针;
                    指向后继节点的指针。
注:在插入和删除的时候需要改变两个指针变量

顺序:先搞定s的前驱和后继,再搞定后节点的前驱,最后前节点的后继

顺序:顺时针
            free(p);

四、栈与队列
1.栈——后进先出(Last In First Out)的线性表(LIFO结构)
存一个元素的时候,top为0,所以空栈的时候top为-1,用-1来判断栈是否为空。
  • 两个栈可以共享空间:数据类型要一样
栈1为空时,top=-1;栈2为空时,top=n;
栈1为满时,top=n-1;栈2为满时,top=0;
当在中间栈1和栈2相遇时,top1+1=top2;

栈的链式结构,不需要有节点,应用在递归上(处理器内部自身会进行的):四则运算表达式P105

2.迭代和递归的区别:
迭代:循环结构,不需要反复调用函数和占用额外的内存;
递归:选择结构,使程序结构清晰简洁,但是大量的递归调用会建立函数的副本,会消耗 大量的时间和内存。

3.队列
  • 队列:数据块、头指针、尾指针
  • 循环队列(顺序队列):
                        解决出对一个数据,需要把所有数据往前移一位,浪费时间的问题,从O(n)->O(1)
                    当front=rear时就不能判断是空队列还是满队列,所以需要外加1.一个标示flag,flag=0,队列为空;flag=1,队列为满。方法二:队列满时,仍然保留一个空位。
        对第二种情况:对满的条件是:(rear+1)%QueueSize==front——会从尾部出来,再从头部进去。
                                计算队列长度:(rear-front+QueueSizde)%QueueSize

                注:在进行入队或出对的情况下也要考虑%QueueSize
                        Q->rear=(Q->rear+1)%MAXSIZE;
  • 链式存储的队列,需要有头结点
                    注:在出对的情况下,就是头结点的后继节点出对,将头结点的next改为出对节点的后继节点;
                            但是若链表除头结点外只剩一个元素,则需要将rear指向头节点

                    从a1里面正式放数据元素。

  • 循环队列是事先申请好空间的,使用期间不释放;而链队列可以申请和释放空间,但需要消耗一点时间。建议:在可以确定队列长队最大值的情况下,使用循环;无法确定,使用链队列。

五、串(????匹配算法不明白
串的存储结构也有顺序存储和链式存储,在链式存储中一个节点对应一个字符,会造成很大的浪费,所以会考虑放多个字符,未被占满时,用非串值字符补全。但串的链式存储除了在连接串与串操作时有一定的方便之外,总的来说不如顺序存储灵活,性能也不好。

1.KMP模式匹配算法
避免重复遍历的情况,需要计算一个子串next数组

其中MAX的计算,从头开始,尾部对应相应的几个,但是不包括第j位

注:字符不相等是将j=next[j];回溯
        KMP算法仅当模式与主串之间存在许多“部分匹配”的情况下才体现出优势,否则和不同的区别不大。

2.改进的KMP模式匹配算法

六、树
  1. 节点拥有的子树称为节点的度。度=0,是叶节点或终端节点。
            树的度是树内各节点的度的最大值。
    2.节点的层次是从根开始定义的,根为第一层。
            树的深度或高度:树中节点的最大层次
      3.森林是m课互不相交的树的集合。

  1. 双亲表示法
->长子域
                                                              或兄弟域
根据自己的需求可以灵活变动,看需要那么地址。

      2.孩子表示法:多重链表
 每个节点有多个指针域,每个指针域指向一棵子树的根节点
->
专门取一个位置来存储节点指针域的个数,但是这时间上额损耗大。
将双亲表示法和孩子表示法综合的:
                               

    3.孩子兄弟表示法:把一棵复杂的树变成了一棵二叉树

    4.二叉树:
  • 二叉树的特点:树中某个节点只有一棵子树,需要区分是左子树还是右子树(树是不用区分的
                特殊的二叉树:斜树(只有左子树或只有右子树);满二叉树(每个节点都有左子树和右子树,完全对称);完全二叉树(节点的孩子可以只有一个,但是必须是连续的,一层层数)

  • 二叉树的性质
            
            
            性质3:对任何一棵二叉树,如果其终端节点数为n0,度为2的节点数为n2,则n0=n2+1。
    
            性质5:I.如果i=1,则节点i是二叉树的根,无双亲;如果i>1,则其双亲是节点[i/2];
                        II.如果2i=n,节点i有左子树,如果2i>n,则节点没有左子树;
                        III.如果2i+1=n,节点i有右子树,如果2i+1=n,则没有。
  • 二叉树的存储结构
            顺序存储,用以为数组,同时利用角标。
            链表:数据域,指针域,
  • 二叉树的遍历方式:都是根据根节点来判断的。
            前序遍历:先访问根节点;中序遍历:先左再根节点,最后右;后序遍历:先左再右,最后根节点;层序遍历:一层一层访问。

    为什么需要这么多形式的遍历:因为计算机只有循环、判断等方式,所以需要通过遍历方式把树中的节点变成有意义的线性序列。
  • 算法

只改变打印数据的位置。

得到唯一的二叉树:都需要中序遍历序列,前序和后序需要一个即可。

  • 线索二叉树

节点有左子树或右子树,那么lchild,rchild里面存放孩子的地址;如果没有孩子,则lchild,rchild存放的是要跳转的地址(即前驱或后继的地址,这两个地址称为线索);通过ltag,rtag来区分是什么地址(0,1标志的内存空间比地址空间小,所以用他们来做标识符)

线索二叉树就是把一个二叉树变成了一个双向链表。线索化的实质:将二叉链表中的空指针改为指向前驱或后继的线索。
这个程序不太懂??????


    5.树、森林、二叉树的转换
  • 树——>二叉树:将兄弟连起来,断开除长子外的孩子连线,兄弟的变成右子树。

  • 森林——>二叉树:先每个树变二叉树;第一个二叉树不动,后面的依次作为前一个二叉树的根节点的右子树插入。


    6.赫夫曼树及应用
节点到节点的路径,经过的连线。如果有权值,就用权值*路径。权值路径最小的就是赫夫曼树。
描述:把每个点的权值从小到大排列,2个最小的放下面,和成一个值再重新选两个最小的,重复。
N1=15;N2=30;N3=60;
  • 赫夫曼编码:把权值变成0,1

0 0