Derived data structure and algorithm analysis--c language description Exercise 2.7
In a function int rand (int n) returns a random number between 1-n. How do I get the array a[n] scrambled?
The initial fisher–yates algorithm is to open an array b[n], put the intended a[n] into b[n], the steps are as follows
Set i=0
1. Generate a random number between 1-a.length length K
2, put a[k] to b[i], remove the a[k],i++ in the array A.
3, if a.length>0, go to the 1th step.
The algorithm is to remove the number in a, each time to shift, so the algorithm complexity of O (n^2).
For example an algorithm process is as follows:
| Random number Range |
Random number |
A |
B |
|
|
1 2 3 4 5 6 7 8 |
|
| Random number Range |
Random number |
A |
B |
| 1–8 |
3 |
1 2 3 4 5 6 7 8 |
3 |
| Random number Range |
Random number |
A |
B |
| 1–7 |
4 |
1 2 3 4 5 6 7 8 |
3 5 |
| Random number Range |
Random number |
A |
B |
| 1–6 |
5 |
1 2 3 4 5 6 7 8 |
3 5 7 |
| 1–5 |
3 |
1 2 3 4 5 6 7 8 |
3 5 7 4 |
| 1–4 |
4 |
1 2 3 4 5 6 7 8 |
3 5 7) 4 8 |
| 1–3 |
1 |
1 2 3 4 5 6 7 8 |
3 5 7 4 8 1 |
| 1–2 |
2 |
1 2 3 4 5 6 7 8 |
3 5 7 4 8 1 6 |
|
|
1 2 3 4 5 6 7 8 |
3 5 7 4 8 1 6 2 |
Later the algorithm has improved, not another array, but to exchange array A above the elements to achieve rearrangement.
This algorithm has 2 versions, the same principle:
Version 1:
[CPP]View Plaincopy
- for (int i = n; i>=1;-I.)
- {
- int J=rand (i); //Generate a random number between 1-i
- Exchange (A[i],a[j]); //Exchange A[i],a[j]
- }
Version 2:
[CPP]View Plaincopy
- for (int i = 1; I <= n; ++i)
- {
- int j= (rand (n)/N) * (n-i+1) +i-1; //Generate a random number between i-n
- Exchange (A[i],a[j]); //Exchange A[i],a[j]
A calculation process for version 1 is as follows:
Modern Method[edit]
We ' ll now do the same thing using Durstenfeld's version of the Algorithm:this time, instead of striking out the chosen Nu Mbers and copying them elsewhere, we ' ll swap them with the last number is not yet chosen. We ll start by writing out the numbers from 1 to 8 as before:
| Range |
| Roll
Scratch |
Result |
|
|
1 2 3 4 5 6 7 8 |
|
For your first roll, we roll a random number from 1 to 8:this time it's 6, so we swap the 6th and 8th numbers in the list:
| Range |
| Roll
Scratch |
Result |
| 1–8 |
6 |
1 2 3 4 5 8 7 |
6 |
The next random number we roll from 1 to 7, and turns off to be 2. Thus, we swap the 2nd and 7th numbers and move on:
| Range |
| Roll
Scratch |
Result |
| 1–7 |
2 |
1 7 3 4 5 8 |
2 6 |
The next random number we are from 1 through 6, and just happens to be 6, which means we leave the 6th number in the list ( Which, after the swap above, was now number 8) in place and just move to the next step. Again, we proceed the same the until the permutation is complete:
| Range |
| Roll
Scratch |
Result |
| 1–6 |
6 |
1 7 3) 4 5 |
8 2 6 |
| 1–5 |
1 |
5 7 3 4 |
1 8 2 6 |
| 1–4 |
3 |
5 7 4 |
3 1 8) 2 6 |
| 1–3 |
3 |
5 7 |
4 3 1 8 2 6 |
| 1–2 |
1 |
7 |
5 4 3 1 8 2 6
|
Reference: Http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
2.7 Shuffle algorithm