郝斌数据结构视频教程笔记(讲的通俗易懂)

  

            郝斌数据结构视频教程笔记

指针:

指针占的总是四个字节,和它指向的数据无关。

Malloc函数:

C语言里面用malloc函数分配了内存,必须要自己手动用free()函数去除,不然会发生内存溢出,很危险;java里面就有自动内存清理机制。

C语言里面,要跨函数调用内存,就必须要通过函数来实现,要使用动态分配。

  静态分配的,函数一执行完就没了,动态分配的却还存在。

链表:

   确定链表只需要头结点一个参数即可。

   链表不是一个连续的,如果要往后移的话,就需要p = p->Next;

算法

   狭义的算法与数据的存储方式密切相关。

   广义的算法是与数据的存储方式无关。

  

泛型:

   利用某种技术达到的效果就是:不同的存数方式,执行的操作是一样的。

   C语言中没有bool类型,C++里面才有bool类型。可以用加上include<stdbool.h>的头文件来声明。

堆:动态分配,由程序员分配。

栈:静态分配,由操作系统分配。

应用:函数调用,中断,表达式求值,内存分配,缓冲处理,迷宫。

         

队列

  一种先进先出的存储结构。

分类:链式队列:用链表实现。

静态队列:用数组实现,通常都必须是循环队列(只能够增加,不能够减少的话,数组的空间就全部浪费了)。

循环队列的讲解:

1.      静态队列为什么必须是循环队列。

2.      循环队列需要几个参数来确定。及其含义的讲解。

2个,front和rear。

头部:front(指向第一个元素),尾部:rear(指向最后一个元素的下一个元素)。

两个参数不同场合有着不同的意义:

3.       队列初始化    front和rear的值都是0.

4.       队列非空 

front代表队列的第一个元素,rear代表队列最后一个有效元素的下一个元素。

5.       队列空。

front和rear的值相等,但是并不一定是0。

6.      循环队列各个参数的含义。

7.      循环队列入队伪算法讲解。

两步完成:

8.      将值存入r所代表的位置。

9.      错误的写法r=r+1(这样会内存溢出,爆掉)

正确的写法:r = (r+1)%数组的长度;

10.   循环队列出队伪算法讲解。

         f = (f+1)%数组的长度;

11.   如何判断循环队列是否为空。

如果front和rear相等,则该队列一定为空。

12.   如何判断循环队列已满。

预备知识:front和rear可大可小,可相等。

两种方式:

13.   多增加一个标志识参数。

14.   少用一个元素[通常用这种方式]。

   如果rear和front的值紧挨着,则队列已满。

   用C语言的伪算法表示就是如下:

   If((r+1)%数组的长度 == f){

     满了。

}else{

    不满。

}

队列算法:

(1)压栈。

(2)出栈。

队列的具体应用:所有与时间有关的操作都与队列有关,

递归

定义:一个函数直接或者间接的调用自己。

      直接调用,间接调用。

      递归必须满足的三个条件:

15.   必须有一个明确的终止条件。

16.   该函数所处理的数据必须在递减。(值可以递增,但处理的值必须递减)。

17.   这个转化必须是可解的。(所有的循环都可以用递归实现,反之不成立)

   递归的循环的比较:

递归:易于理解,速度慢,存储空间大。

循环:不易理解,速度快,存储空间小。

      举例:

         1.1+2+3+……+100的和。

           2.求阶乘。

                数字一大的话,就会发生溢出。

                在visual C++里面,整型和长整型占的字节数一样。

18.   汉诺塔。

 (这不是线性递归,而是个非线性递归)。

N = 1    1

N = 2    3

N = 3    7

……

N = 64   2的64次方减1[这为一个天文数字]

           4.走迷宫。

                   

递归的应用:

  (1)树和森林就是以递归的方式定义的。

 (2)树和图的很多算法都是以递归来实现的。

 (3)很多数学方式就是以递归的方式来定义的。

               斐波拉契数列

模块二:树和图   (非线性结构)

树:

   专业定义:

19.   有且只有一个称为根的节点。

20.   有若干个互不相交的子树,这些子树本身也是一棵树。

              

              通俗的定义:

21.   树是由节点和边组成。

22.   每个节点只可以有一个父节点,但可以有多个子节点。

23.   但有一个节点例外,该节点没有父节点,此节点称为根节点。

专业术语:

       节点     父节点     子节点

       子孙     堂兄弟    

    

       深度:

            从根节点到最底层节点的层数称为深度。

       叶子节点:没有子节点的节点。

       非终端节点:实际就是非叶子节点。

       度:子节点的个数称为度。

        整个树的度挑最大的那个点。

分类:

   

一般树:

     任意一个节点的子节点的个数不受限制。

二叉树:

     任意一个节点的子节点的个数最多是两个,且子节点的位置不可更改(为有序树)。

   

     分类:

             一般二叉树:

             满二叉树:

                在不增加树的层数的前提下,无法再增加一个节点的二叉树就是满二叉树。

             完全二叉树:(包含了满二叉树)

               如果只是删除了满二叉树,最底层,最右边的连续的若干个节点,这样形成的树就是完全二叉树。

   

森林:

     N个互不相交的树的集合。

树的存储:

     

                二叉树的存储:

                         连续存储[完全二叉树]:

                               优点:查找某个节点的父节点和子节点(也包括判断有没有子节点)的速度很快。

                               缺点:耗用内存空间过大。

                        

                         

                         链式存储(不是链表存储):

               

                一般树的存储:(解决非线性用线性解决的方法)

24.   双亲表示法。

     求父节点方便。

25.   孩子表示法。

          求子节点方便。

26.   双亲孩子表示法。

           求父节点和子节点都方便。

27.   二叉树表示法。

把一个普通树,转化为二叉树来存储,

具体转化方法:

      设法保证任意一个节点的:

        左子针域指向它的第一个孩子,右指针域指向它的下一个兄弟。

只要能够满足此条件,就可以把一个普通树转化为二叉树。

一个普通树转化成的二叉树一定没有右子树。

                森林的存储:

先把森林转化成二叉树,再存储二叉树。

操作:

         遍历:

              先序遍历:(本质上是一个递归的过程)

                       先访问根节点

                       再先序访问左子树

                       再先序访问右子树

              中序遍历:

                       中序遍历左子树

                       再访问根节点

                       再中序遍历右子树

              后序遍历:

中序遍历左子树

                       再中序遍历右子树

再访问根节点

 

         已知两种遍历序列求原始二叉树:

            研究发现:通过先序和中序 或者中序和后续,我们可以还原出原始二叉树,但是通过先序和后续是无法还原出原始的二叉树的。

          换一种说法:

               只有通过先序和中序,或者中序和后序,我们才可以唯一的确定一个二叉树。

应用:

     (1)树是数据库中数据组织的一种重要形式。

     (2)操作系统子父进程的关系本身就是一棵树。

     (3)面向对象语言中类的继承关系本身就是一棵树。

链式二叉树遍历具体程序实现:静态分配的内存在函数执行完之后,就消失了,动态分配的却还存在,还能够就访问(malloc函数写的)。

一个int类型的数据占四个字节。

模块三:查找和排序

         折半查找

         

            排序

                  冒泡:

                  插入:

                  选择:

                  快速排序:经过一次排序只能够把第一个元素的确切位置找到(也是利用递归的思想),其它元素依然是无序的。

                  归并排序:

            稳定排序和不稳定排序(相等的话,原来在前面的还是要在前面)。

             

排序和查找的关系:

              排序是查找的前提

             

 

Java中容器和数据结构相关知识:

         Iterator接口。

         Map

              哈希表。

数据结构定义:是研究数据的存储和数据的操作的一门学科。

               数据的存储分为两个:

28.   个体的存储。

29.   个体关系的存储。

 最核心的就是数据关系的存储,个体的存储可以忽略不计。

再次说明什么是泛型:

      同一种逻辑结构,无论该逻辑结构物理存储是什么样子,我们可以对它执行相同的操作。

   

注意:剩下的图的相关知识,需要自己去学习和完善。


猜你喜欢

转载自blog.csdn.net/hello_leiyuanyi/article/details/79781539