免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 7583 | 回复: 8
打印 上一主题 下一主题

[C] 自学c语言过程中,看别人写的代码,有看不懂的地方,怎么解决? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-11-12 16:42 |只看该作者 |倒序浏览
看c programming language 的过程中,看书上的算法实现程序,不明白,是直接跳过去,还是硬着头皮啃下来呢?比如,下面用递归实现快速排序的函数,从swap( v, left, (left + right) / 2)  这句之后,就不懂了。
  1. void qsort(int v[], int left, int right)
  2. {
  3.         int i, last;
  4.         void swap(int v[], int i,int j);
  5.         if(left >= right)
  6.                 return ;
  7.         swap(v, left, (left + right)/2);
  8.         last = left;
  9.         for(i = left +1; i <=right; i++)
  10.         {
  11.                 if(v[i] <v[left])
  12.                         swap(v, ++last, i);
  13.         }
  14.         swap(v,left,last);
  15.         qsort(v, left, last-1);
  16.         qsort(v, last+1, right);
  17. }

  18. void swap(int v[], int i, int j)
  19. {
  20.         int temp;
  21.         temp = v[i];
  22.         v[i] = v[j];
  23.         v[j] = temp;

  24. }
复制代码

论坛徽章:
0
2 [报告]
发表于 2014-11-12 17:42 |只看该作者
很简单,你用vs进行单步调试,画出流程图,基本上就可以很好的 理解了

论坛徽章:
0
3 [报告]
发表于 2014-11-12 17:43 |只看该作者
1 如果你学过数据结构,可以先自己试着写一个,与他的对比,理解的快。
2 如果不懂算法,那还有两个办法:
   A debug,跟进去看每一步变量的数值,看了几个应该就能明白。
   B 假设几个数字,用笔算一下。原理和debug一样。

以这个代码为例,先看懂swap 的功能。
然后,对于,swap(v, left, (left + right)/2);
你假设v只有三个数1,3,2
然后 left = 0, right=2,这样心算也能算出来。

论坛徽章:
0
4 [报告]
发表于 2014-11-12 17:56 |只看该作者

很简单,你用vs进行单步调试,画出流程图,基本上就可以很好的 理解了

论坛徽章:
0
5 [报告]
发表于 2014-11-18 10:32 |只看该作者
自己带了几个数值进去了,观察到for语句的作用是,将大于v[left]的元素右移,直到他们都在v[last]右边。

swap(v,left,last);  将v[left]和v[last]互换,从而实现一次划分。

现在有个问题不明白:

在for循环之前,交换最左v[left]和中间元素v[(left + right)/2]的值有什么作用呢? ( swap(v, left, (left + right)/2);)

好疑惑啊,请哪位大侠帮忙解答下,谢谢。

  1. void qsort(int v[], int left, int right)
  2. {
  3.         int i, last;
  4.         void swap(int v[], int i,int j);
  5.         if(left >= right)                                                /*数目小于2,快速排序结束*/
  6.                 return ;
  7.         swap(v, left, (left + right)/2);                /*将最左和中间元素互换  ----这样做是为什么呢?有什么道理?*/
  8.         last = left;                                                        /*将最左元素的值赋给变量last*/
  9.         for(i = left +1; i <=right; i++)                /*将大于V[left]的数右移*/
  10.         {
  11.                 if(v[i] <v[left])
  12.                         swap(v, ++last, i);
  13.         }
  14.         swap(v,left,last);                                                /*将v[left]移动到这些(大于v[left])数的左边*/
  15.         qsort(v, left, last-1);
  16.         qsort(v, last+1, right);
  17. }

  18. void swap(int v[], int i, int j)                                /*交换v[i]和v[j]的值*/
  19. {
  20.         int temp;
  21.         temp = v[i];
  22.         v[i] = v[j];
  23.         v[j] = temp;

  24. }

复制代码

论坛徽章:
46
2015小元宵徽章
日期:2015-03-06 15:58:18羊年新春福章
日期:2015-04-14 10:37:422015年亚洲杯之阿曼
日期:2015-04-14 10:41:50NBA常规赛纪念章
日期:2015-05-04 22:32:03NBA季后赛大富翁
日期:2015-05-04 22:34:11菠菜明灯
日期:2015-05-04 22:35:49新奥尔良黄蜂
日期:2015-05-04 22:49:2315-16赛季CBA联赛之广夏
日期:2015-12-11 15:02:342015年亚洲杯之巴勒斯坦
日期:2015-03-04 19:56:562015年亚洲杯之阿联酋
日期:2015-03-04 11:19:04休斯顿火箭
日期:2015-03-02 16:32:11纽约尼克斯
日期:2015-03-02 16:09:04
6 [报告]
发表于 2014-11-18 10:52 |只看该作者
多看 多写 多练

论坛徽章:
12
巳蛇
日期:2013-09-16 15:32:242015年辞旧岁徽章
日期:2015-03-03 16:54:152015年亚洲杯之约旦
日期:2015-02-11 14:38:37双鱼座
日期:2015-01-05 11:05:47戌狗
日期:2014-12-08 09:41:18戌狗
日期:2014-08-15 09:29:29双子座
日期:2014-08-05 09:17:17卯兔
日期:2014-06-08 15:32:18巳蛇
日期:2014-01-27 08:47:08白羊座
日期:2013-11-28 21:04:15巨蟹座
日期:2013-11-13 21:58:012015年亚洲杯之科威特
日期:2015-04-17 16:51:51
7 [报告]
发表于 2014-11-18 11:21 |只看该作者
需要补充点基础知识,楼主可以搜一下快速排序,找文章看看基本原理。

论坛徽章:
0
8 [报告]
发表于 2014-11-21 11:25 |只看该作者
书里面写了啊。
Our version of quicksort is not the fastest possible, but it's one of the simplest. We use the middle element of each subarray for partitioning.

你可以尝试用不同位置的element去做partition,比如就用the left element,这个swap就不需要了。

论坛徽章:
5
戌狗
日期:2014-06-09 10:29:10酉鸡
日期:2014-12-01 16:05:27处女座
日期:2015-01-07 18:35:262015亚冠之水原三星
日期:2015-06-03 09:26:222015亚冠之布里斯班狮吼
日期:2015-06-15 10:53:54
9 [报告]
发表于 2014-11-21 18:36 |只看该作者
对于看不懂的代码,个人觉得可以缩小规模一步步来,再结合设计原理重读代码。
那个left你可以理解成一个flag,这个flag的选取会影响算法最坏情况的效率。
因此可以取中,或者random
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP