sort.carbon 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. library "sort";
  5. interface Ordered {
  6. // extend require impls Core.OrderedWith(Self);
  7. fn Less[self: Self](other: Self) -> bool;
  8. fn LessOrEquivalent[self: Self](other: Self) -> bool;
  9. fn Greater[self: Self](other: Self) -> bool;
  10. fn GreaterOrEquivalent[self: Self](other: Self) -> bool;
  11. }
  12. impl i32 as Ordered {
  13. fn Less[self: Self](other: Self) -> bool { return self < other; }
  14. fn LessOrEquivalent[self: Self](other: Self) -> bool { return self <= other; }
  15. fn Greater[self: Self](other: Self) -> bool { return self > other; }
  16. fn GreaterOrEquivalent[self: Self](other: Self) -> bool { return self >= other; }
  17. }
  18. fn Swap[T:! Core.Copy & Core.Destroy](ref from: T, ref to: T) {
  19. var tmp: T = from;
  20. from = to;
  21. to = tmp;
  22. }
  23. fn Partition
  24. [T:! Core.Copy & Core.Destroy & Ordered, N:! Core.IntLiteral()]
  25. (ref a: array(T, N), from_in: i32, to_in: i32) -> i32 {
  26. var pivot_index: i32 = from_in;
  27. let pivot: T = a[pivot_index];
  28. var from: i32 = from_in + 1;
  29. var to: i32 = to_in;
  30. while (from < to) {
  31. // TODO: if (a[from] <= pivot) {
  32. if (a[from].(Ordered.LessOrEquivalent)(pivot)) {
  33. ++from;
  34. // TODO: } else if ((*p)[to - 1] > pivot) {
  35. } else if (a[to - 1].(Ordered.Greater)(pivot)) {
  36. --to;
  37. } else {
  38. // Element at `from` is > pivot, and
  39. // element at `to - 1` is <= pivot.
  40. Swap(ref a[from], ref a[to - 1]);
  41. ++from;
  42. --to;
  43. }
  44. }
  45. Swap(ref a[pivot_index], ref a[from - 1]);
  46. return from - 1;
  47. }
  48. fn Quicksort
  49. [T:! Core.Copy & Core.Destroy & Ordered, N:! Core.IntLiteral()]
  50. (ref a: array(T, N), from: i32, to: i32) {
  51. if (from + 1 >= to) { return; }
  52. var pivot: i32 = Partition(ref a, from, to);
  53. Quicksort(ref a, from, pivot);
  54. Quicksort(ref a, pivot + 1, to);
  55. }