线性表基本内容
线性表简称表,是n个元素的有限序列。
特点为每个元素仅有一个前驱和后继,第一个元素无前驱,最后一个元素无后继,并且所有的元素的元素类型相同。
线性表跟其他的逻辑结构的数据一样,存储结构分为顺序存储和链式存储。
顺序存储的表称作顺序表,链式存储的表称作链表。
顺序表
顺序表用结构体内的数组模拟,用一个int类型的变量存储顺序表的长度。
顺序表的构造函数分为有参及无参两种。
无参的构造函数只需初始化表的长度为0,即可代表这个表是空表。
有参的构造函数就不能构造为空表,而是根据传递进来的数组一个个赋值(莫忘长度的赋值,以及若是传进来的表的长度长于线性表的长度,就抛出异常)。
其他的操作都比较简单,就是简简单单的数组操作即可。
查找操作中:
特别注意顺序表的按位置查找的操作。若是顺序表是从0开始存储,那么查找的位置i就对应的不是顺序表中的a[i],而是a[i-1]。(注意所求位置小于0或者大于链表长度的情况)。
若是按值查找,返回位置,则需要注意返回的位置需要是i+1。
插入或者删除操作中:
在插入或者删除元素时,特别注意元素移动的顺序!
若是插入元素到i位置,所有i~n的元素都需要后移,此时的后移为了保持后面元素的完整性,不能从前往后移动,而是从最后一个元素开始移动,逐步后移(时耗巨大),删除元素前移,则是从前往后移动。
链表
单链表是通过随意的几个存储单元存储信息的。
单链表的每一个点都由结构体构成,里面包含着这个点要存储的数值跟指向下一个区域的指针。
单链表的建立需要一个头指针和一个头节点,都是为了以后构造函数等操作的使用方便,保证操作的可复制性,那样的话一样的操作就是一样的代码,不用分好几个情况了。
链表基本的操作有:
(1)构造函数(分为有参的构造函数和无参的构造函数),带参的构造函数又分为头插法和尾插法两种。
一样的是,所有的构造函数都需要先对头指针(也就是first进行构建:分配空间变成头节点与指向下一个元素(大多数情况下例如单链表,都指向空,特殊情况下如循环链表需要再指向first)
不同的是,不带参的构造函数的构造到此为止,而带参的构造函数还需要借助数组进行赋值等操作。
其中,头插法是申请一个节点然后将它插到头节点之后,最核心的操作为:
s->next=first->next;
first->next=s;
尾插法插入的位置是最后一个节点之后,所以需要一个尾指针来标记最后一个位置,以便于O(1)的插入尾部。核心操作为:
r->next=s;
r=s;
(2)遍历输出
遍历输出时,因为头节点没有值,所以可以用p=first->next作为第一个输出的节点,直到p为空才不输出。
(3)按位删除
在删除时,需要注意的是要是删除那个元素a,则a之前的位置也需要知道(因为a之前位置的指针需要变化,指向的不再是a,而是a->next),但是难点也就这一点点,很简单。
为了解决这一问题,我们可以有两种解决方法。
①构造另一个指针,用于删除的指针为q,记录的是当前的位置,用于记录前一个节点是谁的为p,记录的是前一个节点的位置。每次q移动时,先将q的位置赋值给p,在让q赋值为q->next。
②检查的位置为i-1的位置,在到达i-1位置时,直接将p->next=p->next->next,就可以跳过下一个位置,达到删除的操作。
(4)按值删除
遍历,然后找到数字,然后跟按位删除一样的操作(我还是用的两个指针),这里用找位置的第二个方法就不好用了。
(5)插入
锁定插入的位置|。^ ^)
然后跟节点的构造一个操作的修改方法。
学习反思与问题思考:
说实话,指针一直是我们所不熟悉的一块领域,在此之前,我用过最深的指针就是刻意的练习指针的用法并且取内容操作,再就是用的stl里面的迭代器,即使是迭代器也比指针熟悉。
可能是因为迭代器跟指针的相似性,在学习这里的时候,我十分的明白->的作用到底是什么,但是对指针的某些内容还是不是很清楚。
比如说,头节点的形成。直到现在,我对头节点的个人理解止步于利用头指针在头指针的地盘上申请了一个点类型的空间,里面也有一个next来指向下一个节点(自然为空)。头指针和头节点在我的认知范围内是很融洽的融合在一起的,我做题目的时候也是利用的这个想法。
可是老师所说的显然跟我不一样,在他看来,头指针跟头节点仿佛是。两个东西,头指针指向一个头节点,头节点不存储任何数据,里面的指针指向下一个内存区域。
我对此很是迷茫,不知道该怎么思考才能更好的理解头指针与头节点,只能暂且将我的想法贯彻下去。
其次,对于first以及first->next的取用我也十分的分不清楚。
课本上有时候直接给指针赋值为first,有时候则是赋值为first->next,我清楚的明白first不存储任何数据(可是在循环链表里面我还是存储进去东西了,因为那个约瑟夫环状的特殊构造,不存储数据进去我实在不知道该怎么解决我的问题),也知道first->next才是第一个存储数据的节点,可是每次用都要纠结好久好久
与他类似的是指针直到p->next!=nullptr为循环截至的条件还是以p!=nullptr为循环截止的条件,哎纠结啊纠结。
我的解决方法就是一次次的测试,看看哪一次能够成功,所以了解一直不是很深刻,即使某一次用对了也不自知。
数据结构的题目还没有做完!我要继续加油!大佬太多了,后面的题目给我一种很模糊的感觉(明明用set或者别的操作就能完成的题目非要用链表真的很难受。
但是我明白链表的操作是必须的,数据结构是一门很重要的课程,所有的操作我必须直到的一清二楚,所以即使是我很不情愿,可是我也会很情愿的努力用链表做完所有的操作。
继续加油!一定要学会学好这门基础课程!