其他分享
首页 > 其他分享> > hackerank-30 days of code-day 20 -sorting

hackerank-30 days of code-day 20 -sorting

作者:互联网

1.这道题有关于数组的排序问题,关于sorting,主要有以下几种algorithm:
(以下很多代码来自geekforgeek https://www.geeksforgeeks.org/sorting-algorithms/)

  1. selection sort
    选择排序算法通过从未排序部分重复查找最小元素(考虑升序)并将其放在开头来对数组进行排序。该算法在给定数组中维护两个子数组。

1)已排序的子数组。
2)未排序的剩余子数组。

在选择排序的每次迭代中,都会从未排序的子数组中选取最小元素(考虑升序)并将其移至已排序的子数组。

arr [] = 64 25 12 22 11

//在arr [0 ... 4]中查找最小元素
//并将其放在开头
11 25 12 22 64

//在arr [1 ... 4]中查找最小元素
//并将其放在arr [1 ... 4]的开头
11 12 25 22 64

//在arr [2 ... 4]中找到最小元素
//并将其放在arr [2 ... 4]的开头
11 12 22 25 64

//在arr [3 ... 4]中查找最小元素
//并将其放在arr [3 ... 4]的开头
11 12 22 25 64

2.bubble sort
实质与selection sort 相反, 先排号最右边的最大数,因此为两个for loop
看下来自geekfor geek的简单代码

void swap(int *xp, int *yp)  
{  
    int temp = *xp;  
    *xp = *yp;  
    *yp = temp;  
}  
  
// A function to implement bubble sort  
void bubbleSort(int arr[], int n)  
{  
    int i, j;  
    for (i = 0; i < n-1; i++)      
      
    // Last i elements are already in place  
    for (j = 0; j < n-i-1; j++)  
        if (arr[j] > arr[j+1])  
            swap(&arr[j], &arr[j+1]);  
}  
  1. recursive bubble sort
    递归的想法。

1)基本情况:如果数组大小为1,则返回。
2)一遍普通气泡排序。此遍可修复当前子数组的最后一个元素。
3)对于除当前子数组的最后一个元素之外的所有元素,均重复执行。

// A function to implement bubble sort 
void bubbleSort(int arr[], int n) 
{ 
    // Base case 
    if (n == 1) 
        return; 
  
    // One pass of bubble sort. After 
    // this pass, the largest element 
    // is moved (or bubbled) to end. 
    for (int i=0; i<n-1; i++) 
        if (arr[i] > arr[i+1]) 
            swap(arr[i], arr[i+1]); 
  
    // Largest element is fixed, 
    // recur for remaining array 
    bubbleSort(arr, n-1); 
} 

4.insertion sort
arr []
循环,从i = 1到n-1。
……a)选择元素arr [i]并将其插入排序后的序列arr [0…i-1]
原理:
1)从i=1开始到最后一个元素, 用whileloop找到新元素需要在的位置,期间,将大于key 的都位置+1,为后面找到位置腾出空位出来

/* Function to sort an array using insertion sort*/
void insertionSort(int arr[], int n)  
{  
    int i, key, j;  
    for (i = 1; i < n; i++) 
    {  
        key = arr[i];  
        j = i - 1;  
  
        /* Move elements of arr[0..i-1], that are  
        greater than key, to one position ahead  
        of their current position */
        while (j >= 0 && arr[j] > key) 
        {  
            arr[j + 1] = arr[j];  
            j = j - 1;  
        }  
        arr[j + 1] = key;  
    }  
}  

5.recursive insertion sort
总结一下就是recursive需要考虑在n-1重复的案例的先后,比如bubble sort是在筛选出最大数以后整理剩下的n-1 个重复项, 而insertion sort是需要整理好n-1个重复项得到倒数第二个元素,然后再添加back。

// Recursive function to sort an array using 
// insertion sort 
void insertionSortRecursive(int arr[], int n) 
{ 
    // Base case 
    if (n <= 1) 
        return; 
  
    // Sort first n-1 elements 
    insertionSortRecursive( arr, n-1 ); 
  
    // Insert last element at its correct position 
    // in sorted array. 
    int last = arr[n-1]; 
    int j = n-2; 
  
    /* Move elements of arr[0..i-1], that are 
      greater than key, to one position ahead 
      of their current position */
    while (j >= 0 && arr[j] > last) 
    { 
        arr[j+1] = arr[j]; 
        j--; 
    } 
    arr[j+1] = last; 
} 
  1. merge sort
    像QuickSort一样,合并排序是一种分而治之算法。它将输入数组分为两半,将自己称为两半,然后合并两个排序的两半。merge()函数用于合并两个半部分。
// Merges two subarrays of arr[]. 
// First subarray is arr[l..m] 
// Second subarray is arr[m+1..r] 
void merge(int arr[], int l, int m, int r) 
{ 
    int i, j, k; 
    int n1 = m - l + 1; 
    int n2 =  r - m; 
  
    /* create temp arrays */
    int L[n1], R[n2]; 
  
    /* Copy data to temp arrays L[] and R[] */
    for (i = 0; i < n1; i++) 
        L[i] = arr[l + i]; 
    for (j = 0; j < n2; j++) 
        R[j] = arr[m + 1+ j]; 
  
    /* Merge the temp arrays back into arr[l..r]*/
    i = 0; // Initial index of first subarray 
    j = 0; // Initial index of second subarray 
    k = l; // Initial index of merged subarray 
    while (i < n1 && j < n2) 
    { 
        if (L[i] <= R[j]) 
        { 
            arr[k] = L[i]; 
            i++; 
        } 
        else
        { 
            arr[k] = R[j]; 
            j++; 
        } 
        k++; 
    } 
  
    /* Copy the remaining elements of L[], if there 
       are any */
    while (i < n1) 
    { 
        arr[k] = L[i]; 
        i++; 
        k++; 
    } 
  
    /* Copy the remaining elements of R[], if there 
       are any */
    while (j < n2) 
    { 
        arr[k] = R[j]; 
        j++; 
        k++; 
    } 
} 
  
/* l is for left index and r is right index of the 
   sub-array of arr to be sorted */
void mergeSort(int arr[], int l, int r) 
{ 
    if (l < r) 
    { 
        // Same as (l+r)/2, but avoids overflow for 
        // large l and h 
        int m = l+(r-l)/2; 
  
        // Sort first and second halves 
        mergeSort(arr, l, m); 
        mergeSort(arr, m+1, r); 
  
        merge(arr, l, m, r); 
    } 
} 

7.quick sort
把最后一个元素放到恰当的位置然后分成两部分循环进行sorting

// A utility function to swap two elements  
void swap(int* a, int* b)  
{  
    int t = *a;  
    *a = *b;  
    *b = t;  
}  
  
/* This function takes last element as pivot, places  
the pivot element at its correct position in sorted  
array, and places all smaller (smaller than pivot)  
to left of pivot and all greater elements to right  
of pivot */
int partition (int arr[], int low, int high)  
{  
    int pivot = arr[high]; // pivot  
    int i = (low - 1); // Index of smaller element  
  
    for (int j = low; j <= high - 1; j++)  
    {  
        // If current element is smaller than the pivot  
        if (arr[j] < pivot)  
        {  
            i++; // increment index of smaller element  
            swap(&arr[i], &arr[j]);  
        }  
    }  
    swap(&arr[i + 1], &arr[high]);  
    return (i + 1);  
}  
  
/* The main function that implements QuickSort  
arr[] --> Array to be sorted,  
low --> Starting index,  
high --> Ending index */
void quickSort(int arr[], int low, int high)  
{  
    if (low < high)  
    {  
        /* pi is partitioning index, arr[p] is now  
        at right place */
        int pi = partition(arr, low, high);  
  
        // Separately sort elements before  
        // partition and after partition  
        quickSort(arr, low, pi - 1);  
        quickSort(arr, pi + 1, high);  
    }  
}  

8 heap sort
在这之前需要先明白它是怎么由数组形式变成树图的, root,第一层的左,第一层的右, 第二层的左,第二层的右。

Input data: 4, 10, 3, 5, 1
         4(0)
        /   \
     10(1)   3(2)
    /   \
 5(3)    1(4)
 括号中的数字表示数组中的索引 
数据表示。

将heapify过程应用于索引1:
         4(0)
        / \
    10(1)3(2)
    / \
5(3)1(4)

将heapify过程应用于索引0:
        10(0)
        / \
     5(1)3(2)
    / \
 4(3)1(4)
heapify过程以递归方式调用自身以构建堆
 以自上而下的方式。

代码如下

// To heapify a subtree rooted with node i which is 
// an index in arr[]. n is size of heap 
void heapify(int arr[], int n, int i) 
{ 
   int largest = i; // Initialize largest as root 
   int l = 2*i + 1; // left = 2*i + 1 
   int r = 2*i + 2; // right = 2*i + 2 
 
   // If left child is larger than root 
   if (l < n && arr[l] > arr[largest]) 
       largest = l; 
 
   // If right child is larger than largest so far 
   if (r < n && arr[r] > arr[largest]) 
       largest = r; 
 
   // If largest is not root 
   if (largest != i) 
   { 
       swap(arr[i], arr[largest]); 
 
       // Recursively heapify the affected sub-tree 
       heapify(arr, n, largest); 
   } 
} 
 
// main function to do heap sort 
void heapSort(int arr[], int n) 
{ 
   // Build heap (rearrange array) 
   for (int i = n / 2 - 1; i >= 0; i--) 
       heapify(arr, n, i); 
 
   // One by one extract an element from heap 
   for (int i=n-1; i>=0; i--) 
   { 
       // Move current root to end 
       swap(arr[0], arr[i]); 
 
       // call max heapify on the reduced heap 
       heapify(arr, i, 0); 
   } 
} 

heapify 函数做的是先得到最大数的index, 然后进行循环subtree,
heap函数做的是先建立heap,然后把最大数置换到最后,然后对剩下的n-1个元素进行重新heapify。

后面还有几种sorting algorithm, 后面再介绍。。。

有态度的我 发布了23 篇原创文章 · 获赞 0 · 访问量 339 私信 关注

标签:sort,arr,code,20,hackerank,int,void,heapify,largest
来源: https://blog.csdn.net/weixin_42919657/article/details/104106955