C语言下排序算法详解

C语言下排序算法详解

  • 选择排序法
  • 冒泡排序法
  • 交换排序法
  • 插入排序法
  • 折半(二分排序法)

yuanli xing 东西就不在这里赘述了,直接上代码先,原理的东西都在代码上面有注释:
sort.h

#ifndef __SORT_H_
#define __SORT_H_

//选择排序算法
extern void selectSort(int *num_pointer,const int num);

//冒泡排序算法
extern void bubbleSort(int *num_pointer,const int num);

//冒泡排序算法2
extern void bubbleSort2(int *num_pointer,const int num);

//交换排序算法
extern void swapSort(int *num_pointer,const int num);

//插入排序法则
extern void insertSort(int *num_pointer,const int num);

//折半排序法则
extern void celeritySort(int *num_pointer,const int num);
#endif

sort.c

#include"sort.h"
#include"swap.h"

/**
*选择排序法则:9,6,8,7,3
*算法规则:每一次将数组中的最大的那个数值筛选出来,将这个值提取出来,与最前面没有进行排序的数组元素进行比较
*那前面没有比较的数值的次数就是整个数组长度-1次,这也是外层循环的次数
*内层循环也就是从没有比较数组的后面一个数值开始,假设当前没有比较的元素的位置是i的话,那么开始项的位置就是i+1
*
*注意:选择排序法只是将最大的数值的位置记录下来,最后再进行一次互换,所以默认有一个记录的下标;用来记录位置,即pos
*然后用后续的元素与这个最大的数值进行比较
*
*选择排序在整个排序过程中进行了N*(N-1)/2次排序,适用于数组数量比较小的数组
*/
extern void selectSort(int *num_pointer,const int num){
    int pos;
    int i_count = 0;
    int j_count = 0;

    int *pointer = num_pointer;
    for( i_count = 0; i_count < num-1; i_count++) {
        pos = i_count;
        for(j_count = i_count + 1;j_count < num; j_count++) {
            if(*(pointer+pos) < *(pointer+j_count)){
                pos = j_count;
            }
        }
        if(pos != i_count){
            swap(pointer+i_count,pointer+pos);
        }
    }
    printf_array(num_pointer,num);
}

/**
*冒泡排序法则:
*算法规则:冒泡排序法则是在排序的时候,每一次都是去比较相邻的两个数组的数值a[j]与a[j+1]比较,如果需要swap就会立马进行swap,从而将最大的数值筛选出来,然后后一次的比较从前一个最大值的位置下一位元素开始,所以外层的循环为(数组长度-1)次
*内层循环次数:如果是从数组的0位置开始比较的话,那么循环的内层比较次数为(数组长度-i-1)
*如果是从最后一个位置开始来进行比较的话,内层的比较条件为(j=数组长度-1,j>=i;j--);
*
*注意:不同的方向进行比较的时候,其判别条件也是不一样的 
*
*冒泡排序最好的是正序,只要一次,最差的是逆序,需要n×n次,冒泡排序相对是比较稳定的一种排序法,如果数组稍微有序,则效果是比较好的
*/
extern void bubbleSort(int *num_pointer,const int num){
    int i_count = 0;
    int j_count = 0;
    int *pointer = num_pointer;
    for(i_count = 0;i_count<num;i_count++){
        for(j_count = 0;j_count<num-i_count-1;j_count++){
            if(*(pointer+j_count) < *(pointer+j_count+1)){
                swap(pointer+j_count,pointer+j_count+1);
            }
        }
    }
    printf_array(num_pointer,num);
}

extern void bubbleSort2(int *num_pointer,const int num){
    int i_count = 0;
    int j_count = 0;
    int *pointer = num_pointer;
    for(i_count = 1;i_count < num ;i_count++){
        for(j_count = num -1 ;j_count >= i_count;j_count--){
            if(*(pointer+j_count) >  *(pointer+j_count-1)){
                swap(pointer+j_count,pointer+j_count-1);
            }
        }
    }
    printf_array(num_pointer,num);
}


/**
*交换排序法则:每一次比较都会进行一次互换,比较的前一个数值从0,到num-1
*比较的后值从1,num;(从前数值的后一项开始的,即从i_count+1开始);
*
*注意:在每一次比较的时候都是会进行交换的
*
*与冒泡排序是一样的,正序是最快的,而倒序是最慢的,所以数组稍微有序的时候,效果是比较好的
*/
extern void swapSort(int *num_pointer,const int num){
    int i_count;
    int j_count;
    int *pointer = num_pointer;
    for(i_count = 0; i_count < num-1;i_count++){
        for(j_count=i_count + 1;j_count < num ;j_count++){
            if(*(pointer+i_count) < *(pointer+j_count)){
                swap(pointer+i_count,pointer+j_count);
            }
        }
    }
    printf_array(num_pointer,num);
}

/**
*插入排序法则
*
*插入排序法则相对是比较复杂,其根本工作原理就是抽出一个数据,在前面的数据中寻找相应的位置,然后进行插入,然后继续下一个数据,一直到数据完成排序
*1:首先取出第一数值
*2:取出第二个数值,如果第二个数值大于第一个数值,就放在第一个的后面。如果小于就放前面
*3:取出第三个数值,与最后一个数值进行比较,如果大于就放后面。如果小于,就与前面一个数值进行比较,再判断放在前面还是后面
*4:以此类推,总是先与最后一个数值进行比较
*
*优点:如果数组有序那么会具有较快的运算速度 
*/
extern void insertSort(int *num_pointer,const int num){
    int i_count = 0;
    int *pointer = num_pointer;
    int temp;
    int pos;
    //从0开始意思是第一次取出一个数值,从1开始就是默认拿出了第一个数值
    for(i_count = 1;i_count<num;i_count++){

        temp = *(pointer+i_count);//取出的数值

        pos = i_count-1;//最后一个数值的位置

        //当当前元素的前面位置>0并且当前位置的数值小于前面的数值的时候(取出的数值小于最后一个数值)
        while((pos>=0) && (temp < *(pointer+pos))){
            swap(pointer+1+pos,pointer+pos);
            pos--;
        }
        *(pointer+pos+1)  = temp;
    }
    printf_array(num_pointer,num);
}   



/**
*折半排序法则
*折半排序算法通常也叫做快速排序算法,是选择中间的一个数值middle,然后把中间数值小的放在左边,比中间数值大的数据放在右边,然后对两边分别进行递归的方法进行重新调用;
*1:先取出中间的数值
*2:左边去与中间middle进行比较,如果左边的数值大于middle,筛选出来
*3:右边的数值与中间middle进行比较,如果右边的小于middle,筛选出来,将左右两边的这两个数值进行互换,然后再将pos各往下一个元素提一位,再次进行比较
*这样可以在第一次遍历完了之后,将以中间middle为基准的数值,进行左右分布,
*4:然后再次将左边的一组进行单独二分排序,将右边的一组进行二分排序
*/
extern void celeritySort(int * num_pointer,const int left,const int right){
    int *pointer = num_pointer;
    int i_count = left;
    int j_count = right;
    int middle  = *(pointer+(left+right)/2);//拿到最中间的数的数值

    do{ 
        while((*(pointer+i_count) < middle) && (i_count<right)){
            i_count++;
        }
        while((*(pointer+j_count) > middle) && (j_count>left)){
            j_count--;
        }
        if(i_count <= j_count){
            swap(pointer+i_count,pointer+j_count);
            i_count++;
            j_count--;
        }
    }while(i_count<=j_count);

    //递归左边
    if(left<j_count){
        celeritySort(num_pointer,left,j_count);
    }

    //递归右边
    if(i_count<right){
        celeritySort(num_pointer,i_count,right);
    }

    printf_array(num_pointer,right+1);
}

swap.h

#ifndef __SWAP_H__
#define __SWAP_H_

extern void swap(int *,int *);

extern void printf_array(int *,int);
#endif

swap.c

#include"swap.h"
#include<stdio.h>

extern void swap(int *num_pointer1,int *num_pointer2){
    int temp;
    temp = *num_pointer1;
    *num_pointer1 = *num_pointer2;
    *num_pointer2 = temp;
}

extern void printf_array(int * pointer,int num){
    int count = 0;
    for(count;count<num;count++){
        printf("position:[%d]:value:%d\n",count,*(pointer+count));
    }

}

ceshi daima :
sort_algorithm.c

#include<stdio.h>
#include<stdio.h>
#include"sort.h"
#include"swap.h"

int main(int argc,char *argv[]){
    int select = 0;
    int array_length;
    int num = 0;
    printf("==============\n");
    printf("1:selectSort\n");
    printf("2:bubbleSort\n");
    printf("3:bubbleSort2\n");
    printf("4:swapSort\n");
    printf("5:insertSort\n");
    printf("6:celeritySort\n");
    printf("==============\n");

    scanf("%d",&select);

    printf("please input the array length you want!!\n");
    scanf("%d",&array_length);

    int array_nums[array_length];

    for(num ;num<array_length;num++){
        printf("please input the array element\n");
        scanf("%d",&array_nums[num]);
    }

    printf_array(array_nums,array_length);
    printf("---------------------------\n");
    if(select == 1){    
        selectSort(array_nums,array_length);
    }else if(select == 2){
        bubbleSort(array_nums,array_length);
    }else if(select == 4){
        swapSort(array_nums,array_length);
    }else if(select == 3){
        bubbleSort2(array_nums,array_length);
    }else if(select == 5){
        insertSort(array_nums,array_length);
    }else if(select == 6){
        celeritySort(array_nums,0,array_length-1);
    }else{
        printf("select error\n");
    }
    return 0;
}

最后谢谢大家的访问:欢迎大家持续访问,有错误的地方希望各位看客能够及时指出,谢谢

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值