表、栈、队列是数据结构与算法分析的第二章,其中我要讲的数据结构是来自于我看了各种书跟博客之后的总结跟理解,算法主要是算法导论这本书,讲述的的标准是C语言的标准, 并且我们讨论的常说的数据结构都是抽象的逻辑存在的,大家最好去看一下大O记法怎么计算算法速度跟空间的,我们很多时候就是为了这个效率跟空间弄出了很多抽象数据结构。
接下来先讲表。。。。表这个是书上写的 其实应该是链表跟顺序表两样。
表(list)
L.elem=(Elemtype *)malloc(LIST_INIT_SIZE* sizeof(Elemtype));
那么方便插入跟删除,并且不需要连续的内存地址,它就是链表:
链表由一系列的节点组成,他们不必在内存中相连,如3-1,3-2所示,A1是存在里面的值而800是他下一个元素的地址,这样一个接一个的就形成了链表。如果想删除A2,只要吧A1的尾巴地址(next,图3-2,A1的800)改成A3的地址712,再把A2的尾巴地址设NULL(最好在把权限交还给系统,就完美了)。把A1的尾巴地址换成一个新的内存地址A0,再把A0的尾巴地址指向A2,这样就完成了插入。是不是比顺序表节约了很多的资源呢??
注意:链表不需要内存连续,也正因为如此遍历的效率要比顺序表略慢。
记忆比喻:想象成老鹰捉小鸡的游戏,后一个拉着前一个的衣服,一个接一个的形成链。
上面讲链表是单链表。下面说双链表,什么是双链表?单链表是有个尾巴里面存的是后一个元素的地址,那双链表很明显,手里在抓个绳子。绳子栓的前一个的尾巴,这就是双链表(图3-16)。如果单链表的最后一个元素的尾巴放着第一个元素的位置。那么双链表呢 就比较任性。。大爷我顺时针转够了逆时针也能转(因为前后都有地址嘛,真任性)。那么如果要删除一个元素怎么办呢?(图3_16,删除A3) 如果想删除A3 那就需要吧A2的屁股里存的地址改成A4的。那双向的呢? 一样的,A2的屁股链接到A4,A4得手上的绳子拴上A2,就OK啦。那么如果,没有指针的语言怎么办?那就手动实现一个双向链表,其结构与双向链表是完全一样的,我们管它叫游标。
一般都是用来存储参数名的,比如int a = 10; 这个a 就是存在栈空间里面的,那么10呢? 自然就是堆了。我们先撇开堆不谈 先说说栈。
书上给的定义一大串太特么长了。 简单说就是一个框 你先扔进去的肯定最后才能倒出来, 那么后扔进去的就在上面 直接那就是了(数组)。 利用刚才一叠盘子的记忆方式思考一下,想拿只能拿最上面的,想删除也只能删后进去的,插入也是(其实从概念图上理解就上放上去而已,但实现起来就是插入)。说到这大家是不是奇怪这么个存储形式的有什么用???
那你仔细想想你写代码的时候是什么样的??。运行的时候是全局变量先被实现出来,然后是方法然后局部变量,结束之后呢? 局部变量被销毁 然后方法 最后呢?全局变量。那不就是栈的顺序么(注:这里说得变量跟方法都是只参数名。怕高手挑刺用得,学习者可以不理解)。所以这东西不光能用,还非常的有用,实用。
注意:先进后出。所谓的结构,都是大家常用的存储跟操作模式,是逻辑上的,知道结构就能知道他的方式,那就能写出代码
记忆比喻:框,后扔进去的先出来。
接下来就是今天的最后一个课题。
跟栈一样,队列也是一种表。如果有根管道,那么两头都是通的。。排成一队笔直向前 就跟穿过隧道一样,这边进另外一边出。
如图,我们要记录他得size(长度)跟他的两端,比如说第一个叫front(前面),最后一个叫rear(后面)。
插入:size跟rear都加一然后,把要插入的元素赋给下标为rear的位置,
删除:与上面类似,size跟front都减一 然后再把front加一就好了
注意:先进先出。
记忆比喻:一个单行线车道,前面车不走后面走不成。
关于队列的一些应用就是排队系列,网络排队 或者各种人员登录的时候的等候排队 等等
数据结构这类文章,我修改了3次了已经。越修改越简练,数据结构到底学的是什么。就是你对结构的认知认识,然后用他去解决问题。至于怎么去实现这些个结构,跟相应结构的操作是算法的事(大部分只有指针类语言可以实现)。所以从开始到最后 我这篇文章没有明显的写出算法,以后应该会填上一些吧。还有关于语言的问题,数据结构用类C或者C语言都可以,并不难懂 总共就那么几样一baidu,就全明白了。
有问题希望大家指正
by Areay