C语言的简单应用(五)下

来源:互联网 发布:下载淘宝2016新版本 编辑:程序博客网 时间:2024/06/05 19:14

选择排序:简单选择排序、堆排序

简单选择排序(平均时间O(n²),不稳定)

#include<stdio.h>#define max 10void simplesort(int a[],int len){    int i,j,k,temp;    for(i=1;i<=len-1;i++)    {            k=i;        for(j=i+1;j<=len;j++)          if(a[k]>a[j])            k=j;          if(k!=i)          {            temp=a[i];            a[i]=a[k];            a[k]=temp;          }     }}int main(){    int i,len,a[max];    printf("input the len:");    scanf("%d",&len);    for(i=1;i<=len;i++)    {        printf("a[%d]=",i);        scanf("%d",&a[i]);    }    simplesort(a,len);    puts("the simplesort order:");    for(i=1;i<=len;i++)    printf("%d ",a[i]);    return 0;}

推排序(平均时间O(n㏒₂n),不稳定)

简单选择排序的每次排序除了找到当前最小的关键字外,还产生了许多时间开销大的比较的结果信息,但并没有利用这些信息。堆排序(Heap Sort)是针对简单选择排序所存在的上述问题改进的一种方法。
堆的一些特征
1、是一颗完全二叉树
2、每个节点值均小于(大于)或等于它的两个孩子节点(如果存在的话)的值
3、树根节点(称为堆顶元素)的值最小(称为小顶堆)或最大(称为大顶堆)。故堆顶元素必为最小(或最大)

堆排序基本思想

堆中元素采用数组方式存储,只是将数组存储的记录看成一颗完全二叉树的节点 ,并利用完全二叉树中双亲节点与左右孩子节点的内在关系来进行排序。具体过程:将一组用数组存储的待排序的记录,首先把它们按堆的定义组成一个堆,将堆顶元素取出;然后把剩下的记录再建成堆;如此反复,直到取出全部元素,从而将全部记录排序为有序序列。

实施步骤

一、 序列转换为完全二叉树:对于任意位置,若父节点的位置为i,则它的两个子节点分别位于2i和2i+1。

二、 建堆(将完全二叉树调整为为堆):

1、从中间节点开始调整。
2、找出以此节点为父节点的两个孩子节点的较小值(或较大值),并与父节点比较,若小(大)则与父节点进行交换。然后以交换后的子节点作为新的父节点。重复此步骤直到没有子节点。
3、将步骤2中原来父节点的位置往前推一个位置,作为新的父节点。重复步骤2,直到根节点位置,此时完全二茶树将称为一个堆。

三、 堆排序:输出堆顶元素后,调整剩余n-1个节点,使其关键字成为一个新堆。
1、输出堆顶节点,将堆顶元素与堆底(最后一个)节点交换
2、从根节点开始,重复第步骤中的2
3、1,共进行n-1次,直到只剩下根节点并把该根节点输出为止。

完整代码

#include<stdio.h>#define max 10void sift(int a[],int k,int n) {    int i,j,x,t,mark;    t=a[k];    x=a[k];    i=k;    j=2*i;    mark=0;    while(j<=n&&!mark)    {        if(j<n&&a[j]>a[j+1])            j++;        if(x<=a[j])            mark=1;        else         {            a[i]=a[j];            i=j;            j=2*i;        }    }    a[i]=t;}void creatheap(int a[],int len){    int i;    for(i=len/2;i>=1;i--)    sift(a,i,len);}void heapsort(int a[],int len){    int i,temp;    creatheap(a,len);    for(i=len;i>=2;i--)    {        temp=a[i];        a[i]=a[1];        a[1]=temp;        sift(a,1,i-1);    }}int main(){    int i,j,len,a[max];    printf("input the len:");    scanf("%d",&len);    for(i=1;i<=len;i++)    {        printf("a[%d]=",i);        scanf("%d",&a[i]);    }    heapsort(a,len);    printf("the heapsort order:");    for(i=len;i>=1;i--)    printf("%d ",a[i]);    return 0;}

归并排序(平均时间O(n㏒₂n),稳定)多用于外部排序

归并排序(Merging Sort)是指将两个或两个以上的有序序列合并为一个新的有序序列)

#include<stdio.h>#define max 10void merge(int a[],int low ,int mid,int high,int b[]){    int i,j,k;    i=low;    j=mid+1;    k=low;    while((i<=mid)&&(j<=high))    {        if(a[i]<=a[j])        {            b[k]=a[i];            i++;            k++;        }        else {            b[k]=a[j];            j++;            k++;        }    }    while(i<=mid)    {        b[k]=a[i];        k++;        i++;    }    while(j<=high)    {        b[k]=a[j];        k++;        j++;    }}void msort(int a[],int low ,int high,int b[]){    int mid;    int c[max];    if(low==high)    b[low]=a[low];    else    {        mid=(low+high)/2;        msort(a,low,mid,c);        msort(a,mid+1,high,c);        merge(c,low,mid,high,b);    }}int main(){    int i,j,len,a[max];    printf("input the len:");    scanf("%d",&len);    for(i=1;i<=len;i++)    {        printf("a[%d]=",i);        scanf("%d",&a[i]);    }    msort(a,1,len,a);    printf("the sort order:");    for(i=1;i<=len;i++)    printf("%d ",a[i]);    return 0;}

总结

终于。。。完成了对数据结构的梳理与归纳,但还远远不够,比起应用来说这还还不够,数据结构是门好学科,特别是里面的排序算法,我个人认为学起来很舒服,让人感觉很充实,当然,对于数据结构这门课来说,我认为前面的链表和堆栈队列部分是重中之重,它们真可谓是数据结构的基石部分啊,唯有对这些基石达到应用自如的地步,后面的树、图都不是什么难点,说实话,现在回过头来看看以前的知识盲点,我发觉还是以前没有用心,没能沉下心来好好阅读,量变引起质变,这句话可谓是真理,从7月10号到今天,大约一个礼拜的时间,每天的代码量保持在200+,感觉敲敲代码也不是什么特别费脑子的事情,反而敲之前的沉思倒花去了大半的时间,实践是检验真理的唯一标准,哈哈哈,开始新的征服之旅啦!

原创粉丝点击