简体   繁体   English

C ++插入排序混乱

[英]C++ Insertion sort confusion

I'm trying to implement insertion sort on my own in C++. 我正在尝试在C ++中自己实现插入排序。 I know there are plenty of examples and I compared my solution with existing ones and don't see why mine isn't working. 我知道有很多示例,并且将我的解决方案与现有的示例进行了比较,但看不到为什么我的解决方案无法正常工作。 I know there are libraries for this but I want to implement it on my own. 我知道有用于此的库,但我想自己实现。 I've got 2 different implementations as shown below ( A - one that works, B - one that doesn't work). 我有两种不同的实现,如下所示( A-一种有效, B-一种无效)。

Here is A - One that does work. 这是A-确实有效。 Nothing new here. 这里没有新内容。

    int myArr[5] = {5,4,3,2,1};

    for (int i = 1; i < 5; i++){

        int j = i - 1;
        int key = myArr[i];

        while(myArr[j] > key && j >= 0){
            myArr[j + 1] = myArr[j];
            j = j - 1;
        }        
        myArr[j + 1] = key;

        //Printing array to see what changed:
        for (size_t k = 0; k < 5; ++k){
            cout << myArr[k] << " ";
        }
        cout << endl;
   }

Sample output from A : A的样本输出:

    4 5 3 2 1 
    3 4 5 2 1 
    2 3 4 5 1 
    1 2 3 4 5

Here is B , something I came up with. 这是B ,我想到了。 B is very similar to A except for the lines I've pointed out, where I chose to use myArr subscript instead of key: BA非常相似,除了我指出的那几行外,我选择使用myArr下标代替key:

    int myArr[5] = {5,4,3,2,1};

    for (int i = 1; i < 5; i++){

        int j = i - 1;
        //int key = myArr[i]; //DIFFERENT FROM **A**


        //************** DIFFERENT FROM A **************
        //I didn't use "key", instead I chose to use myArr[i]
        while(myArr[j] > myArr[i] && j >= 0){
            myArr[j + 1] = myArr[j];
            j = j - 1;
        }

        //************** DIFFERENT FROM A **************
        //Same here: I use myArr[i] instead of key        
        myArr[j + 1] = myArr[i];

        //Printing array to see what changed:
        for (size_t k = 0; k < 5; ++k){
            cout << myArr[k] << " ";
        }
        cout << endl;
   }

Sample output from B : B的样本输出:

    5 5 3 2 1 
    5 5 5 2 1 
    5 5 5 5 1 
    5 5 5 5 5 

I don't understand, the only thing I changed was not storing the current value in a variable. 我不明白,我唯一要做的就是不将当前值存储在变量中。 I know I can easily do that and all will be well but what bothers me is that I don't know why B is incorrect. 我知道我可以轻松地做到这一点,并且一切都会好起来的,但令我困扰的是我不知道为什么B不正确。 Any guidance would be appreciated. 任何指导将不胜感激。

This is a good exercise in walking through the code by hand. 这是一个手工遍历代码的好练习。 What's changed? 有什么变化? key is temporary storage for the value at myArr[i] . keymyArr[i]值的临时存储。 The problem with the seemingly innocuous refactor is the fact that myArr[j + 1] is myArr[i] on the first iteration of the inner loop. 看起来无害的重构的问题在于,在内部循环的第一次迭代中, myArr[j + 1] myArr[i] Notice: 注意:

int j = i - 1;
...
myArr[j + 1] = myArr[j]; // j + 1 === i

which is essentially: 本质上是:

myArr[i] = myArr[j]; // whoops!

Here, we've reassigned myArr[i] to something else instead of copying and storing the value in key . 在这里,我们将myArr[i]重新分配给其他东西,而不是将值复制并存储在key We're losing one element on every outer loop iteration whenever the myArr[i] element isn't already sorted. 每当myArr[i]元素尚未排序时,我们在每次外循环迭代中都会丢失一个元素。

Keep the key variable! 保持key变量!

I will use i = 1 to show why it is working different from what you expect. 我将使用i = 1来说明其工作原理与您期望的不同。

int j = i - 1;

j becomes 0. j变为0。

myArr[j + 1] = myArr[j];

Here myArr[1] is assigned value of myArr[0]. 此处为myArr [1]分配了myArr [0]的值。 This is where the problem lies, as 这就是问题所在,因为

myArr[j + 1] = myArr[i];

assigns value of myArr[0] (modified in previously mentioned line) to myArr[1]. 将myArr [0]的值(在前面提到的行中修改)分配给myArr [1]。

In short, the shifting erases the value to be inserted. 简而言之,移位将删除要插入的值。 That's why you need to copy it to another variable (key in code A). 这就是为什么您需要将其复制到另一个变量(代码A中的键)的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM