为什么没有第三个变量的交换在这里不起作用?
Why Swapping without third variable not working here?
我在写选择排序的c语言代码。如果交换是使用第三个变量完成的,它工作正常但是当我更改交换方法而不使用第三个变量时,如下面的代码注释所示。它显示错误的输出(某些位置为零)。我不明白为什么会这样?
我曾尝试在另一个程序中针对相同类型的条件交换两个没有第三个变量的数字。但它在那里工作正常。但是为什么不在我的选择排序程序中。
#include<stdio.h>
void selectsort(int * ,int);//selection sort function
int main(){
int a[5];
int i,n=5;
for(i=0;i<5;i++)
scanf("%d",&a[i]);
selectsort(a,n);
printf("Sorted Array is:\n");
for(i=0;i<5;i++)
printf("%d\n",a[i]);
}
/* Below is selection sort function definition*/
void selectsort(int*p ,int q){
int i,j,h,temp;
for(i=0;i<q-1;i++){
h=i;
for(j=i+1;j<q;j++){
if(p[h]>p[j]){
h=j;
}
}
/* below code is to swap the two numbers ( p[i] and p[h]) without
using third variable , but it is NOT WORKING here
(giving wrong output) BUT WORKING IF THIRD VARIABLE IS USED.Why?*/
p[i]=p[i]+p[h];
p[h]=p[i]-p[h];
p[i]=p[i]-p[h];
}
}
您的 h
和 i
的值不一定不同。
在这种情况下交换不仅不会交换任何东西而且会弄乱你的记忆。
void selectsort(int*p ,int q){
int i,j,h,temp;
for(i=0;i<q-1;i++){
h=i; // <=== Here you start with identical values
for(j=i+1;j<q;j++){
if(p[h]>p[j]){
h=j; // This may or may not be executed.
}
}
// Here h can still be at same value as i.
// What happens in this case is shown in the comments below:
p[i]=p[i]+p[h]; // p[i]=p[i]+p[i]; ==> p[i] *=2;
p[h]=p[i]-p[h]; // p[i]=p[i]-p[i]; ==> p[i] = 0;
p[i]=p[i]-p[h]; // p[i]=p[i]-p[h]; ==> p[i] = 0;
}
}
您可以在进行交换之前添加类似这样的内容:
if (i==h)
continue;
注:
除了学术案例,我不建议使用这种方法。
没有临时变量的交换有很多缺点:
- 仅适用于整数类型
- 需要处理溢出等问题
- 需要处理相同的存储位置。
- 需要额外的算术运算导致更多的代码和更长的执行时间
- 让读者感到困惑并且更难维护
它也只有一个优点
- 为 1 个变量节省堆栈存储空间。
如果您的目标是让读者感到困惑,那么您应该搜索使用 XOR 而不是算术的版本。 ;)
我在写选择排序的c语言代码。如果交换是使用第三个变量完成的,它工作正常但是当我更改交换方法而不使用第三个变量时,如下面的代码注释所示。它显示错误的输出(某些位置为零)。我不明白为什么会这样?
我曾尝试在另一个程序中针对相同类型的条件交换两个没有第三个变量的数字。但它在那里工作正常。但是为什么不在我的选择排序程序中。
#include<stdio.h>
void selectsort(int * ,int);//selection sort function
int main(){
int a[5];
int i,n=5;
for(i=0;i<5;i++)
scanf("%d",&a[i]);
selectsort(a,n);
printf("Sorted Array is:\n");
for(i=0;i<5;i++)
printf("%d\n",a[i]);
}
/* Below is selection sort function definition*/
void selectsort(int*p ,int q){
int i,j,h,temp;
for(i=0;i<q-1;i++){
h=i;
for(j=i+1;j<q;j++){
if(p[h]>p[j]){
h=j;
}
}
/* below code is to swap the two numbers ( p[i] and p[h]) without
using third variable , but it is NOT WORKING here
(giving wrong output) BUT WORKING IF THIRD VARIABLE IS USED.Why?*/
p[i]=p[i]+p[h];
p[h]=p[i]-p[h];
p[i]=p[i]-p[h];
}
}
您的 h
和 i
的值不一定不同。
在这种情况下交换不仅不会交换任何东西而且会弄乱你的记忆。
void selectsort(int*p ,int q){
int i,j,h,temp;
for(i=0;i<q-1;i++){
h=i; // <=== Here you start with identical values
for(j=i+1;j<q;j++){
if(p[h]>p[j]){
h=j; // This may or may not be executed.
}
}
// Here h can still be at same value as i.
// What happens in this case is shown in the comments below:
p[i]=p[i]+p[h]; // p[i]=p[i]+p[i]; ==> p[i] *=2;
p[h]=p[i]-p[h]; // p[i]=p[i]-p[i]; ==> p[i] = 0;
p[i]=p[i]-p[h]; // p[i]=p[i]-p[h]; ==> p[i] = 0;
}
}
您可以在进行交换之前添加类似这样的内容:
if (i==h)
continue;
注:
除了学术案例,我不建议使用这种方法。 没有临时变量的交换有很多缺点:
- 仅适用于整数类型
- 需要处理溢出等问题
- 需要处理相同的存储位置。
- 需要额外的算术运算导致更多的代码和更长的执行时间
- 让读者感到困惑并且更难维护
它也只有一个优点
- 为 1 个变量节省堆栈存储空间。
如果您的目标是让读者感到困惑,那么您应该搜索使用 XOR 而不是算术的版本。 ;)