Demo3—排序
插入排序
插入排序有两种,一种是已经给定数组,对数组中的数据进行排序;另一种是变生成边排序。
1.排序数组已经给出
1.1定义排序的数组
int a[] = {3,0,1,8,7,2,5};
1.2比较第i和i+1个位置上的数
这里要注意越界,若是 i < 7 ,当最后一次比较即 i = 6时,i + 1 = 7,越界,所以是 i< 7-1
for (int i = 0; i < 7 - 1; i++){
if (a[i] > a[i+1]){
int temp = a[i];
a[i] = a[i + 1];
a[i + 1] = temp;
}
}
1.3如果i位置的数比i+1位置的数大,则二者交换,交换之后第i位置的数要和前面所有数进行比较
for (int i = 0; i < 7 - 1; i++){
if (a[i] > a[i+1]){
int temp = a[i];
a[i] = a[i + 1];
a[i + 1] = temp;
for (int j = i; j > 0; j--){
if (a[j] < a[i - 1]){
int temp = a[j];
a[j] = a[j - 1];
a[j - 1] = temp;
}
}
}
}
2.边生成边排序
这种排序有2种思路,一种是:每生成随机数用一个变量储存,将这个数和前面的数进行比较,找到合适的位置插入,使数组中始终保持有序状态;另一种是:每生成一个随机数都先放在数组里,然后和前面每一个数进行比较,直到找到合适的位置。
前者是先找位置后插入,后者是先插入后找位置,但是前者更考验逻辑思维能力,也是比较新颖的一种。
这里只讲述前者哦~
2.1定义一个10个空间大小的空数组
int a[10] = {};
2.2导入生成随机数所需要的头文件
#include <stdlib.h>
#include <time.h>
2.3种下生成随机数所需要的种子
srand((unsigned int)time(NULL));
2.4生成10个随机数
for (int i = 0; i < 10; i++) {
temp = rand() % 10;
printf("%d", temp);
}
2.5每生成一个随机数时都要在数组a中找到合适的位置并把这个数插入数组a,使数组a时刻保持有序状态
for (int i = 0; i < 10; i++) {
temp = rand() % 10;
printf("%d", temp);
//先找到需要保存的位置
if (i == 0){
//第一个
a[i] = temp;
}else{
//找合适的位置插入 和前面的所有数字进行比较
int j = i-1;
for (; j >= 0; j--){
if (a[j] > temp){
//需要将j的值向后移动一个字符
a[j+1] = a[j];
} else{
//若没有跳出,则这个循环结束之后j的位置为0下面执行j+1,j+1永远等于1,空位置永远是数组中的第二个位置
break;
}
}
//j+1就是空出来的位置,以为执行了一个,j--要回到前一个位置
a[j+1] = temp;
}
}
结构体数组排序
结构体数组排序是将一个记录以某个属性为关键字将所有记录按照升序或者降序排列。
题目:
从终端输入几个学生信息,学生信息包括年龄和体重,按照年龄从小到大排序,输出排序好的信息。
分步编写代码:
1.定义一个学生结构体,将学生的信息属性封装起来
typedef struct {
int age;
float weight;
}Student;
2.定义结构体数组用来存放从终端输入的学生信息
Student a[3] = {};
3.从终端输入学生信息,需要定义一个Student类的变量暂时存储输入的学生信息
for (int i = 0; i < 3; i++){
//创建Student变量
Student temp = {};
printf("请输入%d的年龄:",i+1);
scanf("%d", &(temp.age));
printf("请输入%d的体重:",i+1);
scanf("%f", &(temp.weight));
//保存temp的值
a[i] = temp;
}
4.以年龄为关键字按从小到大排序
for (int i = 0; i < 2; i++){
for (int j = 2; j > 0; j--) {
if (a[j].age < a[j-1].age){
Student temp = a[j];
a[j] = a[j-1];
a[j-1] = temp;
}
}
}
5.输出排序好的学生信息
for (int i = 0; i < 3; i++) {
printf("a[%d]: %d %f\n", i,a[i].age, a[i].weight);
}
注意事项:
1.不能给结构体赋初值,因为还没有内存;
2.结构体是把多种类型数据封装成一种类型
3.结构体所占字节遵守字节对齐原则,为4的倍数
4.typedef int RXX_INT;int是已存在的类型,RXX_INT是重定义后的名字
5.访问一个数组元素,a[1]=(a+14)访问一个数组元素时,先访问首地址再看下标的索引位置,再*4得到所访问元素的地址
6.排序时,若前一个与后一个交换位置的情况,要注意越界
7.题目中用temp暂时储存从终端输入的数据的好处:如果要对输入的值进行操作,定义一个新的学生变量temp,效率比较高,可以单独操作,比如对身份证号进行加密,否则对数组整体进行操作,效率比较低。