about counting sort algorithm

会有一股神秘感。 提交于 2019-12-21 06:18:15

问题


I have read a counting sort algorithm which is like this:

Counting Sort(A[1,..n]) //C[1,...k] is the temporary memory and k is the range of integers
   for  i<-- 1 to k
      C[i]<-- 0
   for  j<-- 1 to n
      C[A[j]]<--C[A[j]]+1
   for  i<--2 to k
      C[i]<--C[i]+C[i-1]
   for  j<--n downto 1
      B[C[A[j]]]<--A[j]
      C[A[j]]<--C[A[j]]-1

I want to know that if I change the last for to this:for j<--1 to n ,the algorithm will be correct too???(is there any way to show that with this "for" the algorithm will be correct??? )

also in this way the algorithm is stable too?

thanks


回答1:


The algorithm is correct both ways. It is also stable as you have it right now.

If you change the last for to what you said, it will stop being stable.

Basically, C[i] = how many elements <= i exist after the end of the third for loop. So C[A[j]] gives you the the last position of an element with value A[j] in sorted order, C[A[j]] - 1 the second last position of an element with value A[j] and so on. This is why you decrement the values in C.

Because of this, you have to start iterating your original array in reverse order if you care about stability: so that the last element with value x in your original array gets put first in the new array. Iterating your original array in reverse will guarantee that x is put after all other values equal to x, thus making the algorithm stable.




回答2:


Ok, short explaination of the algorithm:

  1. for loop: initialize the C array with 0 and the size k (the range of integers)
  2. for loop: count the integer and store the number in C
  3. for loop: sum up the total number of values less equal the given one Example: there are five 1, three 2, two 3 => c[1] = 5, c[2] = 8, c[3] = 10
  4. for loop: starting at the end of the A array and putting it to the corresponding C value in the B value and decreasing the value in C

Because you store the last position for the different numbers in the C array, you have to start an the end of the A array, too. If you just work with integers the algorithm would also be correct if you start with j<--1 to n

stability is not given: e.g. the 1s would be in inverse order

Example: (I added indexes to the once, two show the order)

A[1a, 2, 1b]

first for loop

  • C[1] = 0
  • C[2] = 0

second for loop

j=1: A[1] = 1a

C[1] = 1
C[2] = 0

j=2: A[2]=2

C[1] = 1
C[2] = 1

j=3: A[3]=1b

C[1] = 2
C[2] = 1

third for loop

C[2] = 3

fourth for loop

j=1 b[2]=1a c[1]=1

j=2 b[3]=2 c[2]=2

j=3 b[1]=1b c[1]=0

Resulting:

  • b[1] = 1b
  • b[2] = 1a
  • b[3] = 2

=> not stable




回答3:


The algorithm seems to be stable as it is to me.

If you change the last for, then it will still be correct, but won't be stable. (will reverse the order of equal elements).




回答4:


Yes, 1 to n would still sort correctly, but you'll use stability that n downto 1 has.

After the second loop C contains the comulative sum, those values are exactly the indicies of the last element of each number in the final array. That's why going backwards gives stability.

You can get stability for 1 to n too:

Counting Sort(A[1,..n]) //C[1,...k] is the temporary memory and k is the range of integers
   for  i<-- 1 to k
      C[i]<-- 0
   for  j<-- 1 to n
      C[A[j]]<--C[A[j]]+1
   last <-- C[1]
   C[1] <-- 0
   for  i<--2 to k
      tmp <-- C[i]
      C[i]<--C[i-1]+last
      last <-- tmp
   for  j<--n downto 1
      B[C[A[j]]]<--A[j]
      C[A[j]]<--C[A[j]]-1

the cumulative sum gets a bit ugly. But I'm sure this could be done nicer.



来源:https://stackoverflow.com/questions/3076037/about-counting-sort-algorithm

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!