非常诡异,求高手指教

wk20062006 2010-07-20 04:11:26
void ShellSort(int *list,int length) //希尔排序
{
int i;
int j,m,n;
int temp;
i=length;
while(i>=1)
{
i=i/2;
for(j=0;j<i;j++)
{
for(m=j;m+i<length;m=m+i)
{
n=m+i;
if(list[m]>list[n])
{
temp=list[n];
while(list[m]>temp&&m>0)
{
list[m+i]=list[m];
m=m-i;
}
list[m+i]=temp;
}
m=n-i;
}
}
}
}



那个while循环里(list[m]>temp&&m>0)这样子写的话如要给10000数排序就会报错,但(m>0&&list[m]>temp)反过来的话就不会报错,这是为什么啊(报错是指运行时停止工作,如果给少点数排序如100个数,两个都没事),非常诡异。。。
...全文
172 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
ForestDB 2010-07-22
  • 打赏
  • 举报
回复
帮顶。
houyajin 2010-07-22
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 zhao4zhong1 的回复:]

逻辑短路
&&运算左边为假则不会计算右边
[/Quote]

up
fancanqin 2010-07-22
  • 打赏
  • 举报
回复
&&前面为真,后面就不执行了
小楫轻舟 2010-07-21
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 wk20062006 的回复:]

引用 9 楼 killernan 的回复:
引用 2 楼 lightboat09 的回复:

&amp;amp;&amp;amp;
前面为真,后面就不执行了

+1

不是前面为假才不用判断后面的吗,再说就是不判断后面也无所谓啊,m的值没有改变。
[/Quote]

抱歉,我说错了,
是左边为假,后面就不执行了,
因此当m <= 0 时, 后面就不会判断list[m]>temp
出错就出在m小于0时,如m= -1,则list[-1]会报错
wk20062006 2010-07-21
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 killernan 的回复:]
引用 2 楼 lightboat09 的回复:

&amp;&amp;
前面为真,后面就不执行了

+1
[/Quote]
不是前面为假才不用判断后面的吗,再说就是不判断后面也无所谓啊,m的值没有改变。
kingrain213 2010-07-20
  • 打赏
  • 举报
回复
不是太明白,m为负那块的问题吧?
djjlove_2008 2010-07-20
  • 打赏
  • 举报
回复
这是由于&&本身的行为所决定,我们在刚上C语言课程的时候就知道&& ||有短路求值的行为。
讲到这想你应该也明白了,看这段比较好的希尔排序吧。


/*希尔排序
*将算法 SellInsert 中所有的"dk"改为"1"即为算法 InsertSort,
*反过来说,算法 ShellInsert 可以看成是 InsertSort 的扩展。
*
*由于C语言的数组没有"负数"的下标,
*因此,在dk>1时需对j循环中以防"出界"另作"j>0"的判别,
*即L.r[0] 不再起到"监视哨"的作用,而仅仅作为一个暂存记录的空间。
*/
#include <iostream>
using std::cout;
using std::endl;
using std::string;

// 对顺序表L作一趟增量为dk的希尔排序
void ShellInsert(int *L, int dk){

for(int i=dk+1; i < 9; ++i ){
if( L[i] < L[i-dk] ){ // 将 L[i] 插入有序子表
L[0] = L[i];
L[i] = L[i-dk];
int j = i-2*dk;
for( ; j>0 && L[0] < L[j]; j-=dk ){
L[j+dk] = L[j];// 记录后移
}
L[j+dk] = L[0];// 插入到正确位置
}
}
} // ShellInsert

int main()
{
int li[9] = {2,1,8,5,9,4,7,3,6};//其中L[0]作为临时空间,只是比较L[1...8]
for(int i = 1; i<=9; i++){
cout << li[i-1] << " ";
}
cout << endl;
ShellInsert(li,5);
ShellInsert(li,3);
ShellInsert(li,1);
for(int i = 1; i<=9; i++){
cout << li[i-1] << " ";
}
cout << endl;

system("pause");
return 0;
}


nkluckyfire 2010-07-20
  • 打赏
  • 举报
回复
短路了
liutengfeigo 2010-07-20
  • 打赏
  • 举报
回复
短路原则
hedong0411 2010-07-20
  • 打赏
  • 举报
回复
顶一下
killernan 2010-07-20
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 lightboat09 的回复:]

&&
前面为真,后面就不执行了
[/Quote]
+1
SLSnake 2010-07-20
  • 打赏
  • 举报
回复
10000个数?
你的list能放得下吗?有足够空间不?
如果不行就会出错啊
wk20062006 2010-07-20
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 sdp1031 的回复:]
我记得(m>0&&list[m]>temp)
这个是先检查m>0
如果M>0则进行list[m]>temp的判断

是有顺序的

(list[m]>temp&&m>0)
就正好相反了
[/Quote]

为啥排序的数少点的时候好使,多了就不好使了。。。
赵4老师 2010-07-20
  • 打赏
  • 举报
回复
逻辑短路
&&运算左边为假则不会计算右边
Daniel_31 2010-07-20
  • 打赏
  • 举报
回复
我记得(m>0&&list[m]>temp)
这个是先检查m>0
如果M>0则进行list[m]>temp的判断

是有顺序的

(list[m]>temp&&m>0)
就正好相反了
zqq0714 2010-07-20
  • 打赏
  • 举报
回复
谁知道,同看
selooloo 2010-07-20
  • 打赏
  • 举报
回复
m有可能为负,所以要m>0放在前面,利用条件表达式短路
小楫轻舟 2010-07-20
  • 打赏
  • 举报
回复
&&
前面为真,后面就不执行了
macrojj 2010-07-20
  • 打赏
  • 举报
回复
数组越界

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧