基本排序算法


1 冒泡排序

/**基本思路每次从数组中最后一个开始,如果是比前一个值小,就交换,然后判断下一个,向数组开始冒泡

* 这样每次都是取得当前范围内的最小值

*/

void BubbleSort(int *a, int n)
{
    int i = 0;
    int j = 0;
    int flag = 0;

    if ( NULL == a || n == 1 || n == 0) {
        return ;
    }

    for (i = 0; i < n; ++i) {
        flag = 0;
        for (j = n - 1; j > i; --j) {
            if (a[j] < a[j-1]) {
                swap(&a[j], &a[j - 1]);
                flag = 1;
            }
        }/*end of for*/
        if (!flag) {
            break;
        }
    }/*end of for*/

}


2 选择排序

/**每次从后面的范围中选择一个最小的数,放到有序数组的后面*/

void SelectSort(int *a, int n)
{
    int i,j;
    int min = 0;

    if ( NULL == a || n == 1 || n == 0) {
        return ;
    }

    for  (i = 0; i < n - 1; ++i) {
        min = i;
        for (j = i + 1; j < n; ++j) {
            if (a[i] < a[j]) {
                min = j;
            }
        }
        if (min != i) {
            swap(&a[i], &a[min]);
        }
    }
}

3 插入排序

/**假设前面的数组已经排序好了,依次从未排序数组中选择一个数,插入到已排序数组中

* 循环过程为:对于每个未排序的数字,如果其值小于已排序中的数,则已排序的数字可以向后移动

*  否则第一个不小于该值的已排序数的前一个就是这个数应该存放的位置

*/

void InsertSort(int *a, int n)
{
    int i = 0;
    int j = 0;
    int k = 0;

    for ( i = 1; i < n; ++i) {
        k = a[i];
        for (j = i - 1; j >= 0; --j) {
            if ( k < a[j] ) {
                a[j + 1] = a[j];
            } else {
                break;
            }
        }
        a[j+1] = k;
    }
}

/*插入排序,下面的代码更加简洁*/
void InsertSort(int *a, int n)
{
    int i,j;
    int t;

    if (NULL == a || n == 0 || n == 1) {
        return ;
    }

    for (i = 1; i < n; ++i) {
        t = a[i];
        for (j = i; j > 0 && t < a[j - 1]; --j) {
            a[j] = a[j - 1];
        }
        a[j] = t;
    }

}

4 快速排序


如果有这样一个函数,从无序数组中选择一个数,将比这个数小的放到这个数的前面,大的放到后面。最后虽然数组还是无序的,但是这个数却在正确的位置上。(原因在于,假设这个数在已排序数组中的位置为k,这个数小的都在其前面,就意味着前面的数一定在[0,k-1] 的区间。这个数显然是第k个。)

现在只要分别对由这个数划分出来的两个部分进行递归,最终即可得到有序数组。

注意split函数中的是否需要使用等于的情况:

在比较元素大小时,如果加上等于,当所有元素都相同时,split会返回low+1;而如果没有等于,会增加交换次数,但是split会返回(low + high)/2,从而降低了最坏情况下的时间复杂度。

int split(int *a, int low, int high)
{
    int h = high + 1;
    int l = low;
    int s = a[low];

	if (low >= high) {
		return low;
	}
	
    while (1) {
	/*注意,这里不能是h >= low,否则循环退出后,h可能不可访问
        * a[h] > s 以及下面的a[l] < s不使用等号的原因
        * 在于当元素相等时虽然增加了交换次数,却使得整个算法的时间为nlogn而不是n2
        */	
        while (--h > low && a[h] > s) ;

        while (++l <= high && a[l] < s);

        if (l >= h) {
            break;
        } else {
            swap(&a[l], &a[h]);
        }
    }

    swap(&a[h], &a[low]);

    return h;

}

void qsort(int *a, int low, int high)
{
    int s = 0;

    if (low >= high) return ;

    s = split(a, low, high);

    qsort(a, low, s - 1);

    qsort(a, s + 1, high);

}












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值