线性表—链式存储结构
链式存储结构就是一环扣一环的线性结构,好像链条中的每一个人都只知道下一个人的地址,只有从前往后顺序查找才能找到第 j 个人。
链式结构的好处是在插入和删除时不需要移动插入位置后面的元素,但要找到要插入和删除的元素的位置还是得像顺序存储结构一样查找,但这个查找还有所不同,顺序存储结构支持我们使用二分查找之类的方法进行查找插入以及删除的位置,至于链式结构感觉似乎没法使用二分法类似的方法(充分利用有序这一条件进行查找)
链式存储结构适合于插入删除操作比较多的场合,比如飞机航班的乘客信息,至于学校的学生信息就不适合了,后者查询操作多于插入或者删除操作。
单链表数据结构的构建如下:
① LNode.h:单链表节点类模板,就是一个链表最基本的组成元素,是一个struct LNode,里面存储着 【希望节点拥有的数据部分】+【下一个节点的地址 LNode * next 】因为是单链表,只存储了下一个元素的地址。
② Alist.h :也就是我们定义的线性表所应该拥有的最基础的一组操作,里面有纯虚函数,所以是抽象基类,不能实例化。我们在不同类型的线性表里面继承这个类,然后重载其定义的基本操作。
③ LinkList.h :主人公,我们的单向链表类,他public继承了抽象基类Alist.h,且把一个算法MergeList函数模板 声明成了它的友元,因为这个函数要操作Linklist的私有成员,所以必须是友元才行。
下面是LinkList的成员介绍:
基本函数:
【构造函数】:创建一个空的链表,注意,这里的空是有一个 Head 节点的,但是这个Head节点是隐含的,他不算是链表的成员,它的存在只是方便了我们对链表进行各种操作,这样构造函数创建了一个Head节点,数据成员部分没有具体的值,指针 next =NULL;毕竟只是创建一个空表。
【析构函数】:让整个链表分崩离析,注意里面每个节点都要在内存中释放掉 ,析构完成后表应该是空的,我们delete 每一个节点的地址,这个顺序应该从前往后进行,因为只能从前往后进行,先把头结点和后面的部分断开,在获得第一个元素的地址(即Head->next )后,就把Head->next=NULL,然后从前往后依次delete每一个元素,最后把Head delete掉,其实也可以在分开后就把Head释放掉。
查询函数: (大多为const的)
---------------------------------------------------------------------------------------------------------------------------------
归并函数:归并之后有一个变成了空的,这就要把一个链表元素有规则的插入进另一个链表里面,归并完后有一个为空可以通过清空操作来完成,我的做法是并不是真的每一个元素都插入,在la到了NULL之后就把lb的剩下部分都直接连过来了,这样最后要求lb应该是空的,我通过clearlist清空操作来完成,结果由于lb的末尾没有变,造成了内存读写错误。算是指针越界。
---------------------------------------------------------------------------------------------------------------------------------
二基础,六查询,三操作!
----------------------------------------------------------------------------------------------------------------------------------
对const函数有了新的理解,见另一篇关于const成员函数的介绍。