为什么要学数据结构?

  • 学习数据结构的作用就是在理清数据的逻辑关系的前提下,设计出合理的物理存储结构;

  • 若光有算法,没有数据结构,就相当于一个军师有锦囊妙计,但是没有士兵;

  • 对于数据的排序,不仅要想到冒泡(冒泡排序),还有插入排序,快速排序等效率更高的排序算法。



数据机构与算法的关系:

算法分析的目的在于选择合适算法和改进算法。

良好数据结构(影响数据存储和运行的效率)思想就是一种高效的算法,但是数据结构不等于算法。




线性表、栈和队列:解决的是具有“一对一”关系的数据的存储问题;

树:解决的是具有“一对多”(也可以包含“一对一”)关系的数据存储问题;

图:解决的是具有“多对多”(也包含“一对一”和“一对多”)关系的数据存储问题;



线性表(linear_list):

从逻辑上讲,线性表中的数据是依次排列的,就像南飞的大雁队列(小学生排队过马路)(车队)一样,彼此手拉手,每份数据的前面和后面各有一份数据(有前继和后继)。



用线性表存储的数据有两个特点:

  • 存储的数据本身的类型一定保持相同,是int型就都是int型(不能鹤立鸡群),是结构体就都是一种结构体。

  • 数据一旦用线性表存储,各个数据元素之间的相对位置就固定了。相对位置,指的是各数据元素在逻辑结构上的前后次序。



线性表只对数据的逻辑结构有要求,根据实际存储的物理结构的不同(分散存储或者集中存储)分为链表顺序表。


在实际存储时,并没有像顺序表那样也相互紧挨着。恰恰相反,数据随机分布在内存中的各个位置,这种存储结构称为线性表的链式存储

由于分散存储,为了能够体现出数据元素之间的逻辑关系,每个数据元素在存储的同时,要配备一个指针,用于指向它的直接后继元素,

每个元素本身由两部分组成:本身的信息,称为“数据域”;指向直接后继的指针,称为“指针域”


  • 单向链表

  • 双向链表

    双向链表中的结点有两个指针域,一个指向直接前趋,一个指向直接后继。

      


是线性表的一种特殊的存储结构。栈只能从表的固定一端对数据进行插入和删除操作,另一端是封死的。

使用手机时,屏幕页面的跳转使用的就是栈结构(跳转页面时,前一个页面会被存储到栈中;做回退操作时会回到上一个页面,这是进栈页面出栈的效果)


编写程序判断括号匹配问题的时候,使用栈结构会很容易:

  • 如果碰到的是左圆括号或者左大括号,直接压栈;

  • 如果碰到的是右圆括号或者右大括号,就直接和栈顶元素配对:如果匹配,栈顶元素弹栈;反之,括号不匹配;





队列是线性表的一种,在操作数据元素时,和栈一样,有自己的规则:使用队列存取数据元素时,数据元素只能从表的一端进入队列,另一端出队列


队列的先进先出原则





算法的重要性:

对于算法来说一万年太久。“条条大路通罗马”,解决问题的算法有多种,判断哪个算法“更好”。不能只靠时间更需要使用O(n)(大O记法)来客观衡量时间复杂度


O()使用的代码运行的次数来描述

 for a in range(0, 1001):         #需要运算n次

    for b in range(0, 1001-a):  #需要运算n次

        c = 1000 - a - b          #运算两次

        if a**2 + b**2 == c**2:    

            print("a, b, c: %d, %d, %d" % (a, b, c))

时间复杂度为:

T(n) = O(n*n*(1+1)) = O(n*n) = O(n2)



  • 另, 复杂度的计算抓住重要的点



  1. 在武侠小说中,高手往往注重内功的修养,而招式则为其次,有了深厚的内力,即使不会招式,也能见招拆招。


  2. 算法是一种思想,思想的就具有通用性。 谷歌浏览器相比于其他的浏览器,运行速度要快。是因为它占用了更多的内存空间,以空间换取了时间。(内存大的电脑同理)。

  3. 教室里面有五排座位,每排有六个座位,那么这些人的关系是不是线性表?  是的,可以把每一排的人当做一个线性表,5排就是长度为5的线性表,每一排当做是长度为6的线性表。