C语言5种排序、二分查找(递归和非递归)

本篇文章是个人对排序和查找的概念理解和代码解析希望对您有所帮助,如有哪里不合理还请下方评论纠正一下,感谢!!!

冒泡排序

冒泡排序是稳定的。

思想:

对列表每两个相邻的数比较大小,如果前边的比后边的大(或小),那么这两个数就互换位置,就像是冒泡一样。

如图所示:

冒泡排序代码:

void bubblesort(int arr[] , int len){

    int i , j , temp        //定义 外层循环变量 i 内层循环变量 j 临时变量 temp

for( i = 0 ; i< len - 1 ; i++){        //外层 控制 比较多少趟
    
    for( j = 0 ; j < len - i -1 ; j++){        //内层 控制 元素 一趟比较的次数
        
         //从小到大排序,判断当前元素是否大于后一位元素如若大于进行元素的交换
        if( arr[j] > att[j+1]){       
            
            temp = arr[j];
            
            arr[j] = arr[j+1];
            
            arr[j+1] = temp;
            }
        }    
    }
}

简单选择排序

选择排序是不稳定的。

思想:

第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾,依次执行直到排序结束。

如图所示:

选择排序代码:

void selectSort(int arr[] , int len){

     //定义 外层循环变量 i 内层循环变量 j 临时变量 temp  存储第一个元素下标 min
    int i , j , temp , min;
    
    for(i = 0 ;i < len ; i++){
        
        min = i;                //min 标记 未排序第一个元素的位置
        
        for(j = i + 1 ; j < len ; j++){        //找比 min 位置还小的元素
            
            if(arr[j] < arr[min]){      //判断元素是否小于min位置的元素
                min = j;                //小于更新下标
            }
            
        }
        
        if(min != i){        //如果最小值所在位置不为 i,交换最小值和第 i 个元素的位
            temp = arr[min];
            
            arr[min] = arr[i];
            
            arr[i] = temp;
            
        }
        
    }
    
}

插入排序

插入排序是稳定的。

思想:

插入排序是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。将后面的每个数,依次往前移动,直到找到它恰好能放的位置。

如图所示:

插入排序代码:

void insertSort(int arr[] , int  len){
    
    //定义 外层循环变量 i 内层循环变量 j 临时变量 temp
    int  i , j , temp;
    
    for(i = 1; i < len; i++){        //从 1 开始,0 位置当成有序
        
        temp = arr[i];                //temp 记录未排序第一个
        
        for(j = i - 1; j >= 0 && arr[j] > temp; j--){     //内层循环遍历j插入的位置
            
            arr[j+1] = arr[j];        //元素后移,腾位置给插入元素

        } 
        arr[j+1] = temp;            //插入 比较的 后一位
        
    }
    
}

希尔排序

希尔排序是不稳定的。

思想:

希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。

如图所示:

未排序的

进行一次步长排序的

希尔排序代码:

//dk 是增量 步长

void shellInsert(int arr[] , int len ,int dk){
    
    int i , j , temp;        //i 循环变量 j 前边组的位置 temp 临时变量
    
    for(i = dk; i < len; i++){
        
        //判断每组的 第几个元素大小
        if(arr[i] < arr[i-dk]){        //后编组 小于 前边组
            
            temp = arr[i];
            
            j = i - dk;
            
            for(; j >= 0 && temp < arr[j]; j = j - dk){
                //前边的值 给到 后边
                arr[j + dk] = arr[j];
            }  
            arr[j + dk] = temp;
        }
        
    }
    
}

快速排序

快速排序是不稳定的

思想:

通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

如图所示:

快速排序代码:

int getPivot(int arr[] , int low , int high){
    
    //定义基准值
    int pivot = arr[low];
    
    while(low < high){            //i < j 的时候
        
        // j 从后向前找,比基准值 小的元素
        while(low < high && arr[high] >= pivot){
            high--;
        }
        
        //找到了 比基准值小的元素    将元素 给到 i 位置
        arr[low] = arr[high];
        
        //i 从前向后找,比基准值 大的元素
        while(low < high && arr[low] <= pivot){
            low++;
        }
        
        //找到了 比基准值大的元素    将元素 给到 j 位置
        arr[high] = arr[low];
        
    }
    
      //结束条件 i = j 找到了基准值的位置
    arr[low] = pivot;
    
    //返回基准值
    return low;
    
}


void quickSort(int arr[] , int low ,int high){
    
    if(low < high){
        
        //基准值位置的变量
        int pivot = getPivot(arr , low , high);
        
        //递归 对 基准值位置 左边进行 快速排序
        quickSort(arr , low , pivot-1);
        
        //递归 对 基准值位置 右边进行 快速排序
        quickSort(arr , pivot+1 , high);
    }
}

二分查找(递归和非递归)

思想:

二分查找有称为折半查找找寻数组中的元素,我们需要头下标、中间下标和尾下标,查找的数据大于中间下标上的元素就去中间下标到尾下标之间去查找元素,相反如果小于中间下标上的元素,就去中间下标到头下标之间去查找元素。

如图所示:

二分查找(递归)代码:

//arr 数组,low 左边值,high 右边值,key 要查找的关键字
int binarySearch(int arr[] , int low , int high , int key){
   
    int mid;            //中间下标
    
    if(low <= high){
        
        mid = (low + high)/2;    //求中间下标的位置
        
        if(key == arr[mid]){    //找到该数据,返回该数据下标
            return mid;        //递归出口
        }else if(key > arr[mid]){    //查询元素大于中间位置上的元素
                //让头下标后移移动到中间下标加一位置
            return binarySearch(arr , mid+1 , high , key);   
        }else{
                //查询元素小于中间位置上的元素
               //让尾下标后移移动到中间下标减一位置
            return binarySearch(arr , low , mid-1 , key);
        }
        
    }
    return -1;
}

二分查找(非递归)代码:

//arr 数组,low 左边值,high 右边值,key 要查找的关键字
int binarySearch(int arr[] , int low , int high , int key){
    
    int mid;            //中间值
    
    while(low <= high){
        
        mid = (low +high)/2;        //找中间位置
        
        if(key == arr[mid]){
            return mid;                //返回下标
        }else if(key > arr[mid]){      //查询元素大于中间位置上的元素
            low = mid + 1;            //让头下标后移移动到中间下标加一位置
        }else{
            high = mid - 1;            //查询元素小于中间位置上的元素
        }                               //让尾下标后移移动到中间下标减一位置
        
    }
    //没有找到关键字
    return -1;
}

本篇文章到此结束感谢您的观看!!!

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值