Any spline will do, but Bézier will provide smoother transitions between colors than linear. The "best" way depends on what you want to do with the ramp; in some cases, linear is the correct and elegant way to go, but higher-order splines tend to get more "organic" results.
You can handle any number of control points by taking
n nearest control points of the parameter (where
n is the degree of the curve + 1), and doing the interpolation between those found points. This effectively means that the minimum amount of control points is also defined as degree + 1.
Here is a simple example of piecewise linear handling of arbitrary number of points:
float4 colors[] = {float4(1,0,0,1), float4(0,1,0,1), float4(0,0,1,1), float4(0,0,0,1), float4(1,1,1,1)}; // red, green, blue, black, white
int numColors = 5; // must match the actual number of control points <img src='http://public.gamedev.net//public/style_emoticons/<#EMO_DIR#>/smile.png' class='bbc_emoticon' alt=':)' />
float parameter; // initialized earlier to 0...1
float index = parameter * (float)numColors;
int nearestLeftIndex = (int)index; // effectively take the whole number part of the scaled parameter to find the first control point
int nearestRightIndex = nearestLeftIndex + 1; // the next control point is adjacent in the array
// If nearest indices are the same or greater than numColors or less than 0, we should take the nearest point as is, because we're past the color array.
// To extend beyond piecewise linear, find more nearest points like this and perform the next steps with those.
float4 left = colors[nearestLeftIndex];
float4 right = colors[nearestRightIndex];
float fraction = index - (float)nearestLeftIndex; // find the decimal portion of the scaled parameter in between the nearest points
float4 finalColor = lerp (left, right, fraction); // then interpolate between the nearest points