Jump to content

Dutch national flag problem: Difference between revisions

From Wikipedia, the free encyclopedia
Content deleted Content added
Ledrug (talk | contribs)
Remove dubious critique. The interesting thing was efficiency, and "intent" is not an objective matter: how "intentful" is any quicksort code?
Line 66: Line 66:
}
}
</source>
</source>

== Critique ==

The array based algorithm is a good example on how optimization can obfuscate intent. It is focused on 'how' things are done and not on 'what' is done. A much clearer Θ(n) approach is to use 3 filter operations and two concatenations. This might be preferable most of the time, even if real runtime performance suffers.

List based example in [[Haskell_(programming_language) | Haskell]]:
<source lang="Haskell">
data Stone = R | W | B deriving (Eq)
dutchFlagSort :: [Stone] -> [Stone]
dutchFlagSort xs = (filter (== R) xs) ++ (filter (== W) xs) ++ (filter (== B) xs)
</source>

An even better version would choose a built-in sort function parameterized by a comparison operator. Used on arrays this can restore the in-place property as well.


==See also==
==See also==

Revision as of 08:08, 30 August 2012

The Dutch national flag

The Dutch national flag problem is a famous computer science related programming problem proposed by Edsger Dijkstra. The flag of the Netherlands consists of three colours: red, white and blue. Given balls of these three colours arranged randomly in a line (the actual number of balls does not matter), the task is to arrange them such that all balls of the same colour are together and their collective colour groups are in the correct order.

The array case

This problem can also be viewed in terms of rearranging elements of an array. Suppose each of the possible elements could be classified into exactly one of three categories (bottom, middle, and top). For example, if all elements are in 0 ... 1, the bottom could be defined as elements in 0 ... 0.1 (not including 0.1), the middle as 0.1 ... 0.3 (not including 0.3) and the top as 0.3 and greater. (The choice of these values illustrates that the categories need not be equal ranges). The problem is then to produce an array such that all "bottom" elements come before (have an index less than the index of) all "middle" elements, which come before all "top" elements. And to do this sorting without later moving any element after placing it in the array.

One algorithm is to have the top group grow down from the top of the array, the bottom group grow up from the bottom, and keep the middle group just above the bottom. The algorithm stores the locations just below the top group, just above the bottom, and just above the middle in three indexes. At each step, examine the element just above the middle. If it belongs to the top group, swap it with the element just below the top. If it belongs in the bottom, swap it with the element just above the bottom. If it is in the middle, leave it. Update the appropriate index. Complexity is Θ(n) moves and examinations.

Using this algorithm in quicksort to partition elements, with the middle group being elements equal to the pivot, lets quicksort avoid "resorting" elements that equal the pivot.

Here is an example in C++:

void threeWayPartition(int data[], int size, int low, int high) {
  int p = -1;
  int q = size;
  for (int i = 0; i < q;) {
    if (data[i] < low) {
      swap(data[i], data[++p]);
      ++i;
    } else if (data[i] >= high) {
      swap(data[i], data[--q]);
    } else {
      ++i;
    }
  }
}

Example in Java:

public class DutchNationalFlag {
 
    public static void dutchFlagSort(int[] inputArray, int p, int k) {
    	int p_index = 0;
        int k_index = inputArray.length - 1;
    	for(int i = 0; i <= k_index;){
    		if(arr[i] < p){
    			swap(arr, i, p_index);
    			p_index++;
    			i++;
    		}
    		else if(arr[i] >= k){
    			swap(arr, i, k_index);
    			k_index--;
    		}
    		else{
    			i++;
    		}
    	}

    }
    
    public static void swap(int[] arr, int i, int j){
    	int temp = arr[i];
    	arr[i] = arr[j];
    	arr[j] = temp;
    }

 }

See also

  • Public Domain This article incorporates public domain material from Paul E. Black. "Dutch national flag". Dictionary of Algorithms and Data Structures. NIST.
  • Explanation and example execution of basic algorithm
  • C implementation of Dutch national flag problem with Two and Three Colour