28 27 bytes
Adapted from my answer herehere. The general idea is to create a 2D array of the same size as the input, filled with values that increase in the same order as the zig-zag path. Then the linearized (flattened) version of that array is sorted, and the indices of that sorting are kept. Those are the indices that need to be applied to the input in order to produce the zig-zag path.
Input is in the form
[1 2 3; 5 6 4; 9 7 8; 1 2 3]
t % input 2D array. Duplicate ZyZ} % get size as length-2 vector. Split into two numbers: r, c : % range [1,2,...,c] as a row vector w:! % swap, range [1;2;...;r] as a column vector + % add with broadcast. Gives a 2D array -1 % push -1 y^ % duplicate previous 2D array. Compute -1 raised to that 7M % push [1;2;...;r] again Gn/ % divide by input matrix size, that is, r*c * % multiply - % subtract X: % linearize 2D array into column array K#S % sort and push the indices of the sorting. Gives a column vector ) % index input matrix with that column vector