Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize Insertion Sort #593

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

AryanAhadinia
Copy link

No description provided.

@JackyYin
Copy link

I don't get the advantage of this change.
You can swap the elements when compare the elements, why go through the list again?

@AryanAhadinia
Copy link
Author

AryanAhadinia commented Dec 17, 2020

I don't get the advantage of this change.
You can swap the elements when compare the elements, why go through the list again?

Consider we want to insert 5-th element (value = 2) in correct place in this list:
1, 3, 4, 5, 6, 2, 8, 9, 7 --> 1, 2, 3, 4, 5, 6, 8, 9, 7

In pervious algorithm, we had to swap 4 times, (6, 2) and (5, 2) and (4, 2) and (3, 2). Since each swap needs assignment 2 times as least, we'll have variable assignment 8 times in minimum. In general, if we need swaps k times, we'll have 2 * k assignments.

But in new algorithm in same condition, we shift 3, 4, 5 and 6 then insert 2 in correct index. then we'll have k + 2 assignments which is better than 2 * k

@JackyYin
Copy link

JackyYin commented Dec 17, 2020

I don't get the advantage of this change.
You can swap the elements when compare the elements, why go through the list again?

Consider we want to insert 5-th element (value = 2) in correct place in this list:
1, 3, 4, 5, 6, 2, 8, 9, 7 --> 1, 2, 3, 4, 5, 6, 8, 9, 7

In pervious algorithm, we had to swap 4 times, (6, 2) and (5, 2) and (4, 2) and (3, 2). Since each swap needs assignment 2 times as least, we'll have variable assignment 8 times in minimum. In general, if we need swaps k times, we'll have 2 * k assignments.

But in new algorithm in same condition, we shift 3, 4, 5 and 6 then insert 2 in correct index. then we'll have k + 2 assignments which is better than 2 * k

@AryanAhadinia Thanks for your explaination.
How about this version to avoid the 2 * k assignments also avoid going through the k elements again?

  sort(originalArray) {
    const array = [...originalArray];

    // Go through all array elements...
    for (let i = 0; i < array.length; i += 1) {
      let currentIndex = i;
      let tmp = array[i];

      // Call visiting callback.
      this.callbacks.visitingCallback(array[i]);

      // Go and check if previous elements and greater then current one.
      // If this is the case then swap that elements.
      while (
        currentIndex > 0
        && this.comparator.lessThan(array[currentIndex], array[currentIndex - 1])
      ) {
        // Call visiting callback.
        this.callbacks.visitingCallback(array[currentIndex - 1]);

        // Swap the elements.
        array[currentIndex] = array[currentIndex - 1];

        // Shift current index left.
        currentIndex -= 1;
      }

      array[currentIndex] = tmp;
    }

    return array;
  }

@AryanAhadinia
Copy link
Author

AryanAhadinia commented Dec 17, 2020

Yes, it is correct I think, I'll work on this and I'll commit changes ASAP.

@AryanAhadinia
Copy link
Author

AryanAhadinia commented Dec 17, 2020

I don't get the advantage of this change.
You can swap the elements when compare the elements, why go through the list again?

Consider we want to insert 5-th element (value = 2) in correct place in this list:
1, 3, 4, 5, 6, 2, 8, 9, 7 --> 1, 2, 3, 4, 5, 6, 8, 9, 7
In pervious algorithm, we had to swap 4 times, (6, 2) and (5, 2) and (4, 2) and (3, 2). Since each swap needs assignment 2 times as least, we'll have variable assignment 8 times in minimum. In general, if we need swaps k times, we'll have 2 * k assignments.
But in new algorithm in same condition, we shift 3, 4, 5 and 6 then insert 2 in correct index. then we'll have k + 2 assignments which is better than 2 * k

@AryanAhadinia Thanks for your explaination.
How about this version to avoid the 2 * k assignments also avoid going through the k elements again?

  sort(originalArray) {
    const array = [...originalArray];

    // Go through all array elements...
    for (let i = 0; i < array.length; i += 1) {
      let currentIndex = i;
      let tmp = array[i];

      // Call visiting callback.
      this.callbacks.visitingCallback(array[i]);

      // Go and check if previous elements and greater then current one.
      // If this is the case then swap that elements.
      while (
        currentIndex > 0
        && this.comparator.lessThan(array[currentIndex], array[currentIndex - 1])
      ) {
        // Call visiting callback.
        this.callbacks.visitingCallback(array[currentIndex - 1]);

        // Swap the elements.
        array[currentIndex] = array[currentIndex - 1];

        // Shift current index left.
        currentIndex -= 1;
      }

      array[currentIndex] = tmp;
    }

    return array;
  }

Actually, there is a little mistake in this code, I'll correct this and commit in few seconds.

@AryanAhadinia
Copy link
Author

Now it is optimized!

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants