DS02--线性表

一、PTA实验作业

题目1:线性表元素的区间删除

给定一个顺序存储的线性表,请设计一个函数删除所有值大于min而且小于max的元素。删除后表中剩余元素保持顺序存储,并且相对位置不能改变。

1. 设计思路

定义整型变量统计变量n,循环变量i	
if (最小值大于等于最大值) 
	return L
for( i=0 to 链表最后)
	if ( L->Data[i]满足条件 )
		统计变量n++
	否则 L->Data[i-n]=L->Data[i] 剔除不合题意的值
i++ end
L->Last-=n改变链表最后位置

2.代码截图

3.PTA提交列表说明

4.调试问题

- 思路错误:最初始参考课堂派的一道题来做的,后来发现不用那么麻烦,一层循环就可以

题目2:判断链表结点对称

设计算法,判断带头结点的循环双向链表中的数据结点是否对称。 如果对称,输出“yes” 如果不对称,输出“no” 链表空则输出“NULL”

1.设计思路

------------初始化函数-------------

创建头节点L
L的前后指向自己,构成循环链表

销毁函数

定义L及其下一个节点的代理工作结构体指针s,p
while (p指针没指到头结点L)
	delete pre删除前一节点
	pre = p;同时向后移
 	p = p->next;
end p==L循环结束
delete pre 删除最后节点

--------------输出函数---------------

定义L下一个节点的代理工作结构体指针s
若L为空 输出NULL
while(s指针没指到头结点L)
	输出s->data 
	指针后移
end s==L
换行

---------------插入函数--------------

定义计数变量j=0
定义L的代理工作结构体指针p,带插入节点指针s

while(前i-1个节点且不为空)寻找插入位置
	p向后移
	j计数++
end j==i-1找到第i-1个元素

s申请空间并给数据域赋值
s->next = p->next  在p后插入s新节点
s->prior = p  双向
p->next->prior = s
p->next = s


--------------判断对称函数-------------

定义L前后节点的代理工作结构体指针s,r
while (s不等于r)
	若  s数据域不等于r数据域  不对称
	return 0
	否则  继续循环链表
	s,r分别向前后移动遍历链表
end 链表遍历结束
return 1 成功循环则对称 

2.代码截图

3.PTA提交列表说明

4.调试问题

  • 4.1 编译错误:没有加c++头文件

  • 4.2 运行超时:销毁函数错误

调试过程:

最初在dev运行时答案正确但会停止工作

所以我先把判断是否对称函数注释掉,发现在输出链表后就会停止工作

最后检查出是销毁函数的条件错误,因为是双向链表,所以在循环到头结点L时就停止销毁,而我惯性思维将条件写成不为空

  • 4.3 部分正确:空表输出NULL

题目3:顺序表删除重复元素

设计一个算法,从顺序表中删除重复的元素,并使剩余元素间的相对次序保存不变。

1. 设计思路

-----------------创建函数----------------

定义循环变量i
若 节点个数n为0  exit 0
为L申请存放空间
for(i=0 to n)
	L数据域赋值
end 数据存放结束
链表长度=n

------------------输出函数-----------------

定义循环变量i
for(i=0 to 长度-1)
	输出数据加空格
end 输出n-1个数据
输出最后一个数据不加空格


---------------删除重复元素函数--------------

定义循环变量i=0,j=1,记录变量len=1
while (j小于长度)遍历链表
	for(i=0 to len)
		若 有重复元素
		break 跳出
	若 i==len 
	剩余元素加入
	否则  j++
end 

2.代码截图

3.PTA提交列表说明

4.调试问题

部分正确:重复元素,只判断了前后元素是否重复。

二、截图本周题目集的PTA最后排名

1.顺序表PTA排名

2.链表PTA排名

3.我的总分:2.5分

三、本周学习总结

1.谈谈你本周数据结构学习时间是如何安排,对自己安排满意么,若不满意,打算做什么改变?

这周的话,几乎都在PTA上磨时间,有收获也有失落,可能还没能将链表理解透彻,并不能在题目中较好的使用链表。每道题都是极大的挑战。碰到做不出的操作,我会先百度看完思路后,再自己动手打出来,模仿也是种学习。当自己打完后还有不会的地方,这时会自己思考。我认为这种学习方式很适合自己,会坚持下去。

2.谈谈你对线性表的认识?

2.1顺序表:连续的内存划分及数据存储

  • 性质:

①随机访问(查找快,直接定位)
②存储密度高,只存储数据元素
③插入、删除操作需要大量移动元素

  • 插入:

①时间复杂度:O(n)
②空间复杂度:O(1)

  • 删除:

①时间复杂度:O(n)
②空间复杂度:O(1)

2.2单链表:非连续的内存划分

  • 性质:

①逐个遍历(查找慢)
②存储密度相对低,存放指针域
③插入、删除操作快

2.3双链表

在单链表的基础上,结构体增加一个指向前驱结点的prior的指针

2.4循环单链表

在单链表的基础上,在表尾的next指向表头 r->next = L

2.5循环双链表

在循环单链表基础上,结构体增加一个指向前驱结点的prior的指针,加上L->prior = r;r->next = L

3.代码Git提交记录截图

四、阅读代码

题目:重排链表

void reorderList(ListNode head)
 { 
        if(head == null || head.next == null)
            return;
        ListNode p = head;
        ListNode q = head.next;
        while(q != null && q.next != null)
        {
            p = p.next;
            q = q.next.next;
        }
        //中间节点
        q = p.next;  
        p.next = null;
        //将后半段逆序
        ListNode rHead = null;  
        while(q != null)  
        {  
            ListNode r = q.next;  
            q.next = rHead;  
            rHead = q;  
            q = r;  
        }
        //向前半段插入
        q = rHead;  
        p = head;  
        while(p != null && q != null)  
        {  
            ListNode rr = q.next;  
            ListNode lr = p.next;  
            q.next = lr;  
            p.next = q;  

            q = rr;  
            p = lr;  
        }
}

分析:这道题很有意思,第一眼看上去很复杂,其实只要先找到链表的中间节点,然后将后半部分提出来,把后半部分反转,然后将前半部分与反转了的后半部分交叉合并起来。这段代码是从网上找的,只贴出了最核心的一部分。

posted @ 2018-03-24 12:55  limb171004  阅读(1230)  评论(2编辑  收藏  举报