4.9排序优化实现

排序优化,如何实现一个通用的高效的排序算法

比如linux系统最底层的api几乎其他所有库都会依赖glibc,下面讲一下glibc中c语言实现的qsort()方法实现

1.qsort()优先使用归并算法

虽然空间o(n)但在所需大小很小时,问题不大,空间换时间,实现快速

2.如果超过100mb,qsort()使用快排

分界点使用三数取中,防止递归深度导致栈溢出,递归实现通过手动模拟递归实现

3.当快排区间元素小于等于4时,qsort()退化为插入排序

因为小规模数据,o(n^2)不一定比o(nlogn)慢,时间复杂度不一定等于实际运行时间

比如java中Arrays.sort()采用TimSort方法

1.元素个数<32

二分查找插入排序

2.元素个数>=32

归并算法,归并算法核心是分区,以连续升序或降序为分区,最终调为升序入栈,如果分区太小采用二分查找插入排序扩充分区长度到最小值

补:二分查找上,针对有序的数列,思想是分治思想,类似数学中的特值法猜测答案,每次都给中间元素比,省掉一半区间,可以实现o(logn)对数级别非常恐怖的时间复杂度,有时比o(1)还更有效(常量可以是10000,但对数就是100),下面以不存在重复元素举例

1.非递归实现

public int bsearch(int[] a, int n, int value) {

  int low = 0;

  int high = n - 1;

  while (low <= high) {

    int mid = (low + high) / 2;

    if (a[mid] == value) {

      return mid;

    } else if (a[mid] < value) {

      low = mid + 1;

    } else {

      high = mid - 1;

    }

  }

  return -1;

}

注:

i.循环退出条件low<=high要取等

ii.在low,high比较大的时候,mid会溢出,可用low+(high-low)/2,还可以优化为low+((high-low)>>1)(因为运算优先级)

iii.high,low更新

2.递归实现

// 二分查找的递归实现

public int bsearch(int[] a, int n, int val) {

  return bsearchInternally(a, 0, n - 1, val);

}

private int bsearchInternally(int[] a, int low, int high, int value) {

  if (low > high) return -1;

  int mid =  low + ((high - low) >> 1);

  if (a[mid] == value) {

    return mid;

  } else if (a[mid] < value) {

    return bsearchInternally(a, mid+1, high, value);

  } else {

    return bsearchInternally(a, low, mid-1, value);

  }

}

注:分治递归,必须写明数组对象和对象的具体区间

3.限定条件

二分查找只能用于数组储存和数据有序,且数据量不能太小(直接顺序遍历就好了)也不能太大(毕竟用数组存储,消耗太大)

4.课后题

实现一个数平方根,精确小数后6位数

解:二分法思想核心循环区间二分,通过中点来精确查找目标数值的区间,最后实现近似值和准确值,特别类似数学方法中的近似值

i*i=x,比如[0,x],找到区间中点m,检查m*m与x大小比较,若m*m>x取[0,m]反之则取[m,x],直到区间长度小于10(^-6)

你可能感兴趣的:(4.9排序优化实现)