1.本周学习总结#

1.1思维导图##

1.2.谈谈你对线性表的认识及学习体会##

通过线性表的学习,对链表有了更进一步的认识和掌握,链表相比于以前的数组,它对数据的插入、删除,方便了许多,是一种更高效的做法,不用通过挪动数组来插入、删除,只要改变链连接的结点即可。而有序表的操作与数组类似,也是通过移动来插入、删除数据。
上学期也学习过一点链表,但只是粗略的知道有链表这种数据结构的概念,通过这次的学习,学到了链表的一些基本操作,也发现了链表的优点。

2.PTA实验作业#

2.1.题目1:顺序表操作集##

2.1.1设计思路(伪代码)###

查找函数
定义i为Data数组下标
for i=0 to L->Last+1
      如果找到数据X
      返回i
end for
返回ERROR

插入函数
定义Data数组下标i
if  未插入数据时,顺序表里数据个数已经等于MAXSIZE-1
	输出FULL
        返回false
end if
else if 插入位置在第一个数前面或在最后一个数的后面的后面位置
      输出ILLEGAL POSITION
      返回false		
end if
else
      for i=L->Last+1  to i>=P
              把前一个数据放到i这个位置
       end for
       把X赋值给L->Data[P]
       L->Last++;
       返回true
end if

删除函数
定义Data数组下标i
if 要删除数的位置不在顺序表范围内
       输出POSITION P EMPTY
       返回false
end if
else
      for i=P to L->Last
             把第i+1个数往前移
      end for
      L->Last--
      返回true
end if

2.1.2代码截图###


2.1.3本题PTA提交列表说明###


Q1:一开始题目较长,函数又比较多,题目意思不是很理解,Devc上代码写好后,测试时输出结果与题目不同
A1:第一个函数要求创建并返回一个空的线性表,我一开始是L->last=0,但输出结果总是错的,后来看了网上一些代码,发现L->last=-1才是。若L->last置为0,则插入5个数,实际只有4个数被插进去
Q2:输出结果和题目的一样后,开始提交,一直是答案错误
A2:原因是我动态申请时,写的是L=(List)malloc(sizeof(struct List)),改成L=(List)malloc(sizeof(struct LNode))就OK了

2.2 题目2:有序链表合并##

2.2.1设计思路(伪代码)###

定义两个指针p,r
把L1->next赋给p
把L1保存在r中
把r后面的关系断掉
while p&&L2
     if  p->data<L2->data
           p结点插入r后面
           p指针往后移
           r指针往后移
     end if
     else if p->data>L2->data
           L2结点插入r后面
           L2指针往后移
           r指针往后移
     end if
     else
           p结点插入r后面
           p指针往后移
           L2指针往后移
           r指针往后移
     end if
     while p
            p中剩余部分插入r中
     end while
     while L2
           L2中剩余部分插入r中
     end while
     r->next=NULL
end while

2.2.2代码截图###


2.2.3本题PTA提交列表说明###

Q1:输出结果错误
A1:题目要求合后的链表头结点为L1,于是,我直接用L1进行操作,把p,L2直接插在L1上,导致输出结果错误。于是我将L1付给r指针,对r指针进行操作
Q2:如何实现合并两个链表和仍保持有序性
A2:通过遍历两个链表,把较小的数那个插入r中,然后移动较小数所在链表和r的指针,若两个数相同,则只插入其中一个,同时移动p、L2、r的指针,最后,若p或L2有剩余数据,则把剩余的全部插进r中

2.3 题目3:两个有序序列的中位数##

2.3.1设计思路(伪代码)###

主函数
    定义链表指针L1,L2
    定义n
    输入n
    函数调用

尾插法建链表函数
    定义链表指针s,r
    定义i
    给L动态申请空间
    L赋给r
    for i=0 to i<n
	给s动态申请空间
	输入s->data
	把s插到r后面
     end for
     r->next=NULL

合并链表函数 
      定义两个指针p,r
      把L1->next赋给p
      把L1保存在r中
      把r后面的关系断掉
      if  p->data<L2->data
           p结点插入r后面
           p指针往后移
           r指针往后移
     end if
     else if p->data>=L2->data
           L2结点插入r后面
           L2指针往后移
           r指针往后移
     end if
     while p
            p中剩余部分插入r中
     end while
     while L2
           L2中剩余部分插入r中
     end while 
     r->next=NULL;

找链表的中间数函数
     定义指针p
     定义n=0,i=0,j
	p=L->next;
	L=L->next;
      while(p)   
	    n++
	    p指针后移
       end while
       j=(n+1)/2   //中位数
       while(L)
	    i++
	    if i==j 
		输出中位数
            end if
	    L指针后移
	end while

2.3.2代码截图###




2.3.3本题PTA提交列表说明###

Q1:做这题时还是比较顺利
A1:要寻找两个有序序列的中位数,先把这两个链表合并,然后遍历合并后的链表,计算出该链表的元素个数,找出中位数是第几个数,再遍历链表找到中位数

3、阅读代码#

3.1 题目##

编写一个程序,找到两个单链表相交的起始节点。
如下面的两个链表:

在节点 c1 开始相交。

3.2 解题思路##

指针 pA 和 pB 分别指向链表 A 和链表 B 的头结点,之后两个指针分别以步幅为 1 的速度向链表的尾部遍历,当指针 pA 遍历到链表 A 的尾节点时,将指针 pA 指向链表 B 的头部。同样地,当指针 pB 遍历到链表 B 的尾节点时,将指针 pB 指向链表 A 的头部。当两个指针相遇时,指针 pA 或者 pB 所指向的节点就是两个链表的相交节点。

3.3 代码截图##

3.4 学习体会##

该题用两个指针相对其他做法,降低了时间复杂度和空间复杂度,也简化了代码,算是最优的解题的方法。
多看题可以开拓我们的思维,打破我们的定向思维,优化算法,找到更高效的解决方法。