def brick_sort(array, **kwargs): """ Implements Brick Sort / Odd Even sorting algorithm Parameters ========== array: Array The array which is to be sorted. start: int The starting index of the portion which is to be sorted. Optional, by default 0 end: int The ending index of the portion which is to be sorted. Optional, by default the index of the last position filled. comp: lambda/function The comparator which is to be used for sorting. If the function returns False then only swapping is performed. Optional, by default, less than or equal to is used for comparing two values. Examples ======== >>> from pydatastructs import OneDimensionalArray, brick_sort >>> arr = OneDimensionalArray(int,[3, 2, 1]) >>> brick_sort(arr) >>> [arr[0], arr[1], arr[2]] [1, 2, 3] >>> brick_sort(arr, comp=lambda u, v: u > v) >>> [arr[0], arr[1], arr[2]] [3, 2, 1] References ========== .. [1] https://www.geeksforgeeks.org/odd-even-sort-brick-sort/ """ start = kwargs.get('start', 0) end = kwargs.get('end', len(array) - 1) comp = kwargs.get("comp", lambda u, v: u <= v) is_sorted = False while is_sorted is False: is_sorted = True for i in range(start + 1, end, 2): if _comp(array[i + 1], array[i], comp): array[i], array[i + 1] = array[i + 1], array[i] is_sorted = False for i in range(start, end, 2): if _comp(array[i + 1], array[i], comp): array[i], array[i + 1] = array[i + 1], array[i] is_sorted = False if _check_type(array, DynamicArray): array._modify(force=True)
def _merge(array, sl, el, sr, er, end, comp): l, r = [], [] for i in range(sl, el + 1): if i <= end: l.append(array[i]) array[i] = None for i in range(sr, er + 1): if i <= end: r.append(array[i]) array[i] = None i, j, k = 0, 0, sl while i < len(l) and j < len(r): if _comp(l[i], r[j], comp): array[k] = l[i] i += 1 else: array[k] = r[j] j += 1 k += 1 while i < len(l): array[k] = l[i] i += 1 k += 1 while j < len(r): array[k] = r[j] j += 1 k += 1
def partition(low, high, pick_pivot_element): i = (low - 1) x = pick_pivot_element(low, high, array) for j in range(low, high): if _comp(array[j], x, comp) is True: i = i + 1 array[i], array[j] = array[j], array[i] array[i + 1], array[high] = array[high], array[i + 1] return (i + 1)
def _minimum_spanning_tree_parallel_prim_adjacency_list(graph, num_threads): q = [ PriorityQueue(implementation='binomial_heap') for _ in range(num_threads) ] e = [dict() for _ in range(num_threads)] v2q = dict() mst = Graph(implementation='adjacency_list') itr = iter(graph.vertices) for i in range(len(graph.vertices)): v2q[next(itr)] = i % len(q) q[0].push(next(iter(graph.vertices)), 0) while True: _vs = [None for _ in range(num_threads)] with ThreadPoolExecutor(max_workers=num_threads) as Executor: for i in range(num_threads): Executor.submit(_find_min, q[i], _vs, i).result() v = None for i in range(num_threads): if _comp(_vs[i], v, lambda u, v: u.key < v.key): v = _vs[i] if v is None: break v = v.data idx = v2q[v] q[idx].pop() if not hasattr(mst, v): mst.add_vertex(graph.__getattribute__(v)) if e[idx].get(v, None) is not None: edge = e[idx][v] mst.add_vertex(edge.target) mst.add_edge(edge.source.name, edge.target.name, edge.value) mst.add_edge(edge.target.name, edge.source.name, edge.value) for w_node in graph.neighbors(v): w = w_node.name vw = graph.edge_weights[v + '_' + w] j = v2q[w] q[j].push(w, vw.value) if e[j].get(w, None) is None or \ e[j][w].value > vw.value: e[j][w] = vw return mst
def _brick_sort_swap(array, i, j, comp, is_sorted): if _comp(array[j], array[i], comp): array[i], array[j] = array[j], array[i] is_sorted[0] = False
def cocktail_shaker_sort(array: Array, **kwargs) -> Array: """ Performs cocktail sort on the given array. Parameters ========== array: Array The array which is to be sorted. start: int The starting index of the portion which is to be sorted. Optional, by default 0 end: int The ending index of the portion which is to be sorted. Optional, by default the index of the last position filled. comp: lambda/function The comparator which is to be used for sorting. If the function returns False then only swapping is performed. Optional, by default, less than or equal to is used for comparing two values. Returns ======= output: Array The sorted array. Examples ======== >>> from pydatastructs import OneDimensionalArray as ODA, cocktail_shaker_sort >>> arr = ODA(int, [5, 78, 1, 0]) >>> out = cocktail_shaker_sort(arr) >>> str(out) '[0, 1, 5, 78]' >>> arr = ODA(int, [21, 37, 5]) >>> out = cocktail_shaker_sort(arr) >>> str(out) '[5, 21, 37]' References ========== .. [1] https://en.wikipedia.org/wiki/Cocktail_shaker_sort """ def swap(i, j): array[i], array[j] = array[j], array[i] lower = kwargs.get('start', 0) upper = kwargs.get('end', len(array) - 1) comp = kwargs.get("comp", lambda u, v: u <= v) swapping = False while (not swapping and upper - lower >= 1): swapping = True for j in range(lower, upper): if _comp(array[j], array[j + 1], comp) is False: swap(j + 1, j) swapping = False upper = upper - 1 for j in range(upper, lower, -1): if _comp(array[j - 1], array[j], comp) is False: swap(j, j - 1) swapping = False lower = lower + 1 if _check_type(array, DynamicArray): array._modify(force=True) return array
def insertion_sort(array, **kwargs): """ Implements insertion sort algorithm. Parameters ========== array: Array The array which is to be sorted. start: int The starting index of the portion which is to be sorted. Optional, by default 0 end: int The ending index of the portion which is to be sorted. Optional, by default the index of the last position filled. comp: lambda/function The comparator which is to be used for sorting. If the function returns False then only swapping is performed. Optional, by default, less than or equal to is used for comparing two values. backend: pydatastructs.Backend The backend to be used. Optional, by default, the best available backend is used. Returns ======= output: Array The sorted array. Examples ======== >>> from pydatastructs import OneDimensionalArray, insertion_sort >>> arr = OneDimensionalArray(int,[3, 2, 1]) >>> out = insertion_sort(arr) >>> str(out) '[1, 2, 3]' >>> out = insertion_sort(arr, comp=lambda u, v: u > v) >>> str(out) '[3, 2, 1]' References ========== .. [1] https://en.wikipedia.org/wiki/Insertion_sort """ raise_if_backend_is_not_python(insertion_sort, kwargs.get('backend', Backend.PYTHON)) start = kwargs.get('start', 0) end = kwargs.get('end', len(array) - 1) comp = kwargs.get('comp', lambda u, v: u <= v) for i in range(start + 1, end + 1): temp = array[i] j = i while j > start and not _comp(array[j - 1], temp, comp): array[j] = array[j - 1] j -= 1 array[j] = temp if _check_type(array, DynamicArray): array._modify(force=True) return array
def _prev_permutation_comp(x, y, _comp): if _comp(x, y): return True else: return False
def _next_permutation_comp(x, y, _comp): if _comp(x, y): return False else: return True