Start by putting the function you want here.  Then run the whole notebook and it compares various methods.

f[x_] := Cos[x] - x^3; aStart = -2.; bStart = 1.5;
f[x_] := Exp[x] * (x^3 - x); aStart = -2.; bStart = 1.5;
f[x_] :=Min[0.1Exp[x], x - x^2]; aStart = -2.; bStart = 0.5;
f[x_] := Sin[1/x]; aStart = -2.; bStart = 1.5;
f[x_] :=Min[0.1Exp[x/10], 5Exp[x] - 4]; aStart = -2.; bStart = 1.5;
f[x_] := (x-1)Exp[x] ; aStart = -5.; bStart = 5.;  (* Unfair advantage to Ridder's method. *)
f[x_] := x - x^2; aStart = -2.; bStart =0.5;  (*Unfair advantage to Muller's method and quadratic method *)
f[x_] := 2x + 3; aStart = -2.; bStart = 1.5;  (* Linear! *)
f[x_] := Exp[x] - 2; aStart = -5.; bStart = 5.;
f[x_] :=Sign[x]; aStart = -2.; bStart = 1.5;  (* Not a continuous function! *)

tol = 10^-15;  (* Stop when Abs[f[x]] < tol *)
Plot[f[x], {x, aStart, bStart}]
If[f[aStart]*f[bStart] ≥ 0, Print["WARNING: f does not have opposite signs at the endpoints."] ];

Secant Method, which does not have bracketing

a =aStart;
b= bStart;
Print["Secant method for f[x] = ", f[x],", initialized with a = ", a, ", b = ",b];
a0 = a;
b0 = b;
If[a0 ≥ b0, Print["Should have a < b"] ];
fa = f[a];
fb = f[b];
If[Abs[fa] < Abs[fb], (* then swithch to make b closer to root. *)
aTemp = a;
faTemp = fa;
a = b;
fa = fb;
b =aTemp;
fb = faTemp
];
fEvals = 0;  (* start keeping count now *)
If[fa*fb ≥ 0, Print["f does not change sign"] ];
maxitsSecant =20;
SecantConverged = False;
Do[
c = (fb * a - fa * b)/(fb - fa);
If[c < a0 || c > b0, Print["c = ", c, " is outside original bounds."] ];
fc = f[c];
fEvals++;
Print["c = ", c, ", f[c] = ", N[fc]];
If[Abs[fc] < tol, SecantConverged = True;Print["Root near ", c];Break[] ];
b = a;
fb = fa;
a = c;
fa = fc
,{maxitsSecant}
]
Print[fEvals, " function evaluations performed."];
secantEvals = fEvals;

Ridder’s Algorithm

a = aStart;
b = bStart;
Print["Ridder's algorithm for f[x] = ", f[x],", initialized with a = ", a, ", b = ",b]
fa = f[a];
fb = f[b];
fEvals = 0;
If[fa*fb ≥ 0, Print["f does not change sign"] ];
Print["f[a] = ", fa, ", f[b] = ", fb];
maxitsRidder =20;
ridderConverged = False;
Do[
c = (a + b)/2;
fc = f[c];
fEvals ++;
d = c + (c-a)Sign[fa - fb]fc/Sqrt[fc^2 - fa*fb];
fd = f[d];
fEvals ++;
Print["d = ", d,", fd = ", fd, ", (b-a)/(bStart-aStart) = ", (b-a)/(bStart-aStart)];
If[Abs[fd] < tol,ridderConverged = True;Print["Root near d = ", d];Break[] ];
Which[
fc * fd <0,                 a = c; fa = fc; b = d; fb = fd,
fa * fd < 0,               b = d; fb = fd,
fb * fd < 0,                a = d; fa =fd
],
{maxitsRidder}];
Print[fEvals, " function evaluations performed."];
ridderEvals = fEvals;
Print["Bisection method would take ", -Log[(b-a)/(bStart-aStart)]/Log[2], " steps to get similar b-a."];
Print["b - d = ", b-d, ", d - a = ", d-a];

Bisection method

a = aStart;
b = bStart;
Print["Besection Method for f[x] = ", f[x],", initialized with a = ", a, ", b = ",b]
fa = f[a];
fb = f[b];
fEvals = 0;
If[fa*fb ≥ 0, Print["f does not change sign"] ];
Print["f[a] = ", fa, ", f[b] = ", fb];
maxitsBisection =100;
bisectionConverged = False;
Do[
c = (a + b)/2;
fc = f[c];
fEvals ++;
If[Abs[fc] < tol,bisectionConverged = True;Print["Root near c = ", c];Break[] ];
Which[
fa * fc <0,                 b = c; fb = fc,
fb * fc< 0,                 a = c; fa = fc
],
{maxitsBisection}];
Print[fEvals, " function evaluations performed."];
bisectionEvals = fEvals;
Print["b - c = ", b-c, ", c - a = ", c-a];

Muller’s method, which does not have bracketing.  This follows pseudocode at
http://campus.murraystate.edu/academic/faculty/wlyle/420/Muller.htm
I should check for a bug: it takes a long time.

x1 = aStart;
y1 = f[x1];
x2 = bStart;
y2 = f[x2];
Print["Muller's method for f[x] = ", f[x],", initialized with x1 = ", x1, ", x2 = ",x2];
x3 = (y2*x1-y1*x2)/(y2 - y1);  (* this uses secant step *)
x3 = (x1+x2)/2;  (* this uses midpoint *)
y3 = f[x3];
fEvals = 1;  (* computing y1 and y2 don't count *)
Print["{x1, x2, x3} = ", {x1,x2, x3}, ", {y1, y2, y3} = ", {y1, y2, y3}];
maxitsMuller = 10;
mullerConverged = False;
m12 = (y2 - y1)/(x2-x1);
Do[m23 = (y3-y2)/(x3-x2);
f123 = (m23 - m12)/(x3 - x1);
s = m23 + (x3 - x2)f123;
disc = s^2 - 4 y3 f123;
If[disc < 0, Print["Muller's method encountered complex numbers.  Quit"];
Break[]
];
x4 = x3 - 2 y3/(s + Sign[s]Sqrt[s^2 - 4y3 f123]);
If[x4 < Min[aStart,bStart] || x4 > Max[aStart,bStart], Print["Root of quadratic is not in original interval."] ];
y4 = f[x4];
fEvals++;
If[Abs[y4] < tol, mullerConverged = True;Print["root near ", x4, ", f = ", y4]; Break[] ];
Print["f[",x4, "] = ", y4];
x1 = x2;
x2 = x3;
x3 = x4;
y1 = y2;
y2 = y3;
y3 = y4;
,{maxitsMuller}];
Print[fEvals, " function evaluations performed."];
mullerEvals = fEvals;

the following is from the Wolfram Mathworld web site: it doesn’t seem to work.

(* now use Muller's method formula *)
(* This one doesn't seem to work 
q = (c-b)/(b-a);
A = q fc -q(1+q)fb + q^2 fa;
B = (2q+1)fa - (1+q)^2 fb + q^2 fc;
CC = (1+q)fa;
disc = Sqrt[B^2 - 4 A CC];
d1 = c -(c-b)2CC/(B + disc);
d2 = c -(c-b)2CC/(B - disc);
Print["z = ", z, ", Muller's next iterates: ", d1, " and ", d2];
*)

This is “my” algorithm.  It is like Muller’s method, but it maintains the bracketing of the root.

a = aStart;
c = bStart;
Print["Quadratic method for f[x] = ", f[x],", initialized with a = ", a, ", c = ",c];
b = (a+c)/2;
fa = f[a];
fb = f[b];
fc = f[c];
fEvals = 1;
Print["[a, b, c] = ", {a, b, c}, ", f(b) = ", fb];
maxitsQuadratic = 20;
quadraticConverged = False;
Do[p[x_] := fa (((x - b)(x - c))/((a-b)(a- c)))+fb (((x-a)(x-c))/((b - a)(b-c)))+fc (((x - a)(x-b))/((c - a)(c-b)));
soln = Solve[p[x] == 0, x];  (* There are two real solutions *)
z = x/.soln[[1]];
If[z < Min[a,c] || z > Max[a,c],z = x/.soln[[2]] ];
If[z < Min[a,c] || z > Max[a,c], Print["Root of quadratic in interval not found."] ; Break[]];
fz = f[z];
fEvals ++;
If[Abs[fz] < tol, quadraticConverged = True;Print["root near ", z, ", f = ", fz]; Break[] ];
If[fa * fb > 0,
a = b; fa = fb, (* else fb*fc > 0 *)
c = b; fc = fb];
b = z; fb = fz;
Print["[a, b, c] = ", {a, b,c}, ", f(b) = ", fb]
,{maxitsQuadratic}];
Print[fEvals, " function evaluations performed."];
quadraticEvals = fEvals;

Modified Regula Falsi

a = aStart;
b = bStart;
Print["Modified Regula Falsi for f[x] = ", f[x],", a = ", a, ", b = ",b]
fa = f[a];
fb = f[b];
fEvals = 0;
If[fa*fb ≥ 0, Print["f does not change sign"] ];
Print["f[a] = ", fa, ", f[b] = ", fb];
oldfc = 0;
maxitsFalsi =20;
falsiConverged = False;
Do[c = (fb * a - fa * b)/(fb - fa);
fc = f[c];
fEvals ++;
Print["c = ", c, ", f[c] = ", fc];
If[Abs[fc] < tol, falsiConverged=True;Print["Root near c = ", c];Break[] ];
If[fa * fc > 0, 
a = c; 
fa = fc;
If[fc*oldfc > 0, 
fb = fb/2
]
, 
b = c; 
fb = fc;
If[fc * oldfc > 0, 
fa = fa/2
]
];
oldfc = fc;
,{maxitsFalsi}
];
Print[fEvals, " function evaluations performed."];
falsiEvals = fEvals;

Print["Number of evaluations done to find a root of f[x] = ", f[x]," bracketed in the interval [", aStart, ", ",bStart,"]"];
Print["with a tolerance of Abs[f[x]] = ", N[tol]];

If[SecantConverged, Print["Secant method:    ", secantEvals], 
Print["Secant method:    Did not converge with maxits = ", maxitsSecant] ];

If[ridderConverged, Print["Ridder's method:  ", ridderEvals], 
Print["Ridder's method:  Did not converge with maxits = ", maxitsRidder] ];

If[bisectionConverged, Print["Bisection method: ", bisectionEvals],
Print["Bisection method: Did not converge with maxits = ", maxitsBisection] ];

If[falsiConverged, Print["Mod Regula Falsi: ", falsiEvals], 
Print["Mod Regula Falsi: Did not converge with maxits = ", maxitsQuadratic] ]

If[mullerConverged, Print["Muller method:    ", mullerEvals], 
Print["Muller method:    Did not converge with maxits = ", maxitsMuller] ];

If[quadraticConverged, Print["Quadratic method: ", quadraticEvals], 
Print["Quadratic method: Did not converge with maxits = ", maxitsQuadratic] ]