MergeSort.cs 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. //
  2. // Author:
  3. // Jb Evain (jbevain@gmail.com)
  4. //
  5. // Copyright (c) 2008 - 2015 Jb Evain
  6. // Copyright (c) 2008 - 2011 Novell, Inc.
  7. //
  8. // Licensed under the MIT/X11 license.
  9. //
  10. using System;
  11. using System.Collections.Generic;
  12. namespace ILRuntime.Mono {
  13. class MergeSort<T> {
  14. private readonly T [] elements;
  15. private readonly T [] buffer;
  16. private readonly IComparer<T> comparer;
  17. private MergeSort (T [] elements, IComparer<T> comparer)
  18. {
  19. this.elements = elements;
  20. this.buffer = new T [elements.Length];
  21. Array.Copy (this.elements, this.buffer, elements.Length);
  22. this.comparer = comparer;
  23. }
  24. public static void Sort (T [] source, IComparer<T> comparer)
  25. {
  26. Sort (source, 0, source.Length, comparer);
  27. }
  28. public static void Sort (T [] source, int start, int length, IComparer<T> comparer)
  29. {
  30. new MergeSort<T> (source, comparer).Sort (start, length);
  31. }
  32. private void Sort (int start, int length)
  33. {
  34. TopDownSplitMerge (this.buffer, this.elements, start, length);
  35. }
  36. private void TopDownSplitMerge (T [] a, T [] b, int start, int end)
  37. {
  38. if (end - start < 2)
  39. return;
  40. int middle = (end + start) / 2;
  41. TopDownSplitMerge (b, a, start, middle);
  42. TopDownSplitMerge (b, a, middle, end);
  43. TopDownMerge (a, b, start, middle, end);
  44. }
  45. private void TopDownMerge (T [] a, T [] b, int start, int middle, int end)
  46. {
  47. for (int i = start, j = middle, k = start; k < end; k++) {
  48. if (i < middle && (j >= end || comparer.Compare (a [i], a [j]) <= 0)) {
  49. b [k] = a [i++];
  50. } else {
  51. b [k] = a [j++];
  52. }
  53. }
  54. }
  55. }
  56. }