排序算法实例

前三章都讲解了三种排序算法---------桶排序、冒泡排序、快速排序,本文就来运用这些算法牛刀小试一波。

一、问题描述

输入有两行,第一行为一个正整数n,接着第二行输入n个数字(当然n个数字之间有间隔,不能连载一起),这个n个数字可以有重复的

输出有两行,第一行输出这k个数字排序, 第二行统计输入n个数字共有k个不同的数字(即 k<=n)。

示例:

输入:

10
20 40 32 67 40 20 89 300 400 15

输出:
15 20 32 40 67 89 300 400
8

二、代码示例及分析

2.1 桶排序

#include<stdio.h>
#define N 1001

// 此程序采用桶排序  先去重在排序 

void init(int array[])
{
    int i;
    for(i=0;i<N;++i)
        array[i] = 0;
}

int main()
{
    int array[N];    // 对于数字较小的话 可以采用这种方法      
    int i,t,n,k;
    
    while(scanf("%d",&n)!=EOF)
    {
        
        init(array);
        k=0;
        
        for(i=0;i<n;++i)
        {
            scanf("%d",&t);
            array[t] = 1;
        }
        printf("\n\n--------输出结果为-------\n\n");
        for(i=0;i<N;++i)
        {
            if(array[i]==1)  // 如果数字出现过则打印
            {
                k++;
                printf("%d\t",i);
            }
            
        }
        printf("\n%d\n",k);
         
    }
    return 0;
}

时间复杂度大约为O(N+M),效率较高,但是缺点也很明显,数组不可能很大,对输入的数字要求有限制,针对浮点数或大数字的时候,此算法不合适

2.2 冒泡排序

#include<stdio.h>
#define N 101

// 采用冒泡排序  先排序再去重 

int main()
{
    int n,a[N];
    int i,j,len,temp,k;
    
    while(scanf("%d",&n)!=EOF)
    {
        for(i=0;i<n;++i)
            scanf("%d",&a[i]);
        k = 0;
        // bubble sort (From small to big)
        len = n;
        while(--len)
        {
            for(j=0;j<len;++j)
            {
                if(a[j]>a[j+1])
                {
                    temp = a[j];
                    a[j] = a[j+1];
                    a[j+1] = temp;
                }
            }    
        }
        
        //  去重 ,先输出第一个数 
        printf("\n%d\t",a[0]);
        for(i=1;i<n;++i)
        {
            if(a[i-1]!=a[i])
            {
                printf("%d\t",a[i]);
                k++;
            }
        } 
    
        printf("\n%d\n",k+1); // 带上第一个输出的    
    }    
    return 0;
}

时间复杂度O(N^2)   当对大量数据排序时  此算法的时间效率太低了,可以采用快速排序

2.3 快速排序

#include<stdio.h> 
#include<string.h>
#define N 100
 
void quickSort(int array[],int left,int right)
{ 
    int i = left;
    int j = right;
    int value = array[left],temp;    // 得到哨兵元素
    // 异常处理,保证right >= left 
    if(left>right)
        return;
    
    while(i < j)
    {
        // 从右向左找一个比基准数小的 
        while(value<=array[j] && i<j) j--;
        // 从左到右找一个比基数大的
        while(value>=array[i] && i<j)  i++;
        // 当i,j没相遇时  交换两者位置
        if(i < j)
        {
            temp = array[j];
            array[j] = array[i];
            array[i] = temp;
        }
        
    }    
    // 最终基准归位 
    if(i == j)
    {
        array[left] = array[i];
        array[i] = value;
    } 
    
    // 递归调用基准数划分的左右两组序列
    quickSort(array,left,i-1);
    quickSort(array,i+1,right); 
    
}

int main()
{
    int n,k=0,i,array[N]; // n表示要输入排序元素的个数
    scanf("%d",&n);
    for(i=0;i<n;++i)
    {
        scanf("%d",&array[i]);
    } 
    
    // 调用排序函数
    quickSort(array,0,n-1);
    
    //  去重 ,先输出第一个数 
    printf("\n%d\t",array[0]);
    for(i=1;i<n;++i)
    {
        if(array[i-1]!=array[i])
        {
            printf("%d\t",array[i]);
            k++;
        }
    } 
    printf("\n%d\n",k+1); // 带上第一个输出的     
    
    return 0;
}

时间复杂度O(nlogn)   针对大量数字时,此算法的优势会明显提升

 以上三个算法的 示例代码运行的结果 如下所示:

 -----------------------------------------------------------------------------------------------------------------------------------------------

以上就是对这三种排序算法的总结,针对不同情况适当的选取,没有哪种算法是最好的,只有在特定的情况下,适当的选取,会让你的程序更有效率

  

猜你喜欢

转载自www.cnblogs.com/guohaoblog/p/9211638.html