zoukankan      html  css  js  c++  java
  • DS博客作业02--线性表

    1.本周学习总结

    1.1思维导图

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

    个人感觉线性表是一种用基础语言构造出来的一种常用算法,并不是来源于语言自身所带的。也就感觉是新学了一种算法。对于线性表的顺序储存结构的编程倒是没什么问题,但对于链式储存结构——链表编程题,虽然能够理解每个语句的意思以及它的逻辑结构,但是编程时不断的出现编程错误,接着就是段错误,而且函数的缺失,使代码无法在编译器内运行,很难找出错误,可谓是困难重重,个人认为还需要一段时间来加深对链表的理解。

    2.PTA实验作业

    2.1.题目1:

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

    输入格式:

      第一行输入顺序表长度。 第二行输入顺序表数据元素。中间空格隔开。
    

    输出格式:

      数据之间空格隔开,最后一项尾部不带空格。
    

    2.1.1设计思路

      CreateSqList建立顺序表
    	定义i
    	顺序表L申请空间
    	L的长度置为n
    	for i=0 to n
    		L->data[i]=a[i] 顺序表置赋值
    //此函数申请顺序表空间,将数组a[i]的值放入顺序表中
    
      DelSameNode 删除重复数据
    	定义 i,j
    	定义 k=0 
    	定义 len=0 新表的长度
    	定义 b[10]={0,0,0,0,0,0,0,0,0,0} 新表的赋值数组
    	for  i=0  to  L->length
    		b[L->data[i]]++ 将相应元素值放入数组b[i]中
    	for  j=0  to  10
    		if  b[j] 大于 0  如果b[j]>0,则将其下标的值放入新表中
    		{
    			L->data[k]=j 下标的值
    			k++
    			len++
    		}
    	L->length=len  将长度置为len
    //主要是将每个数值当作新数组的下标,并对这个下标代表的值++,再对这个数组b[j]扫描,凡是大于0的则放入新表中,重构数组和顺序表,免去了复杂的数组a[i]删除操作
    
       DispSqList  顺序表的输出
    	定义  i
    	for  i=0  to  L->length  循环输出顺序表
    		if  i  等于  L->length-1
    		    输出  L->data[L->length-1]
    		else
    		     输出  L->data[i]  空格
    //利用循环结构输出顺序表,在最后一个输出时控制一下空格问题
    
    

    2.1.2代码截图


    2.1.3本题PTA提交列表说明。

    • Q1:出现编译错误

    • A1:L=new SqList;语句出现问题,导致一开始顺序表L的申请就出错了

    • Q2:部分正确

    • A2:原因在定义的数组b[j]没有进行初始化为0,导致结果出现错误,反映了我对于未初始化的数组的掌握并不完全

    2.2.题目2:

      已知一个带有表头节点的单链表,查找链表中倒数第m个位置上的节点。
    

    输入格式

      先输入链表结点个数,再输入链表数据,再输入m表示倒数第m个位置。
    

    输出格式

      若能找到则输出相应位置,要是输入无效位置,则输出-1。
    

    2.2.1设计思路

       Finding 寻找导数m个数
    	LinkList   p  定义一个结构体指针
    	定义  i  k=0
    	p=L 
    	while  (L!=NULL)  得出整个链表的元素的个数
    		L=L->next  
    		k++  用k来计数
    	if   k > m  能找到的情况下
    	{
    	    for i=0  to  k-m  直接找到倒数第m个数
    		   p=p->next
    	    if  p不为空
    	    return p->data
    	    else  
    	    return -1
             }
            else
        	    return -1
    

    2.2.2代码截图


    2.2.3本题PTA提交列表说明。

    • Q1:答案部分正确
    • A1:第一步的调整并无加入判断条件,编程时想着能先把大结构写出来再进行调试
    • A2:因为第一步没有加入if语句的判断,自然没有else返回值,则答案还是部分正确
    • A3:再进行修改,发现是for循环内的结点取值错误,会取到后面一个去了,进行修改至

    2.3.题目3:

      已知两个递增链表序列L1与L2,2个链表都是带头结点链表。设计函数实现L1,L2的合并,合并的链表仍然递增有序,头结点为L1的头结点。 合并后需要去除重复元素。
    

    输入格式

      输入分两行,先输入数据项个数,再输入数据项,数字用空格间隔。
    

    输出格式

       在一行中输出合并后新的递增链表,数字间用空格分开,结尾不能有多余空格。
    

    2.3.1设计思路

       MergeList 归并函数
    {
    	定义结构体指针 pa=L1->next  pb=L2->next  r  s;
    	r=L1  r指向L1
    	while(pa!=NULL&&pb!=NULL)  两个指针指向都不为空的时候
    	{
    		if  (pa->data==pb->data)  两元素值都相等的时候,进行重复数据的判断 
    		{
    			if  (pa->next!=NULL)  判断哪个不是空的,不空的那个指针就往下移
    			指针 pa 往下移
    			else
    			指针 pb 往下移
    		}
    		if  (pa->data<pb->data)  
    		{
    			s申请空间
    			s->data=pa->data  pa赋值给s
    			r->next=s  和r连接起来
    			r=s  将指针往下传递
    			pa指针往下移
    		}
    		else
    		{
    			s申请空间
    		        s->data=pb->data;
    		        r->next=s  指针间的连接
    			r=s;
    			pb指针往下移
    		}
    	}
           接着扫描剩下的的长度
    	while(pa!=NULL)
    	{
    		s申请空间
    		s->data=pa->data;
    		r->next=s;
    		r=s;
    		pa指针往下移
    	}
    	while(pb!=NULL)
    	{
    		s=new LNode;
    		s->data=pb->data;
    		r->next=s;
    		r=s;
    		pb=pb->next;
    	}
    	r的后续置为NULL
    }
    

    2.3.2代码截图



    2.3.3本题PTA提交列表说明。

    • Q1:编译错误

    • A1:在判断重复数据的时候,把if条件放入判断不重复的数据的分支内

    • Q2:部分正确

    • A2:,当其出现重复数据的时候,若只将pa指针往后移,则会出现空的状况,加入一个else语句使pb也能往后移

    3、阅读代码

    3.1 题目

        一个长度为L(L>=1)的升序序列S,处在第[L/2]个位置的数称为S的中位数。例如,若序列S1=(11,13,15,17,19),则S1的中位数是15。两个序列的中位数是含它们所有元素的升序序列的中位数。例如,若S2=(2,4,6,8,20),则S1和S2的中位数是11。现有两个等长的升序序列A和B,试设计一个在时间和空间两方面都尽可能高效的算法,找出两个序列A和B的中位数。要求:
    (1)给出算法的基本设计思想。
    (2)根据设计思想,采用C或C++或Java语言描述算法,关键之处给出注释。
    (3)说明你所设计计算法的时间复杂度和空间复杂度。
    

    3.2 解题思路

    此题思路主要是对于S1和S2两个序列的中位数的比较
    (1)如果v1.data[mid1]==v2.data[mid2],则直接返回,它们的中位数相等。
    (2)如果v1.data[mid1]<v2.data[mid2],则舍弃S1中比mid还要小的数(因为它们必不可能是中位数)。若序列数元素个数为偶数,则舍弃中位数前的元素;若序列元素个数是奇数,则舍弃包括中位数前的元 素以及中位数。同理,这时也要舍弃S2中较大的一半。
    (3)如果v1.data[mid1]>v2.data[mid2],则舍弃S1中比mid大的数,同时也要舍弃S2中较小的一半,若序列元素个数为奇数则舍弃S2中位数的元素,若为偶数则舍弃包括中位数在内的元素。

    3.3 代码截图

    3.4 学习体会

    此题为考研题,这个题目是找两个序列的中位数。可以说,这道题难度大倒是不大,但是算法的效率有大有小;我的第一直觉就是,先将两个序列合并,再用冒泡排序法排序,最后找出中位数。显而易见,这种算法效率不是最高的。而答案中的算法可以说是直接跳过两个序列合并,而且直接将中位数比较后的序列切去一半或者直接输出,大大提高算法效率;可以说,考研题的算法的确有种让人豁然开朗的感觉,一个思路的转变,就能够大大简化代码,只能说,算法之路,路漫漫其修远兮,吾将上下而求索。

  • 相关阅读:
    可空类型转换为不可空的普通类型
    如何使用AspNetPager分页控件和ObjectDataSource控件进行分页
    TFS映射后丢失引用的问题
    (很好用)JS时间控件实现日期的多选
    取两个日期之间的非工作日的天数(指的是周六、周日)
    在日期格式化的时候提示错误:Tostring没有采用一个参数的重载
    Linq返回的集合类型不是已有的表格类型时的写法(谨记:列表的时候用)
    系统缓存全解析6:数据库缓存依赖
    实现文本框动态限制字数的实现(好方法)
    实现GridView内容循环滚动
  • 原文地址:https://www.cnblogs.com/lxldbk/p/10627840.html
Copyright © 2011-2022 走看看