1.本周学习总结(0--2分)
1.1思维导图
1.2.谈谈你对线性表的认识及学习体会。
本周学习线性表的主要内容,感觉是之前学习的结构体和链表的综合,只要之前的链表内容搞清楚了,学习起线性表应该不太困难。线性表是n个数据元素的有限序列,主要分为顺序存储结构和链式存储结构,有优点也有缺点,准确把握其特点在应用时会方便精准很多。逻辑关系上相邻的两个元素在物理位置上也相邻。线性表的优点:随机存取表中任一元素,它的存储位置可用一个简单、直观的公式来表示。缺点:作插入或删除操作时,需移动大量元素。在写pta时,最基本的就是写出线性表的插入,删除,虽然看起来挺简单,但是作为最基本的用法,还是尽量写的越熟练越好,这样在写更复杂的代码时才不会因为简单的插入或者删除函数写错而导致调试很久找不出错误。
2.PTA实验作业(6分)
2.1.题目1:顺序表操作集
2.1.1设计思路(伪代码)
函数一:创建并返回一个空的线性表
List MakeEmpty(){ 定义指针 L; L=(List)malloc(sizeof(struct LNode)); //申请空间 L->Last=0;//长度置为0 return L;}
函数二:创建并返回一个空的线性表
Position Find( List L, ElementType X ){ if(!L)return ERROR; end if //线性变为空返回error 定义 i=0; for i=0 to i Last { if(L->Data[i]==X) //找到X return i; end if } end for return ERROR;}
函数三:将X插入在位置P并返回true
bool Insert( List L, ElementType X, Position P ){ if(!L) return false; //函数为空 返回false else if(L->Last>=MAXSIZE) { 输出 FULL return false; } //空间已满 else if(P<0||P>L->Last) { 输出 ILLEGAL POSITION return false; } //P指向非法位置 else { 定义 i; for i=L->Last to i>P { L->Data[i]=L->Data[i-1]; //后移 } L->Data[P]=X; L->Last++; return true; } end if}
函数四:将位置P的元素删除
bool Insert( List L, ElementType X, Position P ){ if(!L) return false; //函数为空 返回false else if(L->Last>=MAXSIZE) { 输出 FULL return false; } else if(P<0||P>L->Last) { 输出 ILLEGAL POSITION return false; } else { 定义 i; for i=L->Last to i>P { L->Data[i]=L->Data[i-1]; //后移 } L->Data[P]=X; L->Last++; return true; } end if}bool Delete( List L, Position P ){ if(!L)return false; //函数为空 end if if(P<0||P>=L->Last) { 输出 POSITION P EMPTY return false; } //指向非法位置 end if L->Last--;//长度减一 for i=P to i Last { L->Data[i]=L->Data[i+1];//前移 } end for return true; }
2.1.2代码截图
2.1.3本题PTA提交列表说明。
- Q1:刚开始提交在空表和删除出现错误
- A1:添加了判断L为空时的代码,在四个函数中都有判断L为空的代码
2.2 题目2:链表倒数第m个数
2.2.1设计思路(伪代码)
函数:已知一个带有表头节点的单链表,查找链表中倒数第m个位置上的节点
int Find(LinkList L, int m ){ 定义指针p,q; 定义count=0; p=L->next,q=L->next; while(p!=NULL) //当p不为尾结点 { if(count next; end if p=p->next; } //p一直移动到尾结点,q移动n-m次,即q移动到倒数第m个 end while if(count <=0) //若输入的m大于链表长度或者m<0都非法 return -1; else return q->data; end if}
2.2.2代码截图
2.2.3本题PTA提交列表说明
- Q1:第一次提交出现了段错误
- A1:思考了下如果输入的m大于链表长度或者m为负值都不行,刚开始考虑了m大于链表长度忽略了m<0的情况,改为if(count<m||m<=0)就对了
2.3 题目3:有序链表的插入删除
2.3.1:设计思路(伪代码)
函数一:有序链表插入元素e
void ListInsert(LinkList &L,ElemType e){ 定义两个指针 p,r; r=new LNode; //申请空间 r->data=e; //储存输入的数据e p=L; while(p->next!=NULL) { if(e>p->next->data) p=p->next; else break; end if } end while //寻找数据e应该插入的位置 r->next=p->next; p->next=r; //头插法插入r}
函数二:链表删除元素e
void ListDelete(LinkList &L,ElemType e){ 定义指针 p; p=L; if(p->next==NULL) //若链表为空 return;//直接返回 不执行以下操作 while(p->next!=NULL) //当p不为尾结点 { if(e==p->next->data) break; else p=p->next; }//找e的位置 end while if(p->next==NULL) printf("%d找不到!\n",e); //p移动置尾结点,表示链表中不存在e else { p->next=p->next->next; }删除e所在结点 end if}
2.2.3代码截图
2.3.3本题PTA提交列表说明
- Q1:第一次提交出现答案错误,后来发现是!用成了英文的,晕
- A1:输出“找不到!”的“!”改成中文的
- Q2:出现错误
- A2:加上if(p->next==NULL) return;当链表为空时,直接返回 不执行以下操作
3、阅读代码(-2--2分)
3.1 题目 两个有序 的单链表ha, hb, 请判断链表a是否包含在链表b内
3.2 解题思路
- 首先创建两个有序链表
- 然后由头结点指向链表的开始节点 LinkList pa = ha->next; LinkList pb = hb->next;
- 如果pa与pb相等,那么我们就要继续比较,也就是
if (pa->data == pb->data) { return inclusion(pa, pb); }
else { pb = pb->next; }
- 这是用了递归的方法,还要再考虑递归结束的条件,如果pa一直走,就算是走到了最后也没有出现return 0的状况,则说明a是包含在b中的
3.3 代码截图
3.4 学习体会
运用了上学期学了但是运用不太熟练的递归算法,把递归和链表结合感觉还是难度挺大的,可以再多看些这方面的应用。