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

程序代码:
#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
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
得分:20 
qsort函数的原型已经指明了实现的思路。

qsort( void *array, size_t length, size_t size, int ( * )( void *, void * ) )

多级排序并不需要由排序函数去做,而是比较函数来干。

要实现通用,就不能让做太多的事,其他的事让使用者自己去弄。排序就只干排序,比较之类的事情,那是使用者自己的事。


链表排序,我想的思路是链表转数组,然后交换每一个节点的值域就行了。
因此,可以用任一排序算法来做。
工作太忙,都这么久了,都没动手。
留存一下,等搜索树搞定了,再回来看看。

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


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-05-08 09:11
九转星河
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
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
得分:0 
回复 6楼 九转星河
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);   
}

你的这个冒泡排序,跟另外一个帖子的冒泡排序几乎是一样的,所以你可以看一下我在那个帖子的分析,为什么这样写会比j = i+1的写法更慢。

当然如果你自己知道的话,那就不用浪费时间看了。

https://bbs.bccn.net/thread-476779-1-1.html

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


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-05-08 19:29
九转星河
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
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
得分:0 
回复 8楼 九转星河
冒泡排序我是自己写的,而且一开始就是j = i + 1的写法,甚至于在很久之后我才知道原来这就叫冒泡排序。

好吧,冒泡排序也是我唯一会的排序,哈哈。

09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-05-08 19:51
九转星河
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



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




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

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