排序算法比较

利用随机函数产生30000个随机整数,利用插入排序、起泡排序、选择排序、快速排序、堆排序、归并排序等排序方法进行排序,并统计每一种排序上机所花费的时间。提示:用顺序存储结构。

// 排序算法比较
#include <stdio.h>
#include<time.h>
#include<stdlib.h>
#define numcnt 40000  // 30000时,有的对比不出来 
int num4[numcnt];
// 插入排序: 
void insert_sort(int a [], int n){
	int i=0,ii=0,temp=0;  
    for(i=1;i<n;i++)  //循环遍历 
    {
        temp=a[i];    //将temp每一次赋值为number[i] 
        ii=i-1;  
        while(ii>=0&&temp<a[ii])   
        {
            a[ii+1]=a[ii];    //将大的元素往前放 
            ii--; 
        }
        a[ii+1]=temp;    
    }
	// 测试,查看排序是否正确 
	for(i = 1; i < n; i++){
		if(a[i] < a[i-1]){
			printf("插入排序有错误!");	
			break;
		}
	}              
}

// 起泡排序
void bub_sort(int a[], int n)     
{
    int i,j,temp;    
    for (j=0;j<n-1;j++)     
    {                           
        for (i=0;i<n-1-j;i++)
        {
            if(a[i]>a[i+1])     //从大到小排就把左边的">"改为"<"
            {
                temp=a[i];      //a[i]与a[i+1](即a[i]后面那个) 交换
                a[i]=a[i+1];    //基本的交换原理"c=a;a=b;b=c" 
                a[i+1]=temp;
            }
        }
    }  
	// 测试,查看排序是否正确 
	for(i = 1; i < n; i++){
		if(a[i] < a[i-1]){
			printf("起泡排序有错误!");	
			break;
		}
	}   
} 

// 选择排序
void select_sort(int a[],int n)
{
	int i, j, index_nmax, tmp;
    for(i=0; i<n; i++) // 总共要找len-1次最大值,每次找最大值的区间 [0,len-i]
    {
        index_nmax = 0;
        for(j=1; j<n-i; j++) // 因为假设了0下标就是最大值,所以循环可以从1开始
        {
            if(a[j] > a[index_nmax])
            {
                index_nmax = j;
            }
        }        
        if(index_nmax != n-i-1) // 避免无意义的位置交换
        {
            tmp = a[index_nmax];
            a[index_nmax] = a[n-i-1];
            a[n-i-1] = tmp;
        }
    }  
	// 测试,查看排序是否正确 
	for(i = 1; i < n; i++){
		if(a[i] < a[i-1]){
			printf("选择排序有错误!");	
			break;
		}
	}    
}

// 快速排序 
void quick_sort(int left, int right)
{
    int i, j, c, temp;
    if(left>right)
        return;
    
    i= left;
    j= right;
    temp = num4[i];    

    while(i != j)
    {
        while(num4[j]>=temp && i<j)
        {
            j--;
        }
        
        while(num4[i]<=temp && i<j)
        {
            i++;
        }

        if(i<j)
        {
            c = num4[i];
            num4[i] = num4[j];
            num4[j] = c;
        }
    }
    
    //left为起始值(参照值)此时的I为第一次排序结束的最后值,与参照值交换位置
    num4[left] = num4[i];
    num4[i] = temp;

    //继续递归直到排序完成
    quick_sort(left, i-1);
    quick_sort(i+1, right);
}

// 堆排序
void HeapAdjust(int a[],int s,int m)//一次筛选的过程
{
    int rc,j;
    rc=a[s];
    for(j=2*s;j<=m;j=j*2)//通过循环沿较大的孩子结点向下筛选
    {
        if(j<m&&a[j]<a[j+1]) j++;//j为较大的记录的下标
        if(rc>a[j]) break;
        a[s]=a[j];s=j;
    }
    a[s]=rc;//插入
}
void Heap_Sort(int a[],int n)
{
    int temp,i;
    for(i=n/2;i>=0;i--)//通过循环初始化顶堆
    {
        HeapAdjust(a,i,n);
    }
    for(i=n-1;i>=0;i--)
    {
        temp=a[1];
        a[1]=a[i];
        a[i]=temp;//将堆顶记录与未排序的最后一个记录交换
        HeapAdjust(a,1,i-1);//重新调整为顶堆
    }
}

// 归并排序 
void merge(int arr[], int low, int mid, int high){
    int i, k, left_low, left_high, right_low, right_high;
    int *tmp = (int *)malloc((high-low+1)*sizeof(int));
    //申请空间,使其大小为两个
     left_low = low;
     left_high = mid;
     right_low = mid + 1;
     right_high = high;

    for(k=0; left_low<=left_high && right_low<=right_high; k++){  // 比较两个指针所指向的元素
        if(arr[left_low]<=arr[right_low]){
            tmp[k] = arr[left_low++];
        }else{
            tmp[k] = arr[right_low++];
        }
    }

    if(left_low <= left_high){  //若第一个序列有剩余,直接复制出来粘到合并序列尾
    //memcpy(tmp+k, arr+left_low, (left_high-left_low+l)*sizeof(int));
    for(i=left_low;i<=left_high;i++)
        tmp[k++] = arr[i];
    }

    if(right_low <= right_high){
    //若第二个序列有剩余,直接复制出来粘到合并序列尾
    //memcpy(tmp+k, arr+right_low, (right_high-right_low+1)*sizeof(int));
        for(i=right_low; i<=right_high; i++)
            tmp[k++] = arr[i];
    }

    for(i=0; i<high-low+1; i++)
        arr[low+i] = tmp[i];
    free(tmp);
    return;
}

void merge_sort(int arr[], unsigned int first, unsigned int last){
    int mid = 0;
    if(first<last){
        mid = (first+last)/2; /* 注意防止溢出 */
        /*mid = first/2 + last/2;*/
        //mid = (first & last) + ((first ^ last) >> 1);
        merge_sort(arr, first, mid);
        merge_sort(arr, mid+1,last);
        merge(arr,first,mid,last);
    }
    return;
}

int main(){
	int num[numcnt];  // 随机数 
	int num1[numcnt]; // 各个排序需要的数组 
	int num2[numcnt];
	int num3[numcnt];
	
	int num5[numcnt];
	int num6[numcnt];
	int i, j;
	
	clock_t start;
	srand(time(0));  //设置时间种子
	// 生成随机数: 
	for(i=0; i < numcnt; i++){
		num[i] = rand() % 1000;    //用rand函数生成0-1000的随机数
		num1[i] = num[i]; 
		num2[i] = num[i];
		num3[i] = num[i];
		num4[i] = num[i];
		num5[i] = num[i];
		num6[i] = num[i];
	}
	// 插入排序 
	start = clock();
	insert_sort(num1, numcnt); 
	printf( "插入排序-用时: %f ms
", (double)(clock() - start) );

	// 起泡排序
	start = clock();
	bub_sort(num2, numcnt);
	printf( "起泡排序-用时: %f ms
", (double)(clock() - start) );
	
	// 选择排序
	start = clock();
	select_sort(num3, numcnt);
	printf( "选择排序-用时: %f ms
", (double)(clock() - start) );
	
	// 快速排序
	start = clock();
	quick_sort( 0, numcnt-1);
	// 测试,查看排序是否正确 
	for(i = 1; i < numcnt; i++){
		if(num4[i] < num4[i-1]){
			printf("快速排序有错误!");	
			break;
		}
	}
	printf( "快速排序-用时: %f ms
", (double)(clock() - start) );
	
	// 堆排序
	start = clock();
	Heap_Sort(num5, numcnt);
	printf( "堆排序-用时: %f ms
", (double)(clock() - start) );
	
	// 归并排序
	start = clock();
	merge_sort(num6, 0, numcnt-1);
	printf( "归并排序-用时: %f ms
", (double)(clock() - start) );
	
	return 0;
}

  

原文地址:https://www.cnblogs.com/zhumengdexiaobai/p/12931774.html