无语
勤奋,踏实,在生活中学习,在学习中快乐……
     这个周末,复习了线性表的常用存储方式。以前总是看得多,写的少,这次真的写起来,发现自己手生的很,都是眼高手低的结果。在写程序的过程中,也遇到了一些问题和以前没有注意的地方。这次深深的体会到了:自己手写一遍比看书5遍都收获大。所以,借此奉劝和我一样眼高手低的园友:实践,实践,再实践……

    下面介绍常用的四种存储方式,附上源码:

顺序表:这是大家最为熟悉的一种描述,相对比较简单。
         优点:存储空间小,不需要额外增加空间,元素按位置查找方便,速度快。
            缺点:必须预先分配空间,在删除和插入操作时,需要移动元素,因此时间复杂度与元素大小成线性关系,面对大型类对象时,此缺点是致命的。
源码:
Code


 链表:
            优点:删除和插入操作不需要移动元素,表长可动态改变。
            缺点:按位置查找需要遍历链表,存储需要额外的空间。
源码:
Code


模拟链式存储:  它是用int模拟链表节点的指针域而形成的,其基本思想是:每个节点有数据和int型模拟指针组成,申请数组空间,开始设置一个head指向链表的头结点,head=0,其int域为-1,表示链表为空。一个first代表了第一个可用空间的下标,first=1,其int域为2,表示下一个可用空间,以此类推……插入和删除的过程,实际就是设置first和链表的int域的过程。可用户多个链表共享空间。
    优点:插入和删除的过程只需要设置int域,不需要移动元素。其销毁链表的速度远高于指针链表,比如,其链表的头尾指针分别为se,释放时,只需执行node[e].link=first;first=s;即完成链表释放。
    缺点:必须预先分配空间,每个节点需要增加一个int域。
源码:
Code


间接寻址: 它是设立二维指针**pptable,其一维数组里存放元素地址,然后按地址存取,如果访问第五个元素,只需取*pptable[4]即可。它结合了顺序表和链表的优点。
    优点:查找元素的时间复杂性为o(1),删除或插入元素时,只需要移动指针,所以很好的去除了与元素类型的线性关系。尤其适合大的对象。
    缺点:需要预先分配空间。相当于每个节点增加了一个指针大小。
源码:
Code

主程序:
Code
    各个类的调用方式一致,在调用其它类时,只需修改对象类型。


算法时间复杂度分析
s表示元素类型的大小

存储结构                查找第k个元素  查找元素x       删除第k个元素  在第k个元素后插入

顺序表(MyArrayList)     o(1)            o(n)            o((n-k)s)       o((n-k)s)

链表(MyNodeList)        o(k)            o(n)            o(k)            o(k+s)

模拟指针(MySimpleNode)  o(k)            o(n)            o(k)            o(k)

间接寻址(MyIndirectList)o(1)            o(n)            o(n-k)          o(n-k)

 

几点注意事项

1.模板如果应用于复杂数据类型,则应该在此类型中重载!===<<等运算符,因为算法中用到这些运算符。

2.在应用DeleteKInsertK函数时,可以连续调用,这也是返回自身引用的原因。

3.连续调用时,应当注意函数的执行方式。函数调用时,会先确定语句中每个参数的值,才开始执行操作。举个例子,比如当前表长为5,执行

        mylist.DeleteK(1,value).DeleteK(mylist.Length(),value);

是错误的,因为函数的实际执行的是mylist.DeleteK(1,value).DeleteK(5,value);当执行完DeleteK(1,value)时,表长变为4,而接着欲执行DeleteK(5,value),则要删除的第五个元素已不存在。所以会发生异常。正确的调用方式为

        mylist.DeleteK(1,value).DeleteK(mylist.Length()-1,value);

Insert函数也有同样的问题。建议在此语句中最好不要使用Length函数。

4.在异常处理上,最好将异常封装成一个类,然后抛出,这里做了简化,没有分清是哪一种异常。

 

我遇到的问题
1.在组织文件时,模板类的声明必须与定义放在同一个文件中,这就破环了信息隐藏,不知大家都是怎么组织文件结构的?

2.在链式存储中,程序编译链接均正常,但在插入时,抛出一个异常。我通过调试,发现引起异常的语句是这一句:

        Node<T> *q = new Node<T>;

我是想分配一个新节点空间,到现在也没有明白为什么不对,希望高手能不吝指教。

posted on 2008-05-26 12:03  程、诚、成  阅读(976)  评论(4编辑  收藏  举报