快速排序在C语言和java下的实现

1. 快排的原理

时隔多日我们在被要求去写一个快速排序的时候可能无从下手,对于一个算法的考单纯的记忆不足以牢牢掌握它,深刻理解其机制才是学习算法的重要手段。

下面我们来解读一下快速排序。

快速排序动态演示

快速排序由东尼·霍尔所发展。快速排序通常明显比其他 Ο(nlogn) 算法更快。在平均状况下,排序 n 个项目要 Ο(nlogn) 次比较。在最坏状况下则需要 Ο(n2) 次比较,但这种状况并不常见。

快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。快速排序又是一种分而治之思想在排序算法上的典型应用。本质上来看,快速排序应该算是在冒泡排序基础上的递归分治法递归分治是快排的核心。

快速排序的最坏运行情况是 O(n²),比如说顺序数列的快排。但它的平摊期望时间是 O(nlogn),且 O(nlogn)
记号中隐含的常数因子很小,比复杂度稳定等于 O(nlogn)
的归并排序要小很多。所以,对绝大多数顺序性较弱的随机数列而言,快速排序总是优于归并排序。

2. 用C实现快排

思路:

  1. 对于一个给定的数组,从中间位置选择一个元素,以该元素为界将其余元素划分为两个子集,一个子集中的元素都小于该元素,另一个子集中的元素都大于或等于该元素。
  2. 对这样的两个子集递归执行这一过程,当某一个子集中的元素的个数小于2时,这个子集就不需要再次排序,终止递归。

代码实现:

void swap(int v[],int i,int j)//用以交换
			{
				int temp;
				temp = v[i];
				v[i] = v[j];
				v[j] = temp;
			}
				
void quick_sort(int v[],int left,int right)
			{
				int i,last;
				if(left >= right)
				{
					return ;
				}
				swap(v,left,(left+right)/2);  //(left+right)/2 为基准点
				last = left;
				for(i = left + 1;i <= right;i++)
				{
					if(v[i] < v[left])
					{
						swap(v,++last,i);
					}
				}
				quick_sort(v,left,last);
				quick_sort(v,left,last-1);
				quick_sort(v,last+1,right);
			}

但是也可以不用递归

typedef struct _Range {
    int start, end;
} Range;

Range new_Range(int s, int e) {
    Range r;
    r.start = s;
    r.end = e;
    return r;
}

void swap(int *x, int *y) {
    int t = *x;
    *x = *y;
    *y = t;
}

void quick_sort(int arr[], const int len) {
    if (len <= 0)
        return; // 避免发生段错误
    // r[]为模拟列表,p为数量,r[p++]为push,r[--p]为pop且取得元素
    Range r[len];
    int p = 0;
    r[p++] = new_Range(0, len - 1);
    while (p) {
        Range range = r[--p];
        if (range.start >= range.end)
            continue;
        int mid = arr[(range.start + range.end) / 2]; // 选取中间点
        int left = range.start, right = range.end;
        do {
            while (arr[left] < mid) ++left;   // 检测左侧是否符合要求
            while (arr[right] > mid) --right; //检测右侧是否符合要求
            if (left <= right) {
                swap(&arr[left], &arr[right]);
                left++;
                right--; // 移动指针
            }
        } while (left <= right);
        if (range.start < right) r[p++] = new_Range(range.start, right);
        if (range.end > left) r[p++] = new_Range(left, range.end);
    }
}
3. 用java实现快排

java实现,思路和c的基本一样

public class QuickSort implements IArraySort {

    @Override
    public int[] sort(int[] sourceArray) throws Exception {
        // 对 arr 进行复制,不改变参数内容
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);

        return quick_sort(arr, 0, arr.length - 1);
    }

    private int[] quick_sort(int[] arr, int left, int right) {
        if (left < right) {
            int partitionIndex = partition(arr, left, right);
            quick_sort(arr, left, partitionIndex - 1);
            quick_sort(arr, partitionIndex + 1, right);
        }
        return arr;
    }

    private int partition(int[] arr, int left, int right) {
        // 设定基准值(pivot)
        int pivot = left;
        int index = pivot + 1;
        for (int i = index; i <= right; i++) {
            if (arr[i] < arr[pivot]) {
                swap(arr, i, index);
                index++;
            }
        }
        swap(arr, pivot, index - 1);
        return index - 1;
    }

    private void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值