if the data is small (like, an integer or something) you can swap the data directly and leave the structure intact. If the data copy is very, very expensive, you can either redesign it so its a list of pointers to data and swap the pointers this way, or you can do the somewhat annoying node shuffle by breaking the pointers and reconnecting them in their new places. Its mostly an order of operations task, you just use temporaries and assignments in the right order to break the list into chunks and reassemble them.
eg 1-2-3-4-5-6 … to swap 2 and 5..
take a pointer to 6 (if it had anything after it, it would tag along) and set 5-next null
grab a pointer to 5 and set 4-> next to null and 5-> next to null
(now you have 6, 5, and 1-2-3-4)
grab a pointer to 2, set 1-> next to 5.
now you have 1-5 as a list and 2-3-4 as a list and 6 as a list)
attach 5-> next to 2-> next. now you have 1-5-3-4
set last pointer to 2 and set 2-> next to 6.
now you have 1-5-3-4-2-6
there may be a way to do it less explicitly (faster) but I am showing all the steps you would take doing it carefully so you can see it. Shortcuts can wait.
your algorithm for finding max seems ok, but I didn't check to make sure you did not lose the list in the process. if head is your list, and you don't have a copy of it, you just lost the list by changing head as you go looking... I would have set temp=head and searched temp for max the same way, keeping head intact (and the names making more sense this way). Make sure you preserved the list; its really easy to forget this and discard all your data.