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
    评论
《妙趣横生的算法(C语言实现)》可作为算法入门人员的教程,也可以作为学习过C语言程序设计的人士继续深造的理想读物,也可作为具有一定经验的程序设计人员巩固和提高编程水平,查阅相关算法实现和数据结构知识的参考资料,同时也为那些准备参加与算法和数据结构相关的面试的读者提供一些有益的帮助。最大的特色在于实例丰富,题材新颖有趣,实用性强,理论寓于实践之中。理论与实践相结合,旨在帮助读者理解算法,并提高C语言编程能力,培养读者的编程兴趣,并巩固已有的C语言知识。全书分为2个部分共10章,内容涵盖了编程必备的基础知识(如数据结构、常用算法等),编程实例介绍,常见算法和数据结构面试题等。可以使读者开阔眼界,提高编程的兴趣,提高读者的编程能力和应试能力。 目录: 第1部分 基础篇 第1章 数据结构基础 1.1 什么是数据结构 1.2 顺序表 1.2.1 顺序表的定义 1.2.2 向顺序表中插入元素 1.2.3 从顺序表中删除元素 1.2.4 实例与分析 1.3 链表 1.3.1 创建一个链表 1.3.2 向链表中插入结点 1.3.3 从链表中删除结点 1.3.4 销毁一个链表 1.3.5 实例与分析 1.4 栈 1.4.1 栈的定义 1.4.2 创建一个栈 1.4.3 入栈操作 1.4.4 出栈操作 1.4.5 栈的其他操作 1.4.实例与分析 1.5 队列 1.5.1 队列的定义 1.5.2 创建一个队列 1.5.3 入队列操作 1.5.4 出队列操作 1.5.5 销毁一个队列 1.5.6 循环队列的概念 1.5.7 循环队列的实现 1.5.8 实例与分析 1.6 树结构 1.6.1 树的概念 1.6.2 树结构的计算机存储形式 1.6.3 二叉树的定义 1.6.4.二叉树的遍历 1.6.5 创建二叉树 1.6.6 实例与分析 1.7 图结构 1.7.1 图的概念 1.7.2 图的存储形式 1.7.3 邻接表的定义 1.7.4.图的创建 1.7.5 图的遍历(1)——深度优先搜索 1.7.6 图的遍历(2)——广度优先搜索 1.7.7 实例与分析 第2章 常用的查找与排序方法 2.1 顺序查找 2.2 折半查找 2.3 排序的概述 2.4 直接插入排序 2.5 选择排序 2.6 冒泡排序 2.7 希尔排序 2.8 快速排序 第3章 常用的算法思想 3.1 什么是算法 3.2 算法的分类表示及测评 3.2.1 算法的分类 3.2.2 算法的表示 3.2.3 算法性能的测评 3.3 穷举法思想 3.3.1 基本概念 3.3.2 寻找给定区间的素数 3.3.3 TOM的借书方案 3.4 递归与分治思想 3.4..1 基本概念 3.4.2 计算整数的划分数 3.4.3 递归的折半查找算法 3.5 贪心算法思想 3.5.1 基本概念 3.5.2 最优装船问题 3.6 回溯法 3.6.1 基本概念 3.6.2 四皇后问题求解 3.7 数值概率算法 3.7.1 基本概念 3.7.2 计算定积分 第2部分 编程实例解析 第4章 编程基本功 4.1 字符类型统计器 4.2 计算字符的ASCII码 4.3 嵌套if.else语句的妙用 4.4 基于switch语句的译码器 4.5 判断闰年 4.6 指针变量作参数 4.7 矩阵的转置运算 4.8 矩阵的乘法运算 4.9 巧用位运算 4.10 文件的读写 4.11 计算文件的大小 4.12 记录程序的运行时间 4.13 十进制/二进制转化器 4.14 打印特殊图案 4.15 打印杨辉三角 4.16 复杂级数的前n项和 4.17 寻找矩阵中的“鞍点” 4.18 n阶勒让德多项式求解 4.19 递归反向输出字符串 4.20 一年中的第几天 第5章 数学趣题(一) 5.1 舍罕王的失算 5.2 求两个数的最大公约数和最小公倍数 5.3 歌德巴赫猜想的近似证明 5.4 三色球问题 5.5 百钱买百鸡问题 5.6 判断回文数字 5.7 填数字游戏求解 5.8 新郎和新娘 5.9 爱因斯坦的阶梯问题 5.10 寻找水仙花数 5.11 猴子吃桃问题 5.12 兔子产仔问题 5.13 分解质因数 5.14 常胜将军 5.15 求兀的近似值 5.16 魔幻方阵 5.17 移数字游戏 5.18 数字的全排列 5.19 完全数 5.20 亲密数 5.21 数字翻译器 5.22 递归实现数制转换 5.23 谁在说谎 第6章 数学趣题(二) 6.1 连续整数固定和问题 6.2 表示成两个数的平方和 6.3 具有特殊性质的数 6.4 验证角谷猜想 6.5 验证四方定理 6.6 递归法寻找最小值 6.7 寻找同构数 6.8 验证尼科彻斯定理 6.9 三重回文数字 6.10 马克思手稿中的数学题 6.11 渔夫捕鱼问题 6.12 寻

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值