1

I'm a bit stuck using quick sort algorithm on an integer array, while saving the original indexes of the elements as they're moved around during the sorting process. Using C#/Visual studio For example

ToSort Array {52,05,08,66,02,10} Indexes : 0 1 2 3 4 5

AfterSort Array {02,05,08,10,52,66} Indexes : 4 1 2 5 0 3

I need to save the indexes of the sorted values in another array. I feel like this is very complex as quick sorting is recursive and any help or pointers would be much appreciated! Thanks!

SheyDev
  • 78
  • 5
  • 1
    Wrap the integers in an object that contains the index and the number. Then quicksort. After, you can iterate the list to retrieve the value and the original index. The Aristocrats. –  Jul 27 '17 at 12:43

2 Answers2

4

As @Will said you can do something like this :

var myArray = new int[] { 52, 05, 08, 66, 02, 10 };

///In tupple item1 you have the number, in the item2 you have the index  
var myIndexedArray = myArray.Select( ( n, index ) => Tuple.Create( n, index ) );

///Or if you are using c# 7, you can use the tuple literals ! :
var myIndexedArray = myArray.Select( ( n, index ) => ( n, index ) );

///Call your quick sort method, sort by the item1 (the number) inside the method
// or use Enumerable.OrderBy:
myIndexedArray = myIndexedArray.OrderBy(x => x.Item1);

///Then get your things back
int[] numbers = myIndexedArray.Select(x => x.Item1).ToArray();
int[] indexes = myIndexedArray.Select(x => x.Item2).ToArray();
Lucas
  • 1,259
  • 15
  • 25
2

LINQ OrderBy uses QuickSort internally. So instead of implementing QuickSort yourself, use OrderBy, if needed with a custom IComparer<T>.

Put the data to be sorted into an anonymous type which remembers the original index, then sort by value. You can retrieve the original index from the index property of the sorted elements.

using System.Linq;

var data = new int[] { 52,05,08,66,02,10 };

var sortingDictionary = data
    .Select((value, index) => new { value, index });

var sorted = sortingDictionary
    .OrderBy(kvp => kvp.value)
    .ToList(); // enumerate before looping over result!

for (var newIndex = 0; newIndex < sorted.Count(); newIndex ++) {
    var item = sorted.ElementAt(newIndex);
    Console.WriteLine(
        $"New index: {newIndex}, old index: {item.index}, value: {item.value}"
    );
}

Fiddle

Edit: incorporated improvements suggested by mjwills

Georg Patscheider
  • 9,357
  • 1
  • 26
  • 36