标签:排序
//排序汇总
#include<stdio.h>
#include <time.h>
#define arr_len(array) (sizeof(array) / sizeof(array[0]))
clock_t start_time, end_time;
void swap(int *arr, int i, int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
//1. 输出源数据
void print_arr(int *arr, int n){
int len = n;
int i = 0;
for(i; i < len; i++){
printf("%d ", arr[i]);
}
printf("\n");
}
//2. 冒泡排序
void bubble_sort(int *arr, int n){
start_time = clock();
int i = 0, j = 0;
int len = n;
for(i; i < len; i++){
for(j = len - 1; j > 0; j--){
if(arr[j] < arr[j - 1]){
swap(arr, j, j - 1);
}
}
}
end_time = clock();
printf("用时: %d ms\n", end_time - start_time);
}
//3. 选择排序
void select_sort(int *arr, int n){
start_time = clock();
int i = 0, j = 0;
int min = 0;
for(i; i < n; i ++){
min = i;
for(j = i + 1; j < n; j++){
if(arr[min] > arr[j]){
min = j; //存放最小值的下标
}
}
if(i != min){
swap(arr, i, min);
}
}
end_time = clock();
printf("用时: %d ms\n", end_time - start_time);
}
//4.插入排序
void insert_sort(int *arr, int len){
start_time = clock();
int i = 1, j = 0, index = 0, temp = 0;
for(i; i < len; i++){
temp = arr[i];
index = i;
for(j = i - 1; j >= 0; j--){
if(arr[j] > temp){
arr[j + 1] = arr[j];
index = j;
}
}
arr[index] = temp;
}
end_time = clock();
printf("用时: %d ms\n", end_time - start_time);
}
//5. 希尔排序 -- 基于插入排序实现
void shell_sort(int *arr, int len){
start_time = clock();
int i = 1, j = 0, index = 0, temp = 0;
int k = len / 2;
while(k){
for(i = k; i < len; i++){
temp = arr[i];
index = i;
for(j = i - k; j >= 0; j -= k){
if(arr[j] > temp){
arr[j + k] = arr[j];
index = j;
}
}
arr[index] = temp;
}
k /= 2;
}
end_time = clock();
printf("用时: %d ms\n", end_time - start_time);
}
//6. 快排序 -- 基于冒泡排序
void quick_sort(int *arr, int low, int high){
start_time = clock();
if(low >= high){
return;
}
int start = low;
int end = high;
int key = arr[start];
while(end > start){
//找右半部分小于key的值
while(start < end && arr[end] >= key) {
--end;
}
arr[start] = arr[end];
//找做半部分大于key的值
while(start < end && arr[start] <= key) {
++start;
}
arr[end] = arr[start];
}
arr[start] = key; //起始位置保留: 起始位置是while循环中的位置
quick_sort(arr, low, start - 1);
quick_sort(arr, start + 1, high) ;
end_time = clock();
printf("用时: %d ms\n", end_time - start_time);
}
//7. 堆排序 -- 基于选择排序
/*
1. 初始化大顶堆
2. 大顶堆和最后一个数据交换后, 在构建 大顶堆
注: 数组的坐标是从0开始的
*/
void heap_sort(int *arr, int len) {
start_time = clock();
int i = 0;
int p_len = len / 2 - 1; //坐标从0开始, 找最后一个 分支节点
//1. 初始化
for(i = p_len; i >= 0; i--) { //从最后一个分支到根节点(i = 0 为根结点)
heap_adjust(arr, i, len) ;
}
//2. 交换, 和 重构堆 注: 从根结点到最后一个分支遍历,效率更高些 否则 从下向上遍历, 会造成含有叶子结点的分支重复判断.
for(i = len - 1; i > 0; i--) { //最后一个结点(i = len - 1)和第一个结点(i = 0)交换
swap(arr, i, 0);
heap_adjust(arr, 0, i - 1); //从根结点开始从新构造 大顶堆 (i - 1表示 去除上次交换的最大值)
}
end_time = clock();
printf("用时: %d ms\n", end_time - start_time);
}
//构建大顶堆
void heap_adjust(int *arr, int s, int len){
int i = 0;
int temp = arr[s]; //保存分支节点的值
for(i = 2 * s + 1; i <= len - 1; i *= 2 + 1 ){ //遍历分支节点下的左右孩子结点(坐标从0开始所以 左孩子是2 * s + 1)
if(i + 1 < len && arr[i] < arr[i + 1]){ //找出左右孩子的最大值(i + 1 < len 用于判断下标是否越界)
++i;
}
if(temp > arr[i]){ //判断左右孩子是否比父节点的值大
break;
}
arr[s] = arr[i]; //如果大于父节点, 则赋值 (父节点保持最大值)
s = i;
}
arr[s] = temp; // 将父节点的值赋值给左孩子或右孩子(取决于上边)
}
int main(void){
int nums[] = {10,100,1000,10000,30000,50000};
int size = nums[0]; //默认是 10个数据
int m = 0, i = 0, num_len;
int arr1[size],arr2[size],arr3[size],arr4[size],arr5[size],arr6[size],arr7[size];
for(m = 0; m < size; m++){
int tmpNum = size - m;
arr1[m] = tmpNum;
arr2[m] = tmpNum;
arr3[m] = tmpNum;
arr4[m] = tmpNum;
arr5[m] = tmpNum;
arr6[m] = tmpNum;
}
int len = arr_len(arr1);
int option = 1;
printf(" 1. 输出源数据\n 2. 冒泡排序\n 3. 选择排序\n 4. 插入排序\n 5. 希尔排序\n 6. 快速排序\n 7. 堆排序\n 0. 退出\n");
while(option){
scanf("%d", &option);
switch(option){
case 1:
print_arr(arr1, len);
break;
case 2:
bubble_sort(arr1, len);
print_arr(arr1, len);
break;
case 3:
select_sort(arr2, len);
print_arr(arr2, len);
break;
case 4:
insert_sort(arr3, len);
print_arr(arr3, len);
break;
case 5:
shell_sort(arr4, len);
print_arr(arr4, len);
break;
case 6:
quick_sort(arr5, 0, len - 1);
print_arr(arr5, len);
break;
case 7:
heap_sort(arr6, len);
print_arr(arr6, len);
break;
case 0:
return 0;
break;
default:
printf(" 1. 输出源数据\n 2. 冒泡排序\n 3. 选择排序\n 4. 插入排序\n 5. 希尔排序\n 6. 快速排序\n 7. 堆排序\n 0. 退出\n");
break;
}
}
return 0;
}
注: 在main方法中 int size = nums[0]; 改动nums中的下标,就可以测试大数据了
我的一个同学 总结的还是挺好的 网址是:http://www.cnblogs.com/zyf-zhaoyafei/p/4658333.html
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:排序
原文地址:http://blog.csdn.net/u010187139/article/details/47154599