📜  对具有前 N 个元素已排序且最后 M 个元素未排序的数组进行排序

📅  最后修改于: 2022-05-13 01:56:05.467000             🧑  作者: Mango

对具有前 N 个元素已排序且最后 M 个元素未排序的数组进行排序

给定两个正整数NM以及一个由(N + M)个整数组成的数组arr[ ] ,使得前N个元素按升序排序,最后M个元素未排序,任务是对给定数组进行排序按升序排列。

例子:

朴素方法:解决给定问题的最简单方法是使用内置的 sort()函数对给定数组进行排序。

时间复杂度: O((N + M)log(N + M))
辅助空间: O(1)

Efficient Approach:上述方法也可以利用Merge Sort的思想进行优化。思路是对数组的最后M个元素进行归并排序操作,然后对数组的第一个N个和最后一个M个元素使用两个排序后的数组合并的概念。请按照以下步骤解决问题:

  • 使用本文讨论的方法对最后M个数组元素执行归并排序操作。
  • 经过上述步骤,子数组 arr[1, N]arr[N + 1, M]按升序排序。
  • 使用本文讨论的方法合并两个排序的子数组 arr[1, N]arr[N + 1, M]
  • 完成上述步骤后,将数组arr[]打印为结果数组。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function for merging the two sorted
// arrays
void merge(int a[], int l, int m, int r)
{
    int s1 = m - l + 1;
    int s2 = r - m;
 
    // Create two temp arrays
    int left[s1];
    int right[s2];
 
    // Copy elements to left array
    for (int i = 0; i < s1; i++)
        left[i] = a[l + i];
 
    // Copy elements to right array
    for (int j = 0; j < s2; j++)
        right[j] = a[j + m + 1];
 
    int i = 0, j = 0, k = l;
 
    // Merge the array back into the
    // array over the range [l, r]
    while (i < s1 && j < s2) {
 
        // If the current left element
        // is smaller than the current
        // right element
        if (left[i] <= right[j]) {
            a[k] = left[i];
            i++;
        }
 
        // Otherwise
        else {
            a[k] = right[j];
            j++;
        }
        k++;
    }
 
    // Copy the remaining elements of
    // the array left[]
    while (i < s1) {
        a[k] = left[i];
        i++;
        k++;
    }
 
    // Copy the remaining elements of
    // the array right[]
    while (j < s2) {
        a[k] = right[j];
        j++;
        k++;
    }
}
 
// Function to sort the array over the
// range [l, r]
void mergesort(int arr[], int l, int r)
{
    if (l < r) {
 
        // Find the middle index
        int mid = l + (r - l) / 2;
 
        // Recursively call for the
        // two halves
        mergesort(arr, l, mid);
        mergesort(arr, mid + 1, r);
 
        // Perform the merge operation
        merge(arr, l, mid, r);
    }
}
 
// Function to sort an array for the
// last m elements are unsorted
void sortlastMElements(int arr[], int N,
                       int M)
{
    int s = M + N - 1;
 
    // Sort the last m elements
    mergesort(arr, N, s);
 
    // Merge the two sorted subarrays
    merge(arr, 0, N - 1, N + M - 1);
 
    // Print the sorted array
    for (int i = 0; i < N + M; i++)
        cout << arr[i] << " ";
}
 
// Driver Code
int main()
{
    int N = 3;
    int M = 5;
    int arr[] = { 2, 8, 10, 17, 15,
                  23, 4, 12 };
    sortlastMElements(arr, N, M);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
 
// Function for merging the two sorted
// arrays
static void merge(int a[], int l, int m, int r)
{
    int s1 = m - l + 1;
    int s2 = r - m;
 
    // Create two temp arrays
    int left[] = new int[s1];
    int right[] = new int[s2];
 
    // Copy elements to left array
    for (int i = 0; i < s1; i++)
        left[i] = a[l + i];
 
    // Copy elements to right array
    for (int j = 0; j < s2; j++)
        right[j] = a[j + m + 1];
 
    int i = 0, j = 0, k = l;
 
    // Merge the array back into the
    // array over the range [l, r]
    while (i < s1 && j < s2) {
 
        // If the current left element
        // is smaller than the current
        // right element
        if (left[i] <= right[j]) {
            a[k] = left[i];
            i++;
        }
 
        // Otherwise
        else {
            a[k] = right[j];
            j++;
        }
        k++;
    }
 
    // Copy the remaining elements of
    // the array left[]
    while (i < s1) {
        a[k] = left[i];
        i++;
        k++;
    }
 
    // Copy the remaining elements of
    // the array right[]
    while (j < s2) {
        a[k] = right[j];
        j++;
        k++;
    }
}
 
// Function to sort the array over the
// range [l, r]
static void mergesort(int arr[], int l, int r)
{
    if (l < r) {
 
        // Find the middle index
        int mid = l + (r - l) / 2;
 
        // Recursively call for the
        // two halves
        mergesort(arr, l, mid);
        mergesort(arr, mid + 1, r);
 
        // Perform the merge operation
        merge(arr, l, mid, r);
    }
}
 
// Function to sort an array for the
// last m elements are unsorted
static void sortlastMElements(int arr[], int N,
                       int M)
{
    int s = M + N - 1;
 
    // Sort the last m elements
    mergesort(arr, N, s);
 
    // Merge the two sorted subarrays
    merge(arr, 0, N - 1, N + M - 1);
 
    // Print the sorted array
    for (int i = 0; i < N + M; i++)
         System.out.print( arr[i] + " ");
}
 
// Driver Code
public static void main(String[] args)
{
    int N = 3;
    int M = 5;
    int arr[] = { 2, 8, 10, 17, 15,
                  23, 4, 12 };
    sortlastMElements(arr, N, M);
}
}
 
// This code is contributed by code_hunt.


Python3
# Python3 program for the above approach
 
# Function for merging the two sorted
# arrays
def merge(a, l, m, r):
     
    s1 = m - l + 1
    s2 = r - m
 
    # Create two temp arrays
    left = [0 for i in range(s1)]
    right = [0 for i in range(s2)]
 
    # Copy elements to left array
    for i in range(s1):
        left[i] = a[l + i]
 
    # Copy elements to right array
    for j in range(s2):
        right[j] = a[j + m + 1]
         
    i = 0
    j = 0
    k = l
 
    # Merge the array back into the
    # array over the range [l, r]
    while (i < s1 and j < s2):
         
        # If the current left element
        # is smaller than the current
        # right element
        if (left[i] <= right[j]):
            a[k] = left[i]
            i += 1
 
        # Otherwise
        else:
            a[k] = right[j]
            j += 1
             
        k += 1
 
    # Copy the remaining elements of
    # the array left[]
    while (i < s1):
        a[k] = left[i]
        i += 1
        k += 1
 
    # Copy the remaining elements of
    # the array right[]
    while (j < s2):
        a[k] = right[j]
        j += 1
        k += 1
 
# Function to sort the array over the
# range [l, r]
def mergesort(arr, l,  r):
     
    if (l < r):
         
        # Find the middle index
        mid = l + (r - l) // 2
 
        # Recursively call for the
        # two halves
        mergesort(arr, l, mid)
        mergesort(arr, mid + 1, r)
 
        # Perform the merge operation
        merge(arr, l, mid, r)
 
# Function to sort an array for the
# last m elements are unsorted
def sortlastMElements(arr, N, M):
     
    s = M + N - 1
 
    # Sort the last m elements
    mergesort(arr, N, s)
 
    # Merge the two sorted subarrays
    merge(arr, 0, N - 1, N + M - 1)
 
    # Print the sorted array
    for i in range(N + M):
        print(arr[i], end = " ")
 
# Driver Code
if __name__ == '__main__':
     
    N = 3
    M = 5
    arr = [ 2, 8, 10, 17, 15, 23, 4, 12 ]
     
    sortlastMElements(arr, N, M)
     
# This code is contributed by ipg2016107


C#
// C# program for the above approach
using System;
class GFG
{
 
// Function for merging the two sorted
// arrays
static void merge(int[] a, int l, int m, int r)
{
    int s1 = m - l + 1;
    int s2 = r - m;
    int i = 0, j = 0;
  
    // Create two temp arrays
    int[] left = new int[s1];
    int[] right = new int[s2];
  
    // Copy elements to left array
    for (i = 0; i < s1; i++)
        left[i] = a[l + i];
  
    // Copy elements to right array
    for (j = 0; j < s2; j++)
        right[j] = a[j + m + 1];
  
    int k = l;
     
  
    // Merge the array back into the
    // array over the range [l, r]
    while (i < s1 && j < s2) {
  
        // If the current left element
        // is smaller than the current
        // right element
        if (left[i] <= right[j]) {
            a[k] = left[i];
            i++;
        }
  
        // Otherwise
        else {
            a[k] = right[j];
            j++;
        }
        k++;
    }
  
    // Copy the remaining elements of
    // the array left[]
    while (i < s1) {
        a[k] = left[i];
        i++;
        k++;
    }
  
    // Copy the remaining elements of
    // the array right[]
    while (j < s2) {
        a[k] = right[j];
        j++;
        k++;
    }
}
  
// Function to sort the array over the
// range [l, r]
static void mergesort(int[] arr, int l, int r)
{
    if (l < r) {
  
        // Find the middle index
        int mid = l + (r - l) / 2;
  
        // Recursively call for the
        // two halves
        mergesort(arr, l, mid);
        mergesort(arr, mid + 1, r);
  
        // Perform the merge operation
        merge(arr, l, mid, r);
    }
}
  
// Function to sort an array for the
// last m elements are unsorted
static void sortlastMElements(int[] arr, int N,
                       int M)
{
    int s = M + N - 1;
  
    // Sort the last m elements
    mergesort(arr, N, s);
  
    // Merge the two sorted subarrays
    merge(arr, 0, N - 1, N + M - 1);
  
    // Print the sorted array
    for (int i = 0; i < N + M; i++)
         Console.Write( arr[i] + " ");
}
 
// Driver code
static void Main()
{
    int N = 3;
    int M = 5;
    int[] arr = { 2, 8, 10, 17, 15,
                  23, 4, 12 };
    sortlastMElements(arr, N, M);
 
}
}
 
// This code is contributed by sanjoy_62.


Javascript


输出:
2 4 8 10 12 15 17 23

时间复杂度: O(M*log M)
辅助空间: O(N + M)