简体   繁体   中英

Javascript Counting Sort implementation

Is this a good way or the best way to implement Counting Sort in Javascript? Can't find a standard JS Counting Sort example.

function countingSort(arr){
  var helper = []; // This helper will note how many times each number appeared in the arr
                   // Since JS arrary is an object and elements are not continuously stored, helper's Space Complexity minor that n
  for(var i = 0; i<arr.length; i++){
    if(!helper[arr[i]]){
        helper[arr[i]] = 1;
    }else{
        helper[arr[i]] += 1;
    }
  }

  var newArr = []; 
  for(i in helper){
    while(helper[i]>0){
        newArr.push(parseInt(i));
        helper[i]--;
    }
  }
  return newArr; 
}

var arr = [5,4,3,2,1,0];
console.log(countingSort(arr)); // [0, 1, 2, 3, 4, 5]

The code is correct, with some comments:

  • In general, the use of for..in on arrays is discouraged, but unless you define enumerable properties on the Array prototype (which is a bad idea anyway), your use of it is fine to me

  • You could improve the part where you loop to push the same value several times. This can be done in "one" go by concatenating Array(helper[i]).fill(i) to the results.

You could also use reduce to make the function more functional programming style. In the extreme, it could look like this:

 function countingSort(arr){ return arr.reduce( (acc, v) => (acc[v] = (acc[v] || 0) + 1, acc), [] ) .reduce( (acc, n, i) => acc.concat(Array(n).fill(i)), [] ); } // Sample run: var arr = [5,4,3,2,1,0]; console.log(countingSort(arr)); // [0, 1, 2, 3, 4, 5]

counting sort is to start by initializing an auxiliary array of length k, that will hold the count of each number. Each index has an initial value of 0. After that, you loop through the input array and increase the “count” for each value by 1 every time you encounter that number in the array. Now, the auxiliary array holds the number of times each element is in the input array. The last step is to loop from the minimum value to the maximum value. In this loop, you'll loop through each corresponding value in the count array, and add the elements who's count is greater than 0 to the array in sequential order. You add each item by using a secondary incrementing variable (eg if we're using “i” to loop from the min to max values, then we'll use “j” to loop through the array), then increasing that second incrementing variable so the next item is placed in the next highest array index, and finally you decrease the value of the current item in the count array so that you don't add too many of elements that value.

 const countingSort = (arr, min, max) => { const count = {}; // First populate the count object for (let i = min; i <= max; i++) { count[i] = 0; } for (let i = 0; i < arr.length; i++) { count[arr[i]] += 1; } /* Now, count is indexed by numbers, with values corresponding to occurrences, eg: * { * 3: 1, * 4: 0, * 5: 2, * 6: 1, * 7: 0, * 8: 0, * 9: 1 * } */ // Then, iterate over count's properties from min to max: const sortedArr = []; for (let i = min; i <= max; i++) { while (count[i] > 0) { sortedArr.push(i); count[i]--; } } return sortedArr; }; console.log(countingSort([3, 6, 5, 5, 9], 3, 9));

const countingSort = (arr, min, max) => {
    
  let counters = [...Array(max+1)].map(e => 0);
  let result = []

  for(let i = min; i < max; i++){
      counters[arr[i]] += 1
  }
  
  for(let j = min; j <= max; j++){
    while( counters[j] > 0){
      result.push(j)
      counters[j]--
    }
  }
  
  return result
}

 const countingSort = (arr, min, max) => { const count = {}; // First populate the count object for (let i = min; i <= max; i++) { count[i] = 0; } for (let i = 0; i < arr.length; i++) { count[arr[i]] += 1; } /* Now, count is indexed by numbers, with values corresponding to occurrences, eg: * { * 3: 1, * 4: 0, * 5: 2, * 6: 1, * 7: 0, * 8: 0, * 9: 1 * } */ // Then, iterate over count's properties from min to max: const sortedArr = []; for (let i = min; i <= max; i++) { while (count[i] > 0) { sortedArr.push(i); count[i]--; } } return sortedArr; }; console.log(countingSort([3, 6, 5, 5, 9], 3, 9));

 const countingSort = (arr, min, max) => { const count = {}; // First populate the count object for (let i = min; i <= max; i++) { count[i] = 0; } for (let i = 0; i < arr.length; i++) { count[arr[i]] += 1; } /* Now, count is indexed by numbers, with values corresponding to occurrences, eg: * { * 3: 1, * 4: 0, * 5: 2, * 6: 1, * 7: 0, * 8: 0, * 9: 1 * } */ // Then, iterate over count's properties from min to max: const sortedArr = []; for (let i = min; i <= max; i++) { while (count[i] > 0) { sortedArr.push(i); count[i]--; } } return sortedArr; }; console.log(countingSort([3, 6, 5, 5, 9], 3, 9));

 let a = [2, 1, 1, 0, 2, 5, 4, 0, 2, 8, 7, 7, 9, 2, 0, 1, 9]; let max = Math.max(...a); let min = Math.min(...a); function countingSort(arr) { const count = []; for (let i = min; i <= max; i++) { count[i] = 0; } for (let i = 0; i < arr.length; i++) { count[arr[i]]++; } const sortedArr = []; for (let i = min; i <= max; i++) { while (count[i] > 0) { sortedArr.push(i); count[i]--; } } return sortedArr; } console.log(countingSort(a));

The simplest way to solve this problem you write like this:

const range = (start, stop, step) => {
    if (typeof stop == "undefined") {
      stop = start;
      start = 0;
       }
     if (typeof step == "undefined") step = 1;

  if ((step > 0 && start >= stop) || (step < 0 && start <= stop)) return [];

     let result = [];
     for (let i = start; step > 0 ? i < stop : i > stop; i += step) 
     result.push(i);
  return result;
};

const numbers = [1, 2, 2, 2, 1, 3, 3, 1, 2, 4, 5];
const max = Math.max.apply(Math, numbers);

let count = Array.apply(null, Array(max + 1)).map(() => 0);
for (x of numbers)
    count[x] += 1;

let arr = [];
for (x in range(max + 1))
  for (i in range(count[x]))
    arr.push(parseInt([x]));

console.log(arr);

Counting Sort — Perfect when you have psoitive integers to sort

Counting Sort for Unique Integer Values

function countingUniqueSort(arr)
{
  // set 1 for the index which is there in the input array
  const count = [];
  for (let i=0; i < arr.length; i++) {
    count[arr[i]] = 1;
  }
  // set indices over input array in order
  let j = 0;
  for (i=0; i<=count.length; i++) {
      if (count[i] === 1) {
        arr[j] = i;
        j++;
      }
  }
  return arr;
}

Counting Sort for possibly duplicate Integer Values

function countingSort(arr)
{
  // increase the value at the index which is there in the input array
  const count = [];
  for (let i=0; i < arr.length; i++) {
    if (count[arr[i]] > 0) {
      count[arr[i]]++;
    } else {
      count[arr[i]] = 1;
    }
  }
  // set indices over input array in order
  let j = 0;
  let k = 0;
  for (i=0; i<=count.length; i++) {
      k = count[i];
      while (k > 0) {
        arr[j] = i;
        j++;
        k--;
      }
  }
  return arr;
}

Test Input

console.log(`Original Array of Unique Elements: ${[3, 2, 5, 4, 8, 7]}`); 
console.log(`Sorted Array of Unique Elements: ${countingUniqueSort([3, 2, 5, 4, 8, 7])}`);

console.log(`Original Array Elements: ${[3, 2, 5, 5, 4, 8, 7]}`); 
console.log(`Sorted Array Elements: ${countingSort([3, 2, 5, 5, 4, 8, 7])}`);

Output

Original Array of Unique Elements: 3,2,5,4,8,7
Sorted Array of Unique Elements: 2,3,4,5,7,8
Original Array Elements: 3,2,5,5,4,8,7
Sorted Array Elements: 2,3,4,5,5,7,8

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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