目录
✍️前言:
前面我们学习了数组,为了加深对数组的学习,通过几道数组的题来进行巩固
如果忘记了可以打开下面链接进行回顾:
下面会练习四道题,有涵盖两种算法(查找和排序算法)
<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;
}
**********************************
(因为有清屏操作,所以看着只有一行输出,是逐步输出的)
最后输出为:
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
📝小结:
- 上面我们练习了数组的题目,并且学习了两种算法:
- 查找算法(顺序查找,二分查找)
- 排序算法(冒泡排序)
我们会在后面学习其他的算法,上面的练习中会发现有一些代码是重复的,那么有没有什么更好的方法来减少重复代码,让代码看起来更精简呢?
- 下面我们会学习函数(可以减少重复代码,可读性更好,更简洁)
以上就是本次练习的小结,
如果上面的内容有错误或者不完整的地方,欢迎大家在评论区指出
感谢大家的浏览🌹🌹🌹