【问题标题】:Combine insertion sort with quick sort function relationship结合插入排序与快速排序函数关系
【发布时间】:2019-09-09 20:02:45
【问题描述】:

混合排序:
数组 A 的元素索引从 int p 到 int r,我们最初通过快速排序方法对 A[] 进行排序,枢轴最初放在数组的末尾,然后递归调用快速排序,但是由于数组中的元素数是小于 t,那么我们停止调用快速排序并通过插入排序对其余元素进行排序,混合函数应该只返回调用插入排序的次数。 main函数打印出调用插入排序的次数。

我多次编写此代码,但函数关系总是如此混乱,大量的错误信息我无法诊断。 而且我不知道为什么它在实践中比结合 random_quick_sort 更快。谢谢

#include<stdio.h>
#include<stdlib.h>
// hybrid quick sort
int hybridsort(int A[], int p, int q, int t);

int  main() {
  int n = 9, t = 3;
  int A[9] = {1, 8, 6, 3, 2, 7, 4, 9, 10};

  for(int i = 0; i < 9; i++)printf(" %d", A[i]);
  printf("\n");

  int res = hybridsort(A, 0, n - 1, t);// rest
  printf("No. of calls = %d\n",res);

  for(int i = 0; i< 9; i++)printf("%d", A[i]);
  printf("\n");

  return 0;
}
int hybridsort(int A[], int p, int r, int t){
  int n, count;
  count = 0;
  int i, j, key;
  n = p - r + 1;
  // if No.elements < t, # of insertion sort gets called
  if(n >= t && p > r ){
      quicksort(A, p, r);
    }
    else{
      // insertionsort
      count = count + 1;
      for(j = 1; j < 6; j++){
      key = A[j];
      i = j - 1;
      while(i > -1 && A[i] > key){
      A[i + 1] = A[i];
      i = i - 1;
    }
    A[i + 1] = key;
   }

 }
}

return count;
}
void quicksort(int A[], int p, int r){
  int q ;
  if(p < r){

    q = partition(A, p,r);
    quicksort(A, p, q - 1);
    quicksort(A, q + 1, r);
  }
}

int partition(int A[], int p, int r){
  int x, i, j, tmp;
  x = A[r];//pivot
  i = p - 1;
  for(j = p; j < r; j++){
    if(A[j] <= x){
      i += 1;
      tmp = A[i];
      A[i] = A[j];
      A[j] = tmp;
    }

  }
  tmp = A[i + 1];
  A[i + 1] = A[r];
  A[r] = tmp;
  return i + 1 ;// pivot index position after sorting

}

【问题讨论】:

  • 对于混合插入+快速排序,对于较小的子数组大小,快速排序应该调用插入排序。在我的回答中,如果 size

标签: quicksort insertion-sort hybrid


【解决方案1】:

混合快速 + 插入排序示例。主程序会调用 QuickSort(),它会调用 InsertionSort 来处理子数组大小

void InsertionSort(int a[], size_t lo, size_t hi)
{
size_t i = lo+1;
size_t j;
int t;
    while(i <= hi){
        t = a[i];
        j = i;
        while((j > lo) && a[j-1] > t){
            a[j] = a[j-1];
            j -= 1;
        }
    a[j] = t;
    i += 1;
    }
}

void QuickSort(int a[], size_t lo, size_t hi)
{
    if(lo >= hi)
        return;
    if((hi-lo) < 32){
        InsertionSort(a, lo, hi);
        return;
    }
    int pivot = a[lo + (hi - lo) / 2];
    int t;
    size_t i = lo - 1;
    size_t j = hi + 1;
    while(1)
    {
        while (a[++i] < pivot);
        while (a[--j] > pivot);
        if (i >= j)
            break;
        t = a[i];
        a[i] = a[j];
        a[j] = t;
    }
    QuickSort(a, lo, j);
    QuickSort(a, j + 1, hi);
}

【讨论】:

  • 虽然它是最坏情况时间为 O(n2) 的基本排序算法之一,但插入排序是当数据接近排序(因为它是自适应的)或当问题规模小(因为它的开销低)。由于这些原因,并且由于它也很稳定,插入排序通常用作递归基本情况(当问题规模较小时),用于更高开销的分治排序算法,例如归并排序或快速排序。 toptal.com/developers/sorting-algorithms#我从其他帖子看到的
  • 感谢一开始的鼓励,我觉得我的代码像垃圾code.visualstudio.com/docs/editor/debugging,我尝试使用工具调试但是这次我真的不知道为什么我的代码不起作用.您能否给我进一步评论代码是可能的?我看到你回答了很多关于排序一些超出我理解的技术分析的问题,所以我现在主要关注代码
  • int pivot = a[lo + (hi - lo) / 2];这与 'int pivot = (lo + hi)/2' 一样吗?但是您的版本允许程序在元素 _num > t 的每个子数组上选择中间枢轴并避免溢出?基本上选择随机枢轴是一样的吗?
  • 混合函数应该只返回调用插入排序的次数。这是一个硬件问题,他们只使用了混合排序和 main(只有两个函数)
  • 我要切换到初学者论坛是不是太容易了^^?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-30
  • 2020-07-30
  • 1970-01-01
  • 2020-01-31
  • 2013-02-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多