What is the significance of storing the array length in the selection sort algorithm?

The code snippet below is taken from the Grokking algorithm book:

const findSmallestIndex = (array) => {
  let smallestElement = array[0]; // Stores the smallest value
  let smallestIndex = 0; // Stores the index of the smallest value

  for (let i = 1; i < array.length; i++) {
    if (array[i] < smallestElement) {
      smallestElement = array[i];
      smallestIndex = i;
    }
  }

  return smallestIndex;
};

// A function to sort the array using selection sort
const selectionSort = (array) => {
  const sortedArray = [];
  const length = array.length;

  for (let i = 0; i < length; i++) {
    // Finds the smallest element in the given array 
    const smallestIndex = findSmallestIndex(array);
    // Adds the smallest element to new array
    sortedArray.push(array.splice(smallestIndex, 1)[0]);
  }

  return sortedArray;
};

console.log(selectionSort([5, 3, 6, 2, 10])); // [2, 3, 5, 6, 10]

In the selectionSort function, it was necessary to store the array's length in a variable to make it work correctly. Attempting to avoid storing the length in a variable caused issues:

const selectionSort = (array) => {
  const sortedArray = [];

  for (let i = 0; i < array.length; i++) {
    // Finds the smallest element in the given array 
    const smallestIndex = findSmallestIndex(array);
    // Adds the smallest element to new array
    sortedArray.push(array.splice(smallestIndex, 1)[0]);
  }

  return sortedArray;
};

console.log(selectionSort([5, 3, 6, 2, 10])); // [2, 3, 5]

The issue may lie with the splice method as it reduces the array's length during each iteration. Although the index might not be crucial in this context, it could potentially be causing the problem!

Answer №1

When you remove an element from the original array in your code, each iteration incrementing i by one while also decreasing the length of the array with splice, i and array.length get closer together by 2 instead of 1. This results in only sorting half of the elements into sortedArray.

By first copying const length = array.length;, the variable length remains unaffected inside the loop. This way, with i++ increasing i by 1 on every iteration, the number of loops is equal to the original array length, ensuring that every element gets sorted.

It's worth noting that your algorithm sorts into a new array but leaves the original array empty, which may not be desired. A sorting algorithm should either sort the array in-place or return a new sorted array without changing the original. You can address this by creating a copy of array at the beginning of your function so the algorithm alters the duplicate rather than the original array.

Answer №2

Sharing this insight here because the existing implementation, which seems to be derived from an algorithms text, is unnecessarily complex and inefficient.

function selectionSort(array) {
  function smallestIndex(start) {
    let si = start;
    for (let i = start + 1; i < array.length; ++i) {
      if (array[i] < array[si])
        si = i;
    }
    return si;
  }

  for (let i = 0; i < array.length; i++) {
    let index = smallestIndex(i), t;
    // swap value into current slot
    t = array[index];
    array[index] = array[i];
    array[i] = t;
  }
  return array;
}

In this version, the smallestIndex() function now takes a starting position as an argument. This allows it to identify the index of the smallest value in the remaining portion of the array. Initially, this will be the smallest value in the entire array. Subsequently, this smallest value is exchanged with the element at the current starting position. As a result, after the first iteration, the element at index 0 becomes the smallest value in the whole array.

During the next iteration, the search for the index commences from 1, enabling the process to locate the second smallest value from the original array and place it in position 1.

This procedure unfolds throughout the array without necessitating the creation of new arrays or calls to Array methods that operate in linear time.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the method for altering the look of a button using JavaScript?

As a beginner in web development, I have a question. Typically, I know how to style the submit button when it's created in the HTML page using CSS. However, I'm wondering if it's possible to apply CSS styling to the JavaScript block instead. ...

Is it possible to easily remove the trailing comma, period, or other punctuation from the end when using the JavaScript pug template engine?

Apologies for the confusion in my question wording. To illustrate, here is an example piece of code: p #[strong Genre]&nbsp; each val in book.genre a(href = val.url) #{val.name} | , I am trying to figure out how to format a comma ...

Turn off automatic zooming for mobile device input

One common issue observed in mobile browsers is that they tend to zoom in on an input field or select drop-down when focused. After exploring various solutions, the most elegant one I came across involves setting the font-size of the input field to 16px. W ...

Is the Vue "Unchecking" feature not properly deleting data from the array?

I need to update my function to handle the removal of a networkAudience when its corresponding checkbox is unchecked. Currently, the networkAudience is being added to the array when checked, but not removed when unchecked. What changes should I make to en ...

Sending a parameter from a click event to a function

Struggling with a jQuery and AJAX issue all night. I am new to both and trying to implement something similar to this example. I have an edit button with the ID stored in a data-ID attribute. Here's an example of what my button looks like: <butto ...

Utilize the same variable within a React functional component across multiple components

Within a React functional component, I am utilizing the following constant: const superHeroPowers = [ { name: 'Superman', status: superManPowerList }, { name: 'Batman', status: batmanPowerList }, { name: 'Wonder Woman&a ...

Simple steps for calling a lit component in React using the ScopedElementsMixin:1. Import

Looking to incorporate the web component Button (lit) into my project using a similar tag approach. For instance, if the <button-test> tag is present on the website, then it should be converted to <button-test-12345>. This is why ScopedElements ...

Unable to display a custom image as a check mark on a checkbox

I tried to add some custom CSS to style the images on my checkmark boxes. The goal was to display an image with a checkmark when clicked, but unfortunately, it's not working as expected during testing. For this task, I utilized CSS and HTML from a he ...

Automating the selection of a drop down based on a condition in Angular 2: A step-by-step guide

I'm facing an issue with a drop-down menu where no default value is selected. On my homepage, I need to automatically select an option based on query parameters. I've attempted various methods but none have been successful. Below is the code snip ...

A common error known as a segmentation fault occurs when attempting to access an array within a Fortran

My fortran program is experiencing issues with a subroutine causing a segmentation fault. The fault occurs after executing line 1434 and printing the message: i: 115 256 2 Segmentation fault (core dumped) The program has pa ...

Ensuring Consistent Height for Bootstrap Card Headers

I am currently working with bootstrap cards on two different web pages. The challenge I am facing is that on one page, the header text has a fixed height so I can easily match their card-header height using min-height. However, on the second page, the card ...

Is there a problem with Framer Motion exit and AnimatePresence in Next.js?

Why isn't my exit prop or AnimatePresence working as expected? This is my custom variant: const imgVariant = { initial: { opacity: 0, y: -100, }, animate: { opacity: 1, y: 0, transition: { type: " ...

Infrastructural setup for multiplayer games using Socket.io

var connectionHandler = function(socket) { var player = null; socket.on('login', function(data) { player = { data: okeyServer.playerJoin(data), socket: socket }; socket.emit('welcome'); }); socket. ...

Forcing Reload of HTML5 Video to Avoid Caching Issues

Is there a way to instruct the HTML5 Video tag to stream the video chunks on demand/load without caching them on the client side? Essentially, how can I prevent the browser from storing the HTML5 video in its cache? My main objective is to have the video ...

My Vuex component is not updating when the state changes

My component is not reacting to Vuex store changes when I edit an existing element, even though it works fine when adding a new element. After hours of debugging and trying everything, I've realized that it might have something to do with deep watchin ...

Guide to verifying the fourth character in the Vuejs confirm password field

password field validation rules: <!-- Password --> <label class="form__group is-required"> <span class="form__label">Password</span> <input class="form__input" type="password" name="for ...

The chart refreshes whenever there is a change in the component's state

Whenever I click the button to use the changeState method, the state changes and the MoreInfo component appears. However, the chart is being drawn again as shown in this GIF: Below is the code snippet: import React from 'react' import './Ho ...

I am unable to input just one numerical value into my function

I am encountering an issue with my function that calls another function. The problem arises when inputting single numbers in the prompt; I have to append a letter like (a1, a2, a3) for it to function correctly. The function "PrintSelectedToPDF" works smoo ...

Dynamically generating an array and seamlessly inserting it into a MySQL database using PHP

I am looking to generate an array that will be used in an insert query, similar to the following: $data=array( 'db_field1'=>$value, 'db_field2'=>$value, 'db_field3'=>$value, and so forth ); $this->db->inser ...

What is the method for adding an HTML tag that includes an md-checkbox and md-icon?

I am currently utilizing angular material and angular js to dynamically add a new HTML div when a certain function is triggered from the view. Here is my view setup: <div id = "main_row" ng-click="defCtrl.submit()"> </div> This is wh ...