数组与排序
数组
数组是由一个或者多个相同数据类型的数据组成的一个集合
一维数组
如果将数组看做一个坐标轴,一维数组则如同只有X坐标,每个数组中的元素内存地址都是连续的,当数据类型和首个元素a[0]确定时,后续a[i]依次递增。
一维数组的初始化
1、未初始化
int a[5];
//大小为5个a[0]--a[4],当为全局变量时默认内容全为0,局部变量随机
2、完全初始化
int a[5]={0,1,2,3,4};
//规定大小情况下完全初始化数组,内容一一对应
int a[]={0,1,2,3,4};
//不规定大小的情况下,后面有多少内容,数组大小即为多少,姑且也算一种完全初始化吧
3、部分初始化
int a[5]={0,1};
//部分初始化的情况下根据顺序依次初始化数组,其余补零,即a[0]=0,a[1]=1,a[2-4]=0;
int a[5]={0};
//所以很多时候定义数组的时候给个空,以防系统塞进去奇奇怪怪的数值,也是为了防止bug吧
二维数组
同样将数组看做一个坐标轴,二维数组就是有x轴和y轴的坐标了,但毕竟计算机里的内存只有一个坐标,所以就需要把二维数组按照一排排的顺序放置,里面的每个地址仍然是连续的。
二维数组的初始化
1、未初始化
int a[3][2];
//大小为3*2=6个,a[0][0]--a[2][1],当为全局变量时默认内容全为0,局部变量随机
2、完全初始化
int a[3][2]={0,1,2,3,4,5};
//规定大小情况下完全初始化数组,按照地址顺序内容一一对应
int a[][2]={0,1,2,3,4,5};
//二维数组的定义第二个必须定义,第一个可以让系统自动定义,自动给于最小的数,在这个例子中,a[n][2],根据后面的个数,n=3
//若int a[][2]={0,1,2,3,4,5,6};此时不够2整除,自动加一,n=4
3、部分初始化
int a[3][2]={0,1};
//t同理部分初始化的情况下根据顺序依次初始化数组,其余补零
排序
接触数组后不可避免解除的就是对一串数据的大小排序,而提到排序,那必然是经典的冒泡排序和选择排序,两种排序的思想在我看来都差不多,都是一遍遍地循环遍历数组,然后选出本次遍历数组符合要求的数。其他排序方法再单开文章吧
冒泡排序
冒泡排序可以理解为每次遍历将符合要求的数据依次放在后面
以四个数 int a[4]={5,1,4,2}; 从小到大排序为例,先放代码,最后有过程图
#include<stdio.h>
#define N 4
int main()
{
int a[N];
for(int i=0;i<N;i++)
{
scanf("%d",&a[i]);
}
for(int i=0;i<N-1;i++)
{
for(int j=0;j<N-1-i;j++)
{
if(a[j]>a[j+1])
{
int m=a[j];
a[j]=a[j+1];
a[j+1]=m;
}
}
}
for(int i=0;i<N;i++)
{
printf("%d ",a[i]);
}
return 0;
}
1、首先要知道我们每次遍历的目的:两两比较,第一次找出最大的,第二次找出第二大,第三次找出第三大,最后一个因为只有一个了,也就不需要遍历了,这也就是最外层为什么是长度减一,得出外层循环
for(int i=0;i<N-1;i++) //N为需要排序的数量,即4
2、然后因为每次我们都是把本次最大的放在最后面,所以前部分还是乱的,仍然需要从第一个开始比较,比较的次数就是未排序的数量的个数-1,第一次需要三次,第二个两次,第三次一次,最后一次不需要比较,所以得出内层循环
for(int j=0;j<N-i-1;j++)//从数组,循环到总数-排好的-1
3、最后就是冒泡排序的方法:将当前的与之后的一个进行对比,若比后面的大,就交换位置,没有则不变,本质就是让这个j时刻指着当前已经遍历的数中的最大值,直到最后与最后一个数进行对比。
if(a[j]>a[j+1]) //当前指向的最大值,和后面的一个进行对比,如果比后面的大,进行交换,如果从大到小排序,则是对比谁比较
{
int m=a[j]; //这里的交换数就类似如何用三个瓶子把其中两个有水的瓶子进行交换
a[j]=a[j+1];
a[j+1]=m;
//若只用两个数,算术计算方法
//a = a + b 两个数求和a+b a[j]=a[j]+a[j+1]
//b = a - b a是和(a+b)-b=a a[j+1]=a[j]-[j+1]
//a = a - b 同理,此时b=a,(a+b)-a=b a[j]=a[j]-a[j+1]
//若只用两个数,位运算方法
//a = a ^ b 异或运算,a^a=0 0 ^ a =a
//b = a ^ b b=(a^b^b)=a^0=a
//a = a ^ b a=(a^b^a)=b^0=b
}
Excel搓的过程图,将就着看看吧,属实不会做动画
选择排序
选择排序则是每次找到最小的,然后放在数值前面
仍然是以四个数 int a[4]={5,1,4,2}; 从小到大排序为例,先放代码
#include<stdio.h>
#define N 4
int main()
{
int a[N];
for(int i=0;i<N;i++)
{
scanf("%d",&a[i]);
}
for(int i=0;i<N-1;i++)
{
int m=i;
for(int j=i+1;j<N;j++)
{
if(a[m]>a[j])
{
m=j;
}
}
int n=a[i];
a[i]=a[m];
a[m]=n;
}
for(int i=0;i<N;i++)
printf("%d ",a[i]);
return 0;
}
1、最外层循环和冒泡一样,因为N个数,只需要找N-1次最小的数即可
2、每次寻找最小数时,以当前数先当最小数,然后在遍历过程中找到实际最小数,这里是利用的m记录最小数的下标。
for(int i=0;i<N-1;i++) //N为需要排序的数量,即4
{
int m=i; //m记录最小值的下标
for(int j=i+1;j<N;j++) //与当前的下一个开始对比
{
if(a[m]>a[j])) //有更小的后记录下标
{
m=j;
}
}
}
3、最后就是交换数了
int n=a[i];
a[i]=a[m];
a[m]=n;
继续搓Excel