Features don't have key-value semantics, because cargo unifies them acress your dependency graph. I'd do a feature per algorithm, so that the user can choose which of them are compiled in. You can then provide a wrapper function that calls one of the algorithms using some logic to decide between them.
An alternative design could include a trait that defines the functionality you need, with different implementations behind cfg-flags. You can then use generics to write most of your code abstracted over a specific implementation.
If this is a binary project and not a library, this can still be a reasonable choice. It will not be nice to compilation (since it's a globally transitive setting), but setting the environment variable RUSTFLAGS to --cfg=algorithm=a will make cfg(algorithm = "a") pass in every crate in the entire compilation graph.
However, note that both cfg(algorithm = "a") and cfg(algorithm = "b")can still be set together; cfg keys can be multivalued. If you're using RUSTFLAGS it's on you to not do anything silly like set cfg(unix) on a non-Unix target.
The "most correct" solution is to make the choice of algorithm a trait implementation provided by simple dependency injection by function argument, as then enabling the features is addictive.