New Zealand batted first and after starting cautiously finished strongly in a total of 273 for six wickets from their 50 overs.
Zimbabwe’s openers added 97 runs in reply but the hosts lost wickets at regular intervals and fell well short of the target, bowled out for 235 in 47.4 overs.
Williamson fell 10 runs short of a century but did record his sixth 50 in ODI cricket to provide the backbone of the visitors’ innings.
He featured in a 56-run partnership with Martin Guptill (42) and a 70-run stand with Grant Elliott.
Williamson was caught after some sharp thinking from Craig Ervine, who took the dismissal on the boundary by padding the ball back into the air as his momentum threatened to carry him over the ropes before recovering to catch the ball.
New Zealand kept up hit a steady tempo with James Neesham, in for the injured Ross Taylor, and Nathan McCullum contributing a lusty 50 runs in the final five overs.
Sean Williams top-scored for the home team with 63 and Hamilton Masakadza made 57.
Zimbabwe won the opening match of the series, all played in the capital, by seven wickets but lost the second when New Zealand reached their target without the loss of a wicket.
New Zealand now go on to play a limited-overs series in South Africa.