主题:<数据结构>(严版)第1~4章学习总结
截至今夜为止,数据结构的前四章的学习终于算是暂告一段落。基本已经记不清楚所用的时间了,大约是用了两星期左右吧,当然这是复习,在此之前已经看过若干遍的数据结构,只是一直觉得未曾完全把握所学的内容。至此,也并不意味着已经彻底掌握了,只是在较以前的基础上,又进一步理解了书中所述的主要内容。而现在,就此作一个简单的总结。
在这四章中,第一章不用说,主要是开场白,介绍数据结构这一门课程的基本概念,以及所用到的描述语言,并介绍了算法这个关键的概念,以及衡量一个算法的两个重要性能指标:时间复杂度和空间复杂度。在这一部份中,时间复杂度的计算是一个难点。这里要注意程序运行步数与时间复杂度的区别。程序运行步数是其中所有循环作用下所有语句加在一起的总共的执行次数,而时间复杂度是指这个执行次数在复杂性以及用时的多少基本上达到哪一个阶,一般以O(1),O(n),O(log n),O(nlog n),O(nn),这样的一些阶数来衡量。这里的阶就象数学中的个位,十位,百位一样,是指一个级别,一个范围,也即如果一个程序的执行步数主要与(n-1)的倍数成线性关系,或是n的倍数成线性关系,它们的复杂度都大抵差不多,故而不用详细地分为是n-1的阶还是n的阶,一律看成大约是n阶,这是一个范围。
第二章讲到的是线性表。线性表是数据结构的四大逻辑结构之一。在这一章里只是介绍了常见的最基本的线性表,在后面几章中还会介绍在基本的线性表上稍作一些规定与限制的线性表(栈,队列,串,广义表)。最基本的线性表就是数据之间存在着线性的关系,都是一对一的关系,一个结点跟接在另一个结点后面,成一条线的关系。每个结点只有一个前驱和一个后继(除第一个结点和最后一个结点而外)。
为了处理这些线性的数据,我们在计算机的内部怎样存储它呢?我们可以采取两种最基本的存储方式,一种是:顺序存储结构,它采用数组来进行存储,也就是说数据是存储在数组里面的,这种结构适合于在整个程序的执行过程中对数据的操作并不影响它的结构,一般只进行查询检索等简单的操作;而所用到的该数组的分配方法可以是静态的也可以是动态的。静态的就是自始至终数组的长度是不变的,比如分配了100个,那就一直是100个,运行前后即运行时都只有这么个固定的空间。但如果是动态的,那么在程序运行过程中,可以根据实际需要空间的情况,而进行动态地增加空间。一般是预先给它分配M个字节左右的空间,如果不够,再固定地增加N个,如果还是不够,再增加N个等,以这样的方式进行。在严版的书上会有相关的程序说明与介绍。
线性表的另一种存储结构就是传说中的以指针来处理的链表。(其实在第一种中用动态数组时也会简单地涉及到指针的操作,但这里是完全的指针操作,就连每一个结点也是用指针的形式来定义。)在这里,常有单链表,双链表,循环链表,等多种结构。结构多一些,也就是说方式多一些。方法多一些,这样我们应用起来的时候就灵活一些。先说说单链表,单链表中,它先定义单链表的结点,也就是说既然是一个单链表的话,它的结点应该具有单链表的风格,每个结点由两个域组成:数据域+指针域。然后可以在此的基础上定义什么是一个单链表。一个单链表就是由这样的一些结点,一个指着一个连接起来的。a->b->c->d... 成为一个链子。而这个链子只所以能够链在一起,靠的就是它的每个结点中的所定义的那个称之为指针域的指针。每个结点都固定的有一个指针,指向它后面的结点。因此,在单链表的操作中,如果需要增加数据或是删除数据,都只需要移动指针即可。也即对指针进行操作即可。修改指针的指向。
无论是用顺序表结构来存储线性表还是链表结构来存储线性表,我们所需要的实现操作都得先在几种存储结构的ADT的基础上实现。也就是说,如果要真正把程序写出来,并执行出数据结构的话,首先得要用计算机语言向程序说明该存储结构的存储方式,所需要用到的操作种类,以及每一种操作所需要实现时在计算机内部直接对存储结构应该作什么样的操作。说明了这些以后,才有可能在主程序中调用这些子程序功能实现模块,一一进行调试实践并得出程序的运行结果。
在以上两种结构中,由于顺序表是以数组为基本存储结构的,所以具有直接随机访问的特点,而链表呢只能逐一地向后移动到相应的数据上才能进行读取,所以具有顺序存取访问的特点。
另外,在链表中,很多时候我们都需要加一个头结点,这是为了简化算法的方便。在殷人昆版的《数据结构》中对此作出了详细的说明,在此我们就不再详述。
在这四章中,第一章不用说,主要是开场白,介绍数据结构这一门课程的基本概念,以及所用到的描述语言,并介绍了算法这个关键的概念,以及衡量一个算法的两个重要性能指标:时间复杂度和空间复杂度。在这一部份中,时间复杂度的计算是一个难点。这里要注意程序运行步数与时间复杂度的区别。程序运行步数是其中所有循环作用下所有语句加在一起的总共的执行次数,而时间复杂度是指这个执行次数在复杂性以及用时的多少基本上达到哪一个阶,一般以O(1),O(n),O(log n),O(nlog n),O(nn),这样的一些阶数来衡量。这里的阶就象数学中的个位,十位,百位一样,是指一个级别,一个范围,也即如果一个程序的执行步数主要与(n-1)的倍数成线性关系,或是n的倍数成线性关系,它们的复杂度都大抵差不多,故而不用详细地分为是n-1的阶还是n的阶,一律看成大约是n阶,这是一个范围。
第二章讲到的是线性表。线性表是数据结构的四大逻辑结构之一。在这一章里只是介绍了常见的最基本的线性表,在后面几章中还会介绍在基本的线性表上稍作一些规定与限制的线性表(栈,队列,串,广义表)。最基本的线性表就是数据之间存在着线性的关系,都是一对一的关系,一个结点跟接在另一个结点后面,成一条线的关系。每个结点只有一个前驱和一个后继(除第一个结点和最后一个结点而外)。
为了处理这些线性的数据,我们在计算机的内部怎样存储它呢?我们可以采取两种最基本的存储方式,一种是:顺序存储结构,它采用数组来进行存储,也就是说数据是存储在数组里面的,这种结构适合于在整个程序的执行过程中对数据的操作并不影响它的结构,一般只进行查询检索等简单的操作;而所用到的该数组的分配方法可以是静态的也可以是动态的。静态的就是自始至终数组的长度是不变的,比如分配了100个,那就一直是100个,运行前后即运行时都只有这么个固定的空间。但如果是动态的,那么在程序运行过程中,可以根据实际需要空间的情况,而进行动态地增加空间。一般是预先给它分配M个字节左右的空间,如果不够,再固定地增加N个,如果还是不够,再增加N个等,以这样的方式进行。在严版的书上会有相关的程序说明与介绍。
线性表的另一种存储结构就是传说中的以指针来处理的链表。(其实在第一种中用动态数组时也会简单地涉及到指针的操作,但这里是完全的指针操作,就连每一个结点也是用指针的形式来定义。)在这里,常有单链表,双链表,循环链表,等多种结构。结构多一些,也就是说方式多一些。方法多一些,这样我们应用起来的时候就灵活一些。先说说单链表,单链表中,它先定义单链表的结点,也就是说既然是一个单链表的话,它的结点应该具有单链表的风格,每个结点由两个域组成:数据域+指针域。然后可以在此的基础上定义什么是一个单链表。一个单链表就是由这样的一些结点,一个指着一个连接起来的。a->b->c->d... 成为一个链子。而这个链子只所以能够链在一起,靠的就是它的每个结点中的所定义的那个称之为指针域的指针。每个结点都固定的有一个指针,指向它后面的结点。因此,在单链表的操作中,如果需要增加数据或是删除数据,都只需要移动指针即可。也即对指针进行操作即可。修改指针的指向。
无论是用顺序表结构来存储线性表还是链表结构来存储线性表,我们所需要的实现操作都得先在几种存储结构的ADT的基础上实现。也就是说,如果要真正把程序写出来,并执行出数据结构的话,首先得要用计算机语言向程序说明该存储结构的存储方式,所需要用到的操作种类,以及每一种操作所需要实现时在计算机内部直接对存储结构应该作什么样的操作。说明了这些以后,才有可能在主程序中调用这些子程序功能实现模块,一一进行调试实践并得出程序的运行结果。
在以上两种结构中,由于顺序表是以数组为基本存储结构的,所以具有直接随机访问的特点,而链表呢只能逐一地向后移动到相应的数据上才能进行读取,所以具有顺序存取访问的特点。
另外,在链表中,很多时候我们都需要加一个头结点,这是为了简化算法的方便。在殷人昆版的《数据结构》中对此作出了详细的说明,在此我们就不再详述。