排序算法

排序

快速排序

1、快速排序

快速排序的基本思想是基于分治法的:设从小到大排序,在待排序表 L[1…n]中任取一个元素pivot作为枢纽(或基准,通常取首元素),通过一趟排序将待排序表划分为独立的两个部分L[1…k-1]和L[k+1…n],使得k左边的元素都小于pivot,右边的元素都大于pivot,则pivot放在了最终位置L[k]处,这个过程叫做一趟快速排序(或一次划分)。然后分别递归地对两个子表重复上述过程,直到每部分内只有一个元素或空为止。
快排的时间复杂度为O(nlog2n),是所有内部排序算法中平均性能最优的排序算法,但是是一种不稳定的排序算法。
算法如下:

/**
  *快速排序,确定枢纽的位置,左边值都比枢纽值小,右边都比枢纽大
  *@param arr 要排序的数组
  *@param low 数组区左端点,默认该值为枢纽
  *@param high 数组区间右端点
  *@return 返回枢纽最终位置(整个排序的最终位置)
*/
int partition (int arr[], int low, int high){
	int pivot = arr[low];
	while( low < high ){
        while(low < high && arr[high] >= pivot){
			high --;
		}
		arr[low] = arr[high];
		while(low < high && arr[low] <= pivot){
			low ++;
		}
		arr[high] = arr[low];
	}
	arr[low] = pivot;
	return low;
}

/**
  *快速排序
  *@param arr 要排序的数组
  *@param low 数组区左端点
  *@param high 数组区间右端点
*/
void quick_sort(int arr[], int low, int high){
    if(low < high){
		int pivot_pos = partition(arr, low, high);
		quick_sort(arr, low, pivot_pos - 1);
		quick_sort(arr, pivot_pos + 1, high);
	}
}

2、基于快速排序,查找第m小的元素

因为快排每次排序确定的枢纽位置都是最终位置,所以边排序边判断枢纽的位置是否为题目要求的位置

/**
  *快速排序,确定枢纽的位置,左边值都比枢纽值小,右边都比枢纽大
  *先判断枢纽值的位置是否为要查的位置,否则分别再向左、右排序
  *@param arr_birth 要排序的数组
  *@param low 要排序的数组区间左端点
  *@param high 要排序的数组区间右端点
  *@param n 第m位置
  *@return 返回枢纽值
*/
int quick_sort (int arr[], int low, int high,int m){
	int low_tmp = low;
	int high_tmp = high;
	int pivot = arr[low];
	while( low < high ){
        while(low < high && arr[high] >= pivot){
			high --;
		}
		arr[low] = arr[high];
		while(low < high && arr[low] <= pivot){
			low ++;
		}
		arr[high] = arr[low];
	}
	arr[low] = pivot;
	if(low == m ){
		return arr[low];
	}else if ( low < m){
		return quick_sort(arr, low+1, high_tmp,m);
	}else{
		return quick_sort(arr, low_tmp, low-1,m);
	}	
}

2、折半插入排序

折半插入排序仅仅是减少了比较元素的次数,约为O(log2 n),该比较次数与待排序表的初始状态无关,仅取决于表中元素的个数;而元素的移动次数未改变,它依赖于待排序表的初始状态。因此,该排序的时间复杂度为O(n2),但对于数据量不大的排序表,该排序算法往往能表现出很好的性能。
折半插入排序是一种稳定的排序算法。

/**
  *折半插入排序,数据量不大时,性能较好且稳定
  *@param arr 要排序的数组
  *@param n 数组大小
*/
void insert_sort(int arr[] ,int n){
	int i, j, low, high, mid;
	int tmp;
	for(i = 1 ; i < n ; i ++){
        tmp = arr[i];
		low = 0;
		high = i - 1;
		while (low <= high){
			mid = (low + high) / 2;
			if( arr[mid] > tmp ){
				high = mid - 1;
			}else{
				low = mid + 1;
			}
		}
		for(j = i-1; j >= high+1; j --){
			arr[j+1] = arr[j];
		}
		arr[high + 1] = tmp;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值