一、排序:冒泡排序
基本思路:两两相邻的元素进行比较,如果前面比后面大,则交换。
详细思路:一趟冒泡排序 -> 解决一个/排好一个数/排对一个数
举例:现在有十个数字待排序,那么需要排九趟才可以都排好
所以如果有n个数字 -> 则需要排n-1趟
第1趟:10个数字待排序 9对比较
第2趟:9个数字待排序 8对比较
······
第9趟:2个数字待排序 1对比较
特别注意⚠️:
//计算数组元素个数:当一个数组传参的时候,形参部分在函数内部是无法计算元素个数的
//所以要先计算出数组元素个数,再把数组元素个数当作参数传递过去
void bubble_sort(int arr[] , int sz)
{
//确定趟数
for (int i=0; i < sz-1; i++) {
//一趟冒泡排序的过程
for (int j=0; j<sz-1-i; j++) {
if(arr[j] > arr[j+1])
{
//交换
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
}
}
}
}
int main()
{
int sz = sizeof(arr)/sizeof(arr[0]);
bubble_sort(arr,sz);
for (int i=0; i<10; i++) {
printf("%d ",arr[i]);
}
}
优化冒泡排序:如果可以判断这一趟已经是有序的,那么之后的几趟冒泡排序就可以不用再排了
在交换部分设置一个flag来判断是否已经有序,如果进行了交换,那么改变flag从而记录发生了
交换,如果一趟下来没有发生交换,即已经有序了,则之后不用在排了,跳出即可。
void bubble_sort_opt(int arr[] , int sz)
{
//确定趟数
for (int i=0; i < sz-1; i++) {
//一趟冒泡排序的过程
//设置flag来记录是否发生了交换
//发生了交换,则证明还不都是有序的;没发生交换,则证明已经全部有序
int flag = 1;
for (int j=0; j<sz-1-i; j++) {
if(arr[j] > arr[j+1]){
//交换
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
flag = 0;
}
}
//如果没交换,则证明已经全部有序,跳出排序的循环
if(flag == 1)
break;
}
}
二、查找:二分查找(数据是有序的)
基本思路:将要查找的数与所有数的中间比较
详细思路:假设在一组数据1 2 3 4 5 6 7 8 9 10中查找7
首先创建两个变量left和right来记录这组数据的左下标和右下标,在创建mid变量来记录左下标和
右下标的平均值。
第一次查找:left=0,right=9,mid=4,比较arr[mid]与要查找的数的大小关系,arr[4]<7,则让left=mid+1
第二次查找:left=5,right=9,mid=7,比较arr[mid]与要查找的数的大小关系,arr[7]>7,则让right=mid-1
第三次查找:left=5,right=6,mid=5,比较arr[mid]与要查找的数的大小关系,arr[5]<7,则让left=mid+1
第三次查找:left=6,right=6,mid=6,比较arr[mid]与要查找的数的大小关系,arr[6]=7,返回mid,即返回要查找的元素在数组中的下标
若最终没有找到,则返回-1。
#include <stdio.h>
int binary_search (int a[],int key,int sz)
{
int left = 0;
int right = sz - 1;
//int mid = (left + right)/2;//mid写在这里,mid永远变不了(更新不了)
while (left <= right) {
int mid = (left + right)/2;//放在循环里mid每一轮都可以更新
if(a[mid]>key)
right = mid - 1;
else if (a[mid]<key)
left = mid + 1;
else
return mid;//返回的是 数组下标
}
return -1;
}
int main(int argc, const char * argv[]) {
int arr[] = {1,2,3,4,5,6,7,8,9,10};
int k = 7;
int len = sizeof(arr)/sizeof(arr[0]);
//找到了返回下标
//找不到返回-1
int ret = binary_search(arr,k,len);
if(ret == -1)
printf("没找到\n");
else
printf("找到了,下标是%d\n",ret);
return 0;
}
特别注意⚠️:1.数组元素个数当作参数传递过去,不可以在函数内部求传过去的数组元素个数。
需要在主函数内部求出来把数组元素个数当参数传给函数!!!
2.循环条件:当左下标小于等于右下标时,才可以寻找;若左下标大于右下标,就会出现小的数
比大的数大-> 明显不成立。所以循环的条件是left<=right。