⏳ 倒计时 110 天 ⏳
对很多同学来说,数据结构本身感觉学习起来还行,比较麻烦的就是代码,而尤其是代码题——自己写代码。今天跟大家分享一下,怎么样才能搞定代码题。
开始做代码题之前你应该:C/C++知识已掌握(知识点部分就行),关于本节知识点思想、代码已掌握。
第一,我们要明确代码题不是全部都需要学,应该根据学校真题确定。一是代码题的量一般不会太大,几乎就是两三道,二是着重考察的知识点也是有所区别的。比如408来说,着重点就在线性表和树相关的代码题。比如2019年的408真题:
第二,代码题解题核心:积累+创新。到上考场的时候,可以说积累达到70-80%,只有20-30%的创新;甚至有的人可以达到100%积累——全是原题,当然这要看学校是怎么出题的。特点是开始难,约到后面越轻松。因为刚开始的时候,你并没有什么积累,出现一道题,可以说100%创新,这当然很难,但是你要端正态度,第一轮苦逼积累,第二轮享受成就感,第三轮100%积累,上考场70%积累+30%创新。比如下面这段代码,是让你删除最小值,其中会涉及到找最小值findMin,而findMin你之前已经积累过,那不就是非常easy了。
/**
* 用引用变量value返回最小元素值
* 这里L必须用引用,否则数组、length将会被复制一份
*/
bool delMin(SqList &L, ElemType &value) {
// 空表判断
if(L.length == 0) {
return false;
}
// 找到最小元素,最小元素下标
int pos;
// 积累过的代码,对你来说就是这么一句话,当然你自己得把这个函数写完整
findMin(L, value, pos);
// 最后一位
int end = L.length-1;
// 执行覆盖
L.data[pos] = L.data[end];
// 表长减一
L.length--;
// 成功
return true;
}
第三,代码题练习步骤。一,得出解题思想。这里所说的思想是编程思想,和正常人的思想是有区别的,不过你学了C/C++语言,也上了知识点的课,可以说基本编程思维已经有了。当然我们一边做题还会一边继续形成自己的编程思想。
在数组中找最小值的编程思想:
① 申请变量value, pos, 初始化value为顺序表第一个元素的值,pos = 0。
② 从顺序表第二位开始遍历,遇见比value更小的元素,就更新value为当前元素,pos为当前元素的下标
二,自己动手写代码。尽量自己去写,总之想过了,想不出来就停止;写完了当然也停止。基础很好的人:直接手写代码就行。基础不好的人:不经历上机编写代码、调试、运行,那么能力是提升不上来的。从头开始写需要建立测试环境,这会浪费你大量时间,划不来。现在测试环境将由我为你搭建起来,你只需进行核心代码编写、调试、运行。三,查看标准答案。目的是积累标准答案的思想,积累标准答案的代码。而积累也分为全积累:针对本道题,部分积累:针对其中的一些代码片段,比如找最小值。直接积累下面的代码。
/**
* 找最小元素,及其下标,用引用返回
*/
void findMin(SqList &L, ElemType &value, int &pos) {
// 表中第一个元素的值
value = L.data[0];
// 表中第一个元素的下标
pos = 0;
for(int i = 1; // 从表中第二位开始
i // 遇见更小的,更新
if(L.data[i] value) {
value = L.data[i];
pos = i;
}
}
// 退出之后
// pos:是最小元素在数组中的下标
// value:是最小元素的值
}
第四,关于时间复杂度的问题。对于题目有时间复杂要求的题目,这种不要太纠结了,一是复杂度达不到也扣不了很多分(一般就扣个2、3分);二是这完全看个人创造能力+积累程度。我们能做的就是尽量积累多一些。比如:
方法一:
文字思想:
①用额外存储空间temp[n],存储A中各个元素出现的频次,temp[k]的值表示k在数组A中出现的次数。
②统计temp中出现次数最多的元素,按题目要求进行返回。
/**
* @数据结构考研冯强
* 计算主元。
* 主元:A中出现次数最多的元素,且总数超过表长一半
* 成功:返回主元值;
* 失败:返回-1。
*/
int getMainElemBySpace(int A[], int n) {
// 题知:元素∈[0,n)
// 构建大小为n的辅助数组
int *temp = (int *)malloc(sizeof(int) * n);
// 初始化数组所有元素值为0
memset(temp, 0, sizeof(int) * n);
// 统计A中各个元素的值,放到数组temp中
// 统计结束之后:temp[k]的值表示k在数组A中出现的次数
for(int i = 0; i temp[A[i]]++;
}
// 在temp中找最大值
int maxCount = temp[0];
int maxCountValue = 0;
for(int i = 1; i if(temp[i] > maxCount) {
maxCount = temp[i];
maxCountValue = i;
}
}
// 返回结果
return maxCount > n/2 ? maxCountValue : -1;
// @数据结构考研冯强
}
复杂度:
时间O(n),空间O(n),扣两三分。
方法二:
①使用排序算法进行排序,最快为O(nlog$_2$n)。
②在排好序的序列中统计出现次数最多的元素,按题目要求返回。
/**
* 进性一趟快排
* 反对枢轴最终位置的下标
*/
int partition(int A[], int low, int high) {
// 选表中第一个元素作为枢轴值
int pivot = A[low];
// 进行移动
while(low // 考察右侧,找到第一个比pivot小的元素下标
while(low = pivot) {
--high;
}
// 放到表头去
A[low] = A[high];
// 考察左侧,找到第一个比pivot大的元素下标
while(low ++low;
}
// 放到表尾去
A[high] = A[low];
}
// 将枢轴放到最终位置
A[low] = pivot;
return low;
}
// 全体快排
void quickSort(int A[], int low, int high) {
// 执行条件
if(low // 进行一次快排
int pivotPos = partition(A, low, high);
// 递归地对左子表快排
quickSort(A, low, pivotPos - 1);
// 递归地对右子表快排
quickSort(A, pivotPos + 1, high);
}
}
/**
* @数据结构考研冯强
* 计算主元。
* 主元:A中出现次数最多的元素,且总数超过表长一半
* 成功:返回主元值;
* 失败:返回-1。
*/
int getMainElemBySort(int A[], int n) {
// 进行快排:从小到大
quickSort(A, 0, n-1);
// 找出现次数最多的元素
int preIndex = 0, currIndex = 1; // 下标
int maxCount = 0; // 次数
int maxCountValue = -1; // 值
while (currIndex 1) {
// 相同值元素统计完毕
if((A[preIndex] != A[currIndex]) || currIndex == n) {
// 比较是否出现了次数更多的元素:出现了就更新
if(currIndex - preIndex > maxCount) {
maxCount = currIndex - preIndex;
maxCountValue = A[preIndex];
}
// 统计下一个元素
preIndex = currIndex;
}
currIndex++;
}
return maxCount > n/2 ? maxCountValue : -1;
// @数据结构考研冯强
}
复杂度:
时间为排序算法时间复杂度,最快O(nlog$_2$n),扣两三分;空间复杂度也为排序算法消耗的空间复杂度,快排为O(log$_2$n)。扣两三分。
方法三:
文字思想:
①出现次数最多的数记录为maxCountValue,其出现次数记录为maxCount。
②初始化maxCountValue为第一个元素,初始化maxCount为1。
③从第二个元素开始遍历:当前元素等于maxCountValue,则maxCount++;当前元素不等于maxCountValue,则maxCount--,如果maxCount被减到0了,则更新maxCountValue为当前元素值,且maxCount更新为1;直到处理完所有元素。
④主元是过半的。这时候再遍历一次表,看看maxCountValue是否过半,过半则maxCountValue是主元,否则无主元。
int getMainElemCount(int A[], int n) {
int maxCountValue = A[0], // 初始化为A[0]
maxCount = 1; // 初始化出现次数为1
// 处理剩余元素
for(int i = 1; i // 仍然相等,则计数+1
if(A[i] == maxCountValue) {
maxCount++;
// 不相等
} else {
// 减去一后等于0,则更新
// 减去一后不等于0,则什么也不做
if((--maxCount) <= 0) {
maxCountValue = A[i];
maxCount = 1;
}
}
}
// 判断是否是主元
maxCount= 0;
for(int i = 0; i if(A[i] == maxCountValue) {
maxCount++;
}
}
// 超过一半才有主元
return maxCount > n/2?maxCountValue:-1;
}
时间复杂度为O(n),空间复杂度为O(1)。满分。
以上就是关于代码题的练习方法,希望大家取得一个不错的成绩哦~
推荐阅读
▲ 八月计算机考研大事件回顾【第三期】
▲【21计算机考研】11所院校公布最新招生信息,四六级成绩本周出!
▲【21计算机考研】14所院校最新招生简章、科目变更、专业目录!
▲【21计算机考研】408改考、专业目录、停招、考试大纲汇总(第1期)
每日福利
?快参与评论吧!揪1位点赞数最多的童鞋,免费赠送数据结构考研刷题小程序学员资格(含完整解析、收藏功能)冯强计算机与软工考研刷题
![4974892e2c4354300d558ddf886056db.gif](https://img-blog.csdnimg.cn/img_convert/4974892e2c4354300d558ddf886056db.gif)
▲ 计算机/软件/网络考研交流总QQ群:971734133
▲ 南航计算机/软件考研交流QQ群(有学校资料):1138098949
▲ 西南大学计算机/软件考研交流QQ群(有学校资料):1128814897
▲ 诚邀各大高校大佬共同创建更多学校QQ群
▲计算机/软件/网络考研交流微信群
若群已满,请添加小助手微信,拉你们进群鸭~
?