您的位置:首页 > 其它

[算法学习笔记]几个排序算法的比较

2016-07-24 15:58 417 查看
前面的文章实现了六中排序算法, 分别是插入排序, 冒泡排序, 选择排序, 归并排序, 堆排序以及快速排序

当数组大小为100时它们的表现为:



明显看出冒泡和选择算法的速度较慢

当数组大小为1W时:



最快的是快排算法, 其次归并排序算法, 对于插入排序来说,面对较大数量时, 性能下降明显

当数组大小为10W时:



最快的快速排序算法和最慢的冒泡排序算法差了2000倍

当然每台计算的性能都不同, 所以结果也会有不同, 有兴趣的同学可以自己尝试:

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define MAX_N  100000      // 数组长度

// 冒泡排序
void bubbleSort(int []);
// 插入排序
void insertionSort(int []);
//选择排序
void selectionSort(int []);
// 归并排序
void merge(int [], int, int, int, int []);
void mergeSort(int [], int, int, int []);

// 堆排序
#define PARENT(i) i >> 1            // 取得父节点的下标
#define LEFT(i) i << 1              // 取得左边子节点的下标
#define RIGHT(i) (i << 1) + 1       // 取得右边子节点的下标

void swap(int *, int *);            // 交换函数
void maxHeapify(int [], int);       // 用于维护堆的性质
void bulidMaxHeap(int []);          // 建堆
void heapSort(int []);              // 堆排序

int heapSize = MAX_N;               // 堆大小,排序时自减

// 快速排序(非随机化)
void quickSort(int [], int, int);
int partition(int [], int, int);

int main(){
int nums[MAX_N], temp[MAX_N];
int i;
// 存放带排序的数组
int bubbleSortArray[MAX_N];
int insertionSortArray[MAX_N];
int selectionSortArray[MAX_N];
int mergeSortArray[MAX_N];
int heapSortArray[MAX_N];
int quickSortArray[MAX_N];
// 用于测试各排序算法的花费时间
clock_t start, finish;
double spendTime;

srand((unsigned)time(0));
for(i = 0; i < MAX_N; i++){
nums[i] = rand() % (MAX_N * 2);
bubbleSortArray[i] = nums[i];
insertionSortArray[i] = nums[i];
selectionSortArray[i] = nums[i];
mergeSortArray[i] = nums[i];
heapSortArray[i+1] = nums[i];
quickSortArray[i] = nums[i];
}

printf("当前数组大小: %d\n", MAX_N);

start = clock();
bubbleSort(bubbleSortArray);
finish = clock();
spendTime = (double)(finish - start) / CLOCKS_PER_SEC;
printf("冒泡排序算法花费时间为%lf秒.\n", spendTime);

start = clock();
insertionSort(insertionSortArray);
finish = clock();
spendTime = (double)(finish - start) / CLOCKS_PER_SEC;
printf("插入排序算法花费时间为%lf秒.\n", spendTime);

start = clock();
selectionSort(selectionSortArray);
finish = clock();
spendTime = (double)(finish - start) / CLOCKS_PER_SEC;
printf("选择排序算法花费时间为%lf秒.\n", spendTime);

start = clock();
mergeSort(mergeSortArray, 0, MAX_N - 1, temp);
finish = clock();
spendTime = (double)(finish - start) / CLOCKS_PER_SEC;
printf("归并排序算法花费时间为%lf秒.\n", spendTime);

start = clock();
heapSort(heapSortArray);
finish = clock();
spendTime = (double)(finish - start) / CLOCKS_PER_SEC;
printf("堆排序算法花费时间为%lf秒.\n", spendTime);

start = clock();
quickSort(quickSortArray, 0, MAX_N - 1);
finish = clock();
spendTime = (double)(finish - start) / CLOCKS_PER_SEC;
printf("快速排序算法花费时间为%lf秒.\n", spendTime);

return 0;
}

// 冒泡排序
void bubbleSort(int nums[]){
int i, j, temp;
for(i = 0; i < MAX_N - 1; i++){
for(j = 0; j < MAX_N - 1 - i; j++ ){
if(nums[j] > nums[j+1]){
swap(nums + j, nums + j + 1);
}
}
}
}

// 插入排序
void insertionSort(int num[]){
int i;
for(i = 1; i < MAX_N; i++){
int key = num[i];    int j = i - 1;
while(j >= 0 && num[j] > key){
num[j + 1] = num[j];
j--;
}
num[j + 1] = key;
}
}

// 选择排序
void selectionSort(int nums[]){
int i, j, temp, index;
for(int i = 0; i < MAX_N - 1; i++){
index = i;
for(j = i + 1; j < MAX_N; j++){
if(nums[j] < nums[index])
index = j;
}
if(index != i){
temp = nums[i];
nums[i] = nums[index];
nums[index] = temp;
}
}
}

/*******************
* 归并排序
* array :数组
* left :起始下标值
* mid : 中间下标值
* right : 结束下标值
* temp : 用于存放临时数组
********************/
void merge(int array[], int left, int mid, int right, int temp[]){
int i = left, j = mid + 1;
int k = 0;
while(i <= mid && j <= right){
if(array[i] < array[j])
temp[k++] = array[i++];
else
temp[k++] = array[j++];
}

while(i <= mid)
temp[k++] = array[i++];

while(j <= left)
temp[k++] = array[j++];

for(i = 0; i < k; i++)
array[left + i] = temp[i];
}

void mergeSort(int array[], int left, int right, int temp[]){
if(left < right){
int mid = (left + right) / 2;
mergeSort(array, left, mid, temp);
mergeSort(array, mid + 1, right, temp);
merge(array, left, mid, right, temp);
}
}

// 堆排序
void swap(int *a, int *b){
int temp = *a;
*a = *b;
*b = temp;
}

void maxHeapify(int nums[], int i){
int l = LEFT(i);    // 取得左子节点的下标
int r = RIGHT(i);   // 取得右子节点的下标
int largest;        // 当前节点和左右两个子节点中最大的值的下标
if(l <= heapSize && nums[l] > nums[i])
largest = l;
else
largest = i;
if(r <= heapSize && nums[r] > nums[largest])
largest = r;
if(largest != i){
swap(nums+i, nums+largest);
maxHeapify(nums, largest);
}
}

void bulidMaxHeap(int nums[]){
int i;
for(i = MAX_N/2; i >= 1; i--){
maxHeapify(nums, i);
}
}

// 快速排序
void heapSort(int nums[]){
bulidMaxHeap(nums);
int i;
heapSize = MAX_N;
for(i = MAX_N; i >= 2; i--){
swap(nums + 1, nums + i);
heapSize--;
maxHeapify(nums, 1);
}
}

void quickSort(int nums[], int p, int r){
if(p < r){
int q = partition(nums, p, r);
quickSort(nums, p, q - 1);
quickSort(nums, q + 1, r);
}
}

int partition(int nums[], int p, int r){
int x = nums[r];
int i = p - 1, j;
for(j = p; j < r; j++){
if(nums[j] <= x){
i++;
swap(nums+i, nums+j);
}
}
swap(nums+i+1, nums+r);

return i+1;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息