I'm confused about passing arrays by reference. Since arrays are stored on the heap it was my belief that when they are passed as parameters the value of the parameter is the location in the heap. This might be confusion as to what the variable is representing.
If the array is stored on the heap, what exactly does the
refkeyword mean when passing an array to a method? It was my belief that changing the array in the called method would change the calling method since it was passed by value and the value contains a reference to the array.If I skip
Sortand instead callDoSortdirectly thenunsortedArrayis sorted correctly. In the program below, why isunsortedArraynever sorted at the end of execution? Does this have anything to do with the fact that this is a recursive algorithm?
Here is the code:
public class Program {
static void Main(string[] args) {
int[] unsortedArray = new[] { 9, 7, 5, 3, 1 };
Sort(unsortedArray);
}
public static void Sort(int[] sortArray) {
DoSort(ref sortArray);
}
public static void DoSort(ref int[] doSortArray) {
if (doSortArray.Length == 1) {
return;
}
int midpoint = doSortArray.Length / 2;
// divide the array into the left portion
int[] left = new int[midpoint];
for (int i = 0; i < midpoint; i++) {
left[i] = doSortArray[i];
}
// divide the array into the right portion
int[] right = new int[doSortArray.Length - midpoint];
int j = 0;
for (int i = midpoint; i < doSortArray.Length; i++) {
right[j] = doSortArray[i];
j++;
}
DoSort(ref left);
DoSort(ref right);
doSortArray = Merge(left, right);
}
/// <summary>
/// Merges the specified unmerged array.
/// </summary>
/// <param name="left">The left.</param>
/// <param name="right">The right.</param>
private static int[] Merge(int[] left, int[] right) {
int i = 0;
int[] result = new int[left.Length + right.Length];
int leftIndex = 0;
int rightIndex = 0;
while (leftIndex < left.Length || rightIndex < right.Length) {
if (leftIndex < left.Length && rightIndex < right.Length) {
if (left[leftIndex] <= right[rightIndex]) {
result[i] = left[leftIndex];
leftIndex++;
} else {
result[i] = right[rightIndex];
rightIndex++;
}
}
else if (leftIndex < left.Length) {
result[i] = left[leftIndex];
leftIndex++;
}
else if (rightIndex < right.Length) {
result[i] = right[rightIndex];
rightIndex++;
}
i++;
}
return result;
}
}
sortArrayby reference toSort, only toDoSort. That's why it works correctly when bypassingSort.