我们已经讨论了合并排序。如何修改算法以使合并在O(1)的额外空间中起作用,并且算法仍在O(n Log n)时间内起作用。我们可以假设输入值仅是整数。
例子:
Input : 5 4 3 2 1
Output : 1 2 3 4 5
Input : 999 612 589 856 56 945 243
Output : 56 243 589 612 856 945 999
对于整数类型,可以使用模数和除法的一些数学技巧就地进行合并排序。这意味着将两个元素值存储在一个索引上,并且可以使用模数和除法来提取。
首先,我们必须找到一个大于数组所有元素的值。现在我们可以将原始值存储为模数,将第二个值存储为除法。假设我们想将arr [i]和arr [j]都存储在索引i(均指arr [i])中。首先,我们必须找到一个大于arr [i]和arr [j]的‘maxval’ 。现在我们可以存储为arr [i] = arr [i] + arr [j] * maxval 。现在arr [i]%maxval将给出arr [i]的原始值,而arr [i] / maxval将给出arr [j]的值。因此,以下是合并排序的实现。
C++
// C++ program to sort an array using merge sort such
// that merge operation takes O(1) extra space.
#include
using namespace std;
void merge(int arr[], int beg, int mid, int end, int maxele)
{
int i = beg;
int j = mid + 1;
int k = beg;
while (i <= mid && j <= end) {
if (arr[i] % maxele <= arr[j] % maxele) {
arr[k] = arr[k] + (arr[i] % maxele) * maxele;
k++;
i++;
}
else {
arr[k] = arr[k] + (arr[j] % maxele) * maxele;
k++;
j++;
}
}
while (i <= mid) {
arr[k] = arr[k] + (arr[i] % maxele) * maxele;
k++;
i++;
}
while (j <= end) {
arr[k] = arr[k] + (arr[j] % maxele) * maxele;
k++;
j++;
}
// Obtaining actual values
for (int i = beg; i <= end; i++)
arr[i] = arr[i] / maxele;
}
// Recursive merge sort with extra parameter, naxele
void mergeSortRec(int arr[], int beg, int end, int maxele)
{
if (beg < end) {
int mid = (beg + end) / 2;
mergeSortRec(arr, beg, mid, maxele);
mergeSortRec(arr, mid + 1, end, maxele);
merge(arr, beg, mid, end, maxele);
}
}
// This functions finds max element and calls recursive
// merge sort.
void mergeSort(int arr[], int n)
{
int maxele = *max_element(arr, arr+n) + 1;
mergeSortRec(arr, 0, n-1, maxele);
}
int main()
{
int arr[] = { 999, 612, 589, 856, 56, 945, 243 };
int n = sizeof(arr) / sizeof(arr[0]);
mergeSort(arr, n);
cout << "Sorted array \n";
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
return 0;
}
Java
// Java program to sort an array
// using merge sort such that
// merge operation takes O(1)
// extra space.
import java.util.Arrays;
class GFG
{
static void merge(int[] arr, int beg,
int mid, int end,
int maxele)
{
int i = beg;
int j = mid + 1;
int k = beg;
while (i <= mid && j <= end)
{
if (arr[i] % maxele <=
arr[j] % maxele)
{
arr[k] = arr[k] + (arr[i]
% maxele) * maxele;
k++;
i++;
}
else
{
arr[k] = arr[k] +
(arr[j] % maxele)
* maxele;
k++;
j++;
}
}
while (i <= mid)
{
arr[k] = arr[k] + (arr[i]
% maxele) * maxele;
k++;
i++;
}
while (j <= end)
{
arr[k] = arr[k] + (arr[j]
% maxele) * maxele;
k++;
j++;
}
// Obtaining actual values
for (i = beg; i <= end; i++)
{
arr[i] = arr[i] / maxele;
}
}
// Recursive merge sort
// with extra parameter, naxele
static void mergeSortRec(int[] arr, int beg,
int end, int maxele)
{
if (beg < end)
{
int mid = (beg + end) / 2;
mergeSortRec(arr, beg,
mid, maxele);
mergeSortRec(arr, mid + 1,
end, maxele);
merge(arr, beg, mid,
end, maxele);
}
}
// This functions finds
// max element and calls
// recursive merge sort.
static void mergeSort(int[] arr, int n)
{
int maxele = Arrays.stream(arr).max().getAsInt() + 1;
mergeSortRec(arr, 0, n - 1, maxele);
}
// Driver code
public static void main(String[] args)
{
int[] arr = {999, 612, 589,
856, 56, 945, 243};
int n = arr.length;
mergeSort(arr, n);
System.out.println("Sorted array ");
for (int i = 0; i < n; i++)
{
System.out.print(arr[i] + " ");
}
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 program to sort an array using
# merge sort such that merge operation
# takes O(1) extra space.
def merge(arr, beg, mid, end, maxele):
i = beg
j = mid + 1
k = beg
while (i <= mid and j <= end):
if (arr[i] % maxele <= arr[j] % maxele):
arr[k] = arr[k] + (arr[i] %
maxele) * maxele
k += 1
i += 1
else:
arr[k] = arr[k] + (arr[j] %
maxele) * maxele
k += 1
j += 1
while (i <= mid):
arr[k] = arr[k] + (arr[i] %
maxele) * maxele
k += 1
i += 1
while (j <= end):
arr[k] = arr[k] + (arr[j] %
maxele) * maxele
k += 1
j += 1
# Obtaining actual values
for i in range(beg, end + 1):
arr[i] = arr[i] // maxele
# Recursive merge sort with extra
# parameter, naxele
def mergeSortRec(arr, beg, end, maxele):
if (beg < end):
mid = (beg + end) // 2
mergeSortRec(arr, beg, mid, maxele)
mergeSortRec(arr, mid + 1, end, maxele)
merge(arr, beg, mid, end, maxele)
# This functions finds max element and
# calls recursive merge sort.
def mergeSort(arr, n):
maxele = max(arr) + 1
mergeSortRec(arr, 0, n - 1, maxele)
# Driver Code
if __name__ == '__main__':
arr = [ 999, 612, 589, 856, 56, 945, 243 ]
n = len(arr)
mergeSort(arr, n)
print("Sorted array")
for i in range(n):
print(arr[i], end = " ")
# This code is contributed by mohit kumar 29
C#
// C# program to sort an array
// using merge sort such that
// merge operation takes O(1)
// extra space.
using System;
using System.Linq;
class GFG
{
static void merge(int []arr, int beg,
int mid, int end,
int maxele)
{
int i = beg;
int j = mid + 1;
int k = beg;
while (i <= mid && j <= end)
{
if (arr[i] %
maxele <= arr[j] % maxele)
{
arr[k] = arr[k] + (arr[i] %
maxele) * maxele;
k++;
i++;
}
else
{
arr[k] = arr[k] +
(arr[j] % maxele) *
maxele;
k++;
j++;
}
}
while (i <= mid)
{
arr[k] = arr[k] + (arr[i] %
maxele) * maxele;
k++;
i++;
}
while (j <= end)
{
arr[k] = arr[k] + (arr[j] %
maxele) * maxele;
k++;
j++;
}
// Obtaining actual values
for ( i = beg; i <= end; i++)
arr[i] = arr[i] / maxele;
}
// Recursive merge sort
// with extra parameter, naxele
static void mergeSortRec(int []arr, int beg,
int end, int maxele)
{
if (beg < end)
{
int mid = (beg + end) / 2;
mergeSortRec(arr, beg,
mid, maxele);
mergeSortRec(arr, mid + 1,
end, maxele);
merge(arr, beg, mid,
end, maxele);
}
}
// This functions finds
// max element and calls
// recursive merge sort.
static void mergeSort(int []arr, int n)
{
int maxele = arr.Max() + 1;
mergeSortRec(arr, 0, n - 1, maxele);
}
//Driver code
public static void Main ()
{
int []arr = {999, 612, 589,
856, 56, 945, 243};
int n = arr.Length;
mergeSort(arr, n);
Console.WriteLine("Sorted array ");
for (int i = 0; i < n; i++)
Console.Write( arr[i] + " ");
}
}
// This code is contributed
// by inder_verma.
输出:
Sorted array
56 243 589 612 856 945 999