emm,之前有些总结,比如第一章放在csdn了,就po网址吧,不再复制过来了。(好懒)
第一章的一些基本概念,包括ADT、时间复杂度、空间复杂度啥的:https://blog.csdn.net/weixin_43314579/article/details/88045149
数组元素过多导致数组爆了:https://blog.csdn.net/weixin_43314579/article/details/88141451
-----------------------------------------------------------------
来说说第二章,更为具体地学习了线性表,包括顺序表和链表以及其初始化、创建和输出。
然后搞明白了一点额外的知识点。
形参的种类及其能否改变实参:https://blog.csdn.net/weixin_43314579/article/details/88381831
做PTA的时候用new报错了,发现只有C没有C++的编译器,查了资料发现new是C++的关键字,在C中动态分配空间需要用到malloc函数
https://www.cnblogs.com/luoyang0515/p/10529761.html
哦对了,PTA更新后我就不喜欢了,还是老版本好...
不扯了,其实链表啥的还算能理解,但是用不好。特别是再加上排序、删除等功能,书没怎么看代码也没打过,有点虚。
很多时候会把指针和结点本身搞混。比如我定义了个指针p,指向某个结点。
p本身是指针啊,它代表了它指向的那个结点。
结点还有个指针域p->next也是指针啊,p->next又表示下个结点。
但p->next说是指向下个结点,是指向结点呢还是结点的数据域呢?
其实细想还是可以相同的,但总是一下子反应不过来。
说白了就是,指针,结点,傻傻分不清楚。
虽然链表和顺序表相比更难,但是也好用吧,毕竟顺序表的优势只是体现在按下标查找,在其他方面要么差不多,比如按值查找;要么就是链表强,比如进行增删查改。
至于算法,真的是个好东西,在这里细致讲讲。
那题十万个数据的实践题,一开始用for循环嵌套for循环,遍历两个数组,把每个数一一比较一遍....
1 for (int i = 0; i < m; i++) { //遍历a数组,将a数组的每个数与b数组中的每个数比较 2 3 for (int j = 0; j < n; j++) { 4 if (a[i] == b[j]) { 5 c[num] = a[i]; 6 num++; 7 } 8 } 9 }
这能不超时?思前想后我想到个办法,就先把数组非降序排序,这样一旦发现相同的数就不用从头扫描,接着往下就行了。
1 for (int i = 0; i < m; i++) { //遍历a数组,将a数组的每个数与b数组中的每个数比较,若a[i]==b[j],那么a[i+1]从b[j+1]开始比较 2 for (int j = temp; j < n; j++) { 3 if (a[i] == b[j]) { 4 c[num] = a[i]; 5 temp = j + 1; 6 num++; 7 break; 8 } 9 } 10 }
过了吗?太天真了,当然没有。虽然第三个测试点的1万个数据的时间减少了将近一半,但由于还是两个for循环嵌套,时间复杂度没变,十万个数据还是挂了....
然后我么得办法了...直到上课讲到两个集合合并的时候采用排序-比较-提取的方法,用一个for循环就行了。这两题很相似啊,前面都一样,只要改一下提取的条件就行了,只用提取相同的数。
1 for (int i = 0, j = 0; i < m&&j<n; ) { //a[i]与b[j]比较,因为ab都排序了。如果a大,那么a和b的下一个比;如果a小,那么b和a的下一个比。相同则记录。 2 if (a[i] > b[j]) { 3 j++; 4 continue; 5 } 6 else if (a[i] < b[j]) { 7 i++; 8 continue; 9 } 10 else { 11 c[num] = a[i]; 12 num++; 13 i++; 14 j++; 15 continue; 16 } 17 }
于是,成功降低时间复杂度后,终于过了这题。
综上所述,好的算法很强大,只是你想的想不到的问题....这门课真难哇
虽然目前的问题基本都能通过网上查找解决,但我还有些点没涉及到,比如把动态申请的空间释放等方法用到程序中。希望在今后的学习中能涉及的更广,将学到的用上,学以致用,学有所用,才算真正学到东西了。