排序——选择排序、冒泡排序和快速排序比较

1、选择排序思路:
一、以 int 类型为例
二、拿第一个数与后面数相比较,若是比后面的数大则交换
三、拿第二个数与后面的数比较,若是比后面的数大则交换
四、直到比较到倒数第二个数,最后一个数不用比较
五、两个数比较能够用中间变量替换或者位运算
六、利用位运算时需注意,若是两个数相等则不能使用位运算
七、函数代码以下:
void SelectSort(int array[], size_t size)
{
	size_t i, j;
	for (i=0; i<size-1; i++)
		for (j=size-1; j>i; j--)
			if (array[i] > array[j])
			{
				array[i] = array[i] ^ array[j];
				array[j] = array[i] ^ array[j];
				array[i] = array[i] ^ array[j];
			}
}

2、冒泡排序思路:函数

一、以 int 类型为例
二、每轮依次比较相邻两个数的大小,后面比前面小则交换
三、代码以下:
void RubbleSort(int array[], size_t size)
{
	size_t i, j;
	for (i=0; i<size-1; i++)
		for (j=0; j<size-1-i; j++)
			if (array[j] > array[j+1])
			{
				array[j]   = array[j] ^ array[j+1];
				array[j+1] = array[j] ^ array[j+1];
				array[j]   = array[j] ^ array[j+1];
			}
}
3、快速排序思路:
一、以 int 类型为例
二、选择第一个数为基点,右边 j 开始查找比基点小的数中止,再从左边 i 查找比基点数大的数停住
三、调换 i、j 对应的数后执行步骤 2,知道 i 和 j 相遇,此时 i == j
四、调换 i 对应的数和基点数,将源数列一分为 2 后分别重复步骤 二、三、4,知道结束
五、注意使用位运算调换时必须判断交换两个数不能相等,不然第二个数为 0
六、函数代码以下:
void QuickSort(int array[], int left, int right)
{
	if (left >= right)
		return;
	int i, j;
	int tmp;
	i = left;
	j = right;

	while (i < j)
	{
		while (array[j]>=array[left] && i<j)
			j--;
		while (array[i]<=array[left] && i<j)
			i++;

		tmp = array[i];
		array[i] = array[j];
		array[j] = tmp;
	}
	
	tmp = array[left];
	array[left] = array[i];
	array[i] = tmp;

	QuickSort(array, left, i-1);
	QuickSort(array, i+1, right);
}
4、冒泡排序和快速排序比较:
一、选择排序不稳定,时间复杂度为 O(n2)
二、冒泡排序稳定,时间复杂度为 O(n2)
三、快速排序不稳定,时间复杂度为 O(nlogn)
四、对于 100000 个随机数排序,选择排序约 20s,冒泡排序约 60s,快排约 0.02s
五、代码以下:
/*************************************************************************
  > File Name: sort.c
  > Author: Wenfei6316
  > Mail: Wenfei6316@163.com 
  > Created Time: 2018年06月16日 星期六 11时34分48秒
 ************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

#define LEN	100000


//选择排序
void SelectSort(int array[], size_t size)
{
	size_t i, j;
	for (i=0; i<size-1; i++)
		for (j=size-1; j>i; j--)
			if (array[i] > array[j])
			{
				array[i] = array[i] ^ array[j];
				array[j] = array[i] ^ array[j];
				array[i] = array[i] ^ array[j];
			}
}


//冒泡排序
void RubbleSort(int array[], size_t size)
{
	size_t i, j;
	for (i=0; i<size-1; i++)
		for (j=0; j<size-1-i; j++)
			if (array[j] > array[j+1])
			{
				array[j]   = array[j] ^ array[j+1];
				array[j+1] = array[j] ^ array[j+1];
				array[j]   = array[j] ^ array[j+1];
			}
}

//快速排序
void QuickSort(int array[], int left, int right)
{
	if (left >= right)
		return;
	int i, j;
	int tmp;
	i = left;
	j = right;

	while (i < j)
	{
		while (array[j]>=array[left] && i<j)
			j--;
		while (array[i]<=array[left] && i<j)
			i++;

		tmp = array[i];
		array[i] = array[j];
		array[j] = tmp;
	}
	
	tmp = array[left];
	array[left] = array[i];
	array[i] = tmp;

	QuickSort(array, left, i-1);
	QuickSort(array, i+1, right);
}

int main(int argc, const char *argv[])
{
	int i;
	clock_t start, end;
	int *a, *b, *c;
	a = (int *)malloc(sizeof(int)*LEN);
	if (a == NULL)
	{
		perror("Create a failed");
		return EXIT_FAILURE;
	}
	
	b = (int *)malloc(sizeof(int)*LEN);
	if (b == NULL)
	{
		perror("Create b failed");
		return EXIT_FAILURE;
	}
	c = (int *)malloc(sizeof(int)*LEN);
	if (c == NULL)
	{
		perror("Create c failed");
		return EXIT_FAILURE;
	}

	srand(time(NULL));
	for (i = 0; i<LEN; i++)
	{
		a[i] = rand() % 10000;
		c[i] = b[i] = a[i];
	}

	printf("a[100] = %d b[100] = %d c[100] = %d\n", a[100], b[100], c[100]);

	start = clock();
	SelectSort(a, LEN);
	end = clock();
	printf("end - start = %lf seconds\n", (double)(end-start)/CLOCKS_PER_SEC);

	start = clock();
	RubbleSort(b, LEN);
	end = clock();
	printf("end - start = %lf seconds\n", (double)(end-start)/CLOCKS_PER_SEC);

	start = clock();
	QuickSort(c, 0, LEN-1);
	end = clock();
	printf("end - start = %lf seconds\n", (double)(end-start)/CLOCKS_PER_SEC);

	printf("a[100] = %d b[100] = %d c[100] = %d\n", a[100], b[100], c[100]);
	
	return 0;
}
     六、运行结果以下: