标题:就来冒泡一下~写个冒泡排序玩玩~
取消只看楼主
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
结帖率:99.25%
已结贴  问题点数:20 回复次数:10 
就来冒泡一下~写个冒泡排序玩玩~
写了个通用性较强的冒泡法排序~就是感觉输出样式需要的话可以改改~还有如果要进行二级排序则要另外写比较函数了~不过总体感觉还是不错的~
原谅没啥时间写注释了~

程序代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>

#ifndef MY_SORT
#define My_SORT

#define List_Size sizeof(SqList)

typedef struct SqList
{
    void* Data;                   //抽象储存数据类型
    void** Point;                 //抽象数据指针类型
    size_t len;                      //数组长度
    size_t size;                     //单位数组元素规模大小

}SqList,*PSqList;

void Sort(void* a,size_t len,size_t Data_Size,int (*Comp)(void* a,void* b));     //创建一个节点

void Swap(void* a,void* b,size_t size);
void Get_Data(PSqList L,void* a);

void Fun(PSqList L,int (*Comp)(void* a,void* b));   //冒泡法排序

void Del_List(PSqList* L);
void Del_Data(void** p);

void Sort(void* a,size_t len,size_t Data_Size,int (*Comp)(void* a,void* b))
{
    PSqList L=NULL;

    size_t i=0;

    L=(PSqList)malloc(List_Size);

    assert(L!=NULL);
    memset(L,0,List_Size);

    L->size=Data_Size;
    L->len=len;


    L->Data=malloc(L->size*len);
    assert(L->Data!=NULL);
    memset(L->Data,0,L->size*len);
    memcpy(L->Data,a,Data_Size*len);

    L->Point=malloc(sizeof(void** )*L->len);
    assert(L->Point!=NULL);
    memset(L->Point,0,sizeof(void** )*L->len);

    for (i=0;i!=len;++i)
        L->Point[i]=(char* )L->Data+i*L->size;

    Fun(L,Comp);
    Get_Data(L,a);

    Del_List(&L);


}

void Get_Data(PSqList L,void* a)
{
    size_t i=0;

    for (i=0;i!=L->len;++i)
        memcpy((char* )a+i*L->size,(char* )L->Point[i],L->size);
}

void Swap(void* a,void* b,size_t size)
{
    size_t t=0;

    memcpy(&t,a,size);
    memcpy(a,b,size);
    memcpy(b,&t,size);
}

void Fun(PSqList L,int (*Comp)(void* a,void* b))
{
    size_t i=0;
    size_t j=0;

    for (i=0;i<L->len;++i)
        for (j=0;j<L->len-i-1;++j)
            if ((*Comp)((char* )L->Point[j],(char* )L->Point[j+1])==1)
                Swap(L->Point[j],L->Point[j+1],L->size);   
}

void Del_Data(void** p)
{
    if (*p==NULL)
        return ;

    free(*p);
    *p=NULL;
}

void Del_List(PSqList* L)
{
    if (*L==NULL)
        return ;

    Del_Data(&(char* )(*L)->Point);
    Del_Data(&(*L)->Data);
    Del_Data(L);
}

#endif






程序代码:
#include"Sort.h"
#include<time.h>

#define NUM 10
typedef int ElemType;

int Comp(void* a,void* b);
void Init(ElemType a[]);
void Print(ElemType a[]);

int main()
{
    ElemType a[NUM]={0};

    Init(a);
    Print(a);

    Sort(a,NUM,sizeof(ElemType),Comp);

    Print(a);

    return 0;
}

int Comp(void* a,void* b)
{
    ElemType at=*(ElemType*)a;
    ElemType bt=*(ElemType*)b;

    if (at>bt)
        return 1;

    if (at<bt)
        return -1;

    return 0;
}

void Init(ElemType a[])
{
    int i=0;

    srand((unsigned )time(NULL));

    for (i=0;i!=NUM;++i)
        a[i]=rand()%(NUM*10);
}

void Print(ElemType a[])
{
    int i=0;

    for (i=0;i!=NUM;++i)
        printf("%-4d ",a[i]);

    puts("");
}


[此贴子已经被作者于2017-5-8 19:22编辑过]

搜索更多相关主题的帖子: size void Point int NULL 
2017-05-08 07:28
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
就是无聊写来玩玩~感觉和那个qsort封装过的快排还是有差距的~改改可以改成qsort那款样式了~不过比较函数通用却要能解决多级排序问题才行~不过一级排序还是可以做到通用的~顺便提一下没有全面测试~可能会存在bug~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-05-08 07:51
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
回复 3楼 renkejun1942
其实不做通用比较函数会省事很多~至于链表排序~用双向链表进行插入和删除工作会省事很多~交换指针值域~看来要用个指针数组才行啊~这个可以试一下~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-05-08 10:06
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
突然考虑到一个问题~小数和实数不能按内存块数值大小进行比较~~看来还是老老实实写比较函数好~~~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-05-08 18:28
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
还是把它改成了qsort的函数的形式~到头来还是觉得这样实用性较强~~~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-05-08 19:24
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
回复 7楼 renkejun1942
我也受教了~~
记得老师叫我学冒泡法排序的时候也是用这种方法~~不过我在老师教之前已经学会这种写法了~现在回头看看还是有收获的~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-05-08 19:50
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
回复 9楼 renkejun1942
程序代码:
void sort(int * a, int len)
{
    int i,j;
    int t;

    for( i = 0; i < len; ++i )
        for( j = i + 1; j < len; ++j )
            if( a[ i ] > a[ j ] )
            {
                t = a[ i ];
                a[ i ] = a[ j ];
                a[ j ] = t;
            }
}


你这样写i<len和j=i+1;j<len不会越界么?~~~~
感觉是i<len-1

而且t=a[i];a[i]=a[j];a[j]=t;这样不连续比较感觉这样冒泡不太生动~~~倒是像比较排序的改编~网上还有一种写法是~

程序代码:
    for(i=0;i<10-1;i++)    
        {//n个数要进行n-1趟比较  
        for(j=i+1;j<10;j++)          //每趟比较n-i次  
            if(a[j-1]>a[j])          //依次比较两个相邻的数,将小数放在前面,大数放在后面  
            {  
                int t=a[j];  
                a[j]=a[j+1];  
                a[j+1]=t;  
            }  
    }  


感觉相邻两个数交换可读性更高~可以参考一下~~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-05-08 20:01
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
回复 11楼 renkejun1942
想到了个题外话~

从减少运算次数方面考虑
你说i=i+1和i+=1和i++比较是不是i++的执行效率会高些呢~

看到几乎所有for循环都是写i++而没有什么人会去写i=i+1的~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-05-08 20:10
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
回复 13楼 renkejun1942
程序代码:
#include<stdio.h>
#include<time.h>
int main()
{
    double duration=0;
    int i=0;
    int s=10;
    clock_t TIME_START=0;
    clock_t TIME_END=0;

    while (s--)
    {
        TIME_START=clock();

        for (i=0;i<100000000;++i);

        TIME_END=clock();

        duration=(double)(TIME_END-TIME_START)/CLOCKS_PER_SEC;

        printf("%f\n",duration);
  
        TIME_START=clock();

         for (i=0;i<100000000;i++);

        TIME_END=clock();

        duration=(double)(TIME_END-TIME_START)/CLOCKS_PER_SEC;
   
        printf("%f\n\n",duration);
    }

    return 0;
}


感觉其实差不多~也许是小范围内运算差距不大~


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-05-08 20:42
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
回复 17楼 renkejun1942
我的对比过也是一样耶~

程序代码:
    .file    "a.c"
    .def    ___main;    .scl    2;    .type    32;    .endef
    .text
    .align 2
.globl _main
    .def    _main;    .scl    2;    .type    32;    .endef
_main:
    pushl    %ebp
    movl    %esp, %ebp
    subl    $8, %esp
    andl    $-16, %esp
    movl    $0, %eax
    addl    $15, %eax
    addl    $15, %eax
    shrl    $4, %eax
    sall    $4, %eax
    movl    %eax, -8(%ebp)
    movl    -8(%ebp), %eax
    call    __alloca
    call    ___main
    movl    $0, -4(%ebp)
    leal    -4(%ebp), %eax
    incl    (%eax)
    movl    $0, %eax
    leave
    ret

好像我的真的不是gcc5.3.0这个没有显示gcc版本~~~~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-05-08 21:09



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-476788-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.536742 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved