C语言练习——数组的练习(涉及顺序、二分查找,冒泡排序)

目录

✍️前言:

前面我们学习了数组,为了加深对数组的学习,通过几道数组的题来进行巩固

如果忘记了可以打开下面链接进行回顾:

下面会练习四道题,有涵盖两种算法(查找和排序算法)

  • <Windows.h> sleep()函数,sleep(1000)表示暂停1000毫秒(以毫秒为单位
  • <stdlib.h>system()函数,system("cls")表示清屏,将前面的内容全部清理
  • 算法的实现:
    • 排序算法:冒泡排序
    • 查找算法:顺序查找(暴力),二分查找(或叫折半查找)

1、多个字符从两端移动,向中间汇聚

  • arr1[] = "welcome to bit..."
  • arr2[] = "#################"
  • 让字符串"#################"从两端移动,逐步到最后为"welcome to bit..."
c 复制代码
#include<stdio.h>
#include<string.h>              //strlen( )函数
#include<Windows.h>     //Sleep( )函数
int main() {
    char arr1[] = "welcome to bit...";
    char arr2[] = "#################";
    int left = 0;
    int right = strlen(arr1) - 1;
    printf("%s\n", arr2);
    while (left <= right) {     //循环确保左边界不能超过右边界的位置
        //让程序暂停执行指定的秒数
        //这个是睡眠函数(单位是毫秒),暂停1000毫秒
        Sleep(1000);

        //将arr1的值逐步赋值给arr2
        arr2[left] = arr1[left];
        arr2[right] = arr1[right];
        left++;
        right--;
        printf("%s\n", arr2);
    }
    return 0;
}
******************************
输出为:
#################
w###############.
we#############..
wel###########...
welc#########t...
welco#######it...
welcom#####bit...
welcome### bit...
welcome #o bit...
welcome to bit...
c 复制代码
#include<stdio.h>
#include<stdlib.h>              //system( )函数
#include<string.h>              //strlen( )函数
#include<Windows.h>     //Sleep( )函数
int main() {
    char arr1[] = "welcome to bit...";
    char arr2[] = "#################";
    int left = 0;
    int right = strlen(arr1) - 1;
    printf("%s\n", arr2);
    while (left <= right) {     //循环确保左边界不能超过右边界的位置
        //让程序暂停执行指定的秒数
        //这个是睡眠函数(单位是毫秒),暂停1000毫秒
        Sleep(1000);

        //清空控制台屏幕上的所有输出内容(类似清屏操作)
        system("cls");

        //将arr1的值逐步赋值给arr2
        arr2[left] = arr1[left];        
        arr2[right] = arr1[right];
        left++;
        right--;
        printf("%s\n", arr2);
    }
    return 0;
}![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/ac8c57dc9c0b4398b06369f3475feca9.gif#pic_center)

**********************************
(因为有清屏操作,所以看着只有一行输出,是逐步输出的)
最后输出为:
welcome to bit...

2、冒泡排序

有一段数组arr[] = { 3,4,2,1,6,5,8,9,7,10 }

  • 把这个数组排序
  • 得到逆序和正序的数组(移动最大值/最小值)
  • 这个是正序----移动最大值放在最后面 的动画展示,每次两两判断大的值往后移动
  • (下面的代码可以用一个flag来进行标记,这样可以减少循环的次数,当flag=1时(没有交换过),说明已经是正序排序直接跳出循环)
cpp 复制代码
//正序----移动最大值放在最后面
#include<stdio.h>
int main() {
    int arr[] = { 3,4,2,1,6,5,8,9,7,10 };
    int n = sizeof(arr) / sizeof(arr[0]);       //得到数组arr的大小
    for (int i = 0; i < n - 1; i++) {           //循环的趟数
        for (int j = 0; j < n - 1 - i; j++) {   //一趟中循环判断的次数
            if (arr[j] > arr[j + 1]) {              //当数组的排序不是正序就交换
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
    for (int i = 0; i < n; i++) {
        printf("%d ",arr[i]);
    }
    return 0;
}
*****************************************
*****************************************
//正序----移动最大值放在最后面
//使用falg来进行标记
#include<stdio.h>
int main() {
    int arr[] = { 3,4,2,1,6,5,8,9,7,10 };
    int n = sizeof(arr) / sizeof(arr[0]);       //得到数组arr的大小
    //冒泡排序
    //正序----移动最大值放在最后面
    for (int i = 0; i < n - 1; i++) {           //循环的趟数
        int flag = 1;       //进行标记,判断是否已经是正序排好了,没有交换的状态为1
        for (int j = 0; j < n - 1 - i; j++) {   //一趟中循环判断的次数
            if (arr[j] > arr[j + 1]) {              //当数组的排序不是正序就交换
                flag = 0;                               //交换了状态为0
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
        if (flag == 1)
            break;
    }
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    //二分查找
    return 0;
}
c 复制代码
//正序----移动最小值在最前面
#include<stdio.h>
int main() {
    int arr[] = { 3,4,2,1,6,5,8,9,7,10 };
    int n = sizeof(arr) / sizeof(arr[0]);       //得到数组arr的大小
    for (int i = 0; i < n - 1; i++) {           //循环的趟数
        for (int j = n - 1; j > i; j--) {           //一趟中循环判断的次数
            if (arr[j] < arr[j - 1]) {               //当数组的排序不是正序就交换
                int temp = arr[j];
                arr[j] = arr[j - 1];
                arr[j - 1] = temp;
            }
        }
    }
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    return 0;
}
c 复制代码
//逆序-----移动最大值在最前面
#include<stdio.h>
int main() {
    int arr[] = { 3,4,2,1,6,5,8,9,7,10 };
    int n = sizeof(arr) / sizeof(arr[0]);       //得到数组arr的大小
    for (int i = 0; i < n - 1; i++) {           //循环的趟数
        for (int j = n - 1; j > i; j--) {           //一趟中循环判断的次数
        	//如果后面的值大于前面的值,则交换
            if (arr[j] > arr[j - 1]) {               //当数组的排序不是逆序就交换
                int temp = arr[j];
                arr[j] = arr[j - 1];
                arr[j - 1] = temp;
            }
        }
    }
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    return 0;
}
c 复制代码
//逆序-----移动最小值在最后面
#include<stdio.h>
int main() {
    int arr[] = { 3,4,2,1,6,5,8,9,7,10 };
    int n = sizeof(arr) / sizeof(arr[0]);       //得到数组arr的大小
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            //如果前面的值小于后面的值,则交换
            if (arr[j] < arr[j + 1]) {              //逆序
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    return 0;
}

3、顺序查找

有一段数组arr[] = { 3,4,2,1,6,5,8,9,7,10 }

  • 查找数字(11和5),判断是否存在
  • 如果存在(输出存在,并且输出数组的下标);如果不存在(输出找不到)

可以将数组排序,也可以不排

c 复制代码
#include<stdio.h>
int main() {
    int arr[] = { 3,4,2,1,6,5,8,9,7,10 };
    int find1 = 11, find2 = 5;
    int n = sizeof(arr) / sizeof(arr[0]);
    int found1 = 0, found2 = 0;
    int index1 = 0, index2 = 0;
    
    for (int i = 0; i < n; i++) {
        if (find1 == arr[i]) {
            found1 = 1;
            index1 = i;
            break;
        }
    }
    if (found1) {
        printf("%d存在,下标是:%d\n", find1, index1);
    }
    else
        printf("%d不存在\n", find1);

    for (int i = 0; i < n; i++) {
        if (find2 == arr[i]) {
            found2 = 1;
            index2 = i;
            break;
        }
    }
    if (found2) {
        printf("%d存在,下标是:%d\n", find2, index2);
    }
    else
        printf("%d不存在\n", find2);
    return 0;
}
*******************************************
输出:
11不存在
5存在,下标是:5

4、二分查找

有一段数组arr[] = { 3,4,2,1,6,5,8,9,7,10 }

  • 查找数字(43和7),判断是否存在
  • 如果存在(输出存在,并且输出数组的下标);如果不存在(输出找不到)

前面我们使用了顺序查找了进行查找,到这个的效率低且时间复杂度高,下面我们使用二分查找来进行查找

  • 需要将数组排序
  • arr[] = { 1,2,3,4,5,6,7,8,9,10 }
  • 再进行查找
  • 下面是动画演示,来进行理解这个算法是如何实现的


c 复制代码
#include<stdio.h>
int main() {
    int arr[] = { 3,4,2,1,6,5,8,9,7,10 };
    int n = sizeof(arr) / sizeof(arr[0]);       //得到数组arr的大小
    //冒泡排序
    //正序----移动最大值放在最后面
    for (int i = 0; i < n - 1; i++) {           //循环的趟数
        int flag = 1;       //进行标记,判断是否已经是正序排好了,没有交换的状态为1
        for (int j = 0; j < n - 1 - i; j++) {   //一趟中循环判断的次数
            if (arr[j] > arr[j + 1]) {              //当数组的排序不是正序就交换
                flag = 0;                               //交换了状态为0
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
        if (flag == 1)
            break;
    }
    //二分查找(折半查找)
    int left = 0, right = n - 1;
    int f1 = 43, f2 = 7;        //需要寻找的值
    int fa1 = 0, fa2 = 0;       //标记是否找到
    int index1 = 0, index2 = 0;     //记录下标
    //查找43这个值
    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (arr[mid] < f1) {       //如果中间值小于目标值 
            left = mid + 1;          //那么让左边界为中间值的下标的下一位
        }
        else if (arr[mid] > f1) {    //如果中间值大于目标值 
            right = mid - 1;        //那么让右边界为中间值的下标的前一位
        }
        else{
            index1 = mid;
            fa1 = 1;        //标记找到了
            break;      //找到退出循环
        }
    }
    if (fa1 == 1)
        printf("%d存在,下标为:%d\n", f1, index1);
    else
        printf("%d不存在\n", f1);
    //查找7这个值
    left = 0;
    right = n - 1;
    while (left <= right) {
        int mid = left + (right - left) / 2;        
        if (arr[mid] < f2) {       //如果中间值小于目标值 
            left = mid + 1;          //那么让左边界为中间值的下标的下一位
        }
        else if (arr[mid] > f2) {    //如果中间值大于目标值 
            right = mid - 1;        //那么让右边界为中间值的下标的前一位
        }
        else {
            index2 = mid;
            fa2 = 1;        //标记找到了
            break;      //找到退出循环
        }
    }
    if (fa2 == 1)
        printf("%d存在,下标为:%d\n", f2, index2);
    else
        printf("%d不存在\n", f2);
    return 0;
}
*****************************************
输出:
43不存在
7存在,下标为:6

📝小结:

  • 上面我们练习了数组的题目,并且学习了两种算法:
    • 查找算法(顺序查找,二分查找)
    • 排序算法(冒泡排序)

我们会在后面学习其他的算法,上面的练习中会发现有一些代码是重复的,那么有没有什么更好的方法来减少重复代码,让代码看起来更精简呢?

  • 下面我们会学习函数(可以减少重复代码,可读性更好,更简洁)

以上就是本次练习的小结,

如果上面的内容有错误或者不完整的地方,欢迎大家在评论区指出

感谢大家的浏览🌹🌹🌹

相关推荐
东京老树根2 小时前
SAP学习笔记 - BTP SAP Build08 - BPA Condition,Decision Table
笔记·学习
Brilliantwxx2 小时前
【C++】类与对象(下)
c++·笔记·算法
深蓝海拓2 小时前
基于QtPy (PySide6) 的PLC-HMI工程项目(十二)最后的工作
网络·笔记·python·学习·pyqt·plc
承渊政道2 小时前
【动态规划算法】(从入门到精通:路径问题)
数据结构·c++·学习·算法·leetcode·macos·动态规划
王的宝库2 小时前
【Ansible】变量与敏感数据管理:Vault 加密 + Facts 采集详解
笔记·学习·ansible
中屹指纹浏览器2 小时前
2026浏览器指纹隔离技术深度对比与大规模集群部署性能优化实践
经验分享·笔记
我不是懒洋洋2 小时前
手写一个LRU缓存:从原理到高并发实战
c语言·经验分享
星幻元宇VR3 小时前
VR机动车模拟驾驶系统助力交通安全科普
科技·学习·安全·生活·vr
U盘失踪了4 小时前
Playwright with sync_playwright() as p 上下文管理器
笔记