Почему обмен без третьей переменной здесь не работает? - PullRequest
0 голосов
/ 17 мая 2019

Я писал код языка 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];
}
}

1 Ответ

2 голосов
/ 17 мая 2019

Ваши значения 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 вместо арифметики.;)

...