Remembering that this is just the way *I* would approach it, I'd have a table of the CPU and IO bursts separate from everything else.
int CPU_Bursts[MAX_PROCESSES][MAX_BURSTS];
int IO_Delays[MAX_PROCESSES][MAX_BURSTS];
(I'm assuming 'bursts' means 'time to spend doing it')
And the records in the queues would contain the process number (0..29) and burst number (0..9) and use those to index into the above arrays when you need to. My thinking is that the data (the arrays) is sort of the 'sample data set' and not really part of the algorithm per se.
It sounds like you want to do a bunch-o-stats gathering, so I think the process record needs to know when it entered the current queue it is on, and then buckets for the total waits and the like. So, for example, the LAST process is on the ready queue, just like all the others, at time 0. It has to wait for all the other CPU bursts on all the other processes before it gets its crack. So, when you go to process that LAST entry, he has been waiting for <current time> - <placed on queue time> clock ticks. Use that for your stats.
Then for the main driver, something like:
put all processes on the rdyQueue.
while not-done,
if the rdyQueue is not empty,
add front process' burst time onto the clock
(to pretend the burst has elapsed);
do any other bookkeeping with this process
(like figure out his delay in waiting for the CPU);
move this process to the waitQueue if it has more work to do
(else terminate the process and remove it from the queues)
(put the current clock time into the process record
as 'when I entered this queue').
Similarly, process the waitQueue if it isn't empty
If both are empty, you are done!
For simplicity, too, it might be easiest to have the process records in an array and just put the POINTERS on the queue, that way you can still iterate the array when all processes are off the queues (when the processes are 'done').