目录
每日一问:什么是数组?
数组(Array)是有序的元素序列。
在C语言中, 数组属于构造数据类型。一个数组可以分解为多个数组元素,这些数组元素可以是基本数据类型或是构造类型。
引入数组?!
四只小鸡住酒店?
一个一个的去订酒店,一只一间,逐只分,随机的
一百只小鸡住房间?
数量较大,不方便分,更不方便找
组团申请一串连续的房间(组团定制),每个小鸡都有自己的编号,且编号是连续的
这个“小鸡战队”数组,数组的0~99号 一 一对应100只小鸡
一、一维数组
1. 一维数组的定义
数组元素类型 数组名字[常量表达式];
例如:
代码中的int为数组元素的类型,而a表示的是数组变量名,括号中的4表示的是数组中包含的元素 个数。
注意 在数组a[4]中只能使用a[0]、a[1]、a[2]、a[3],而不能使 用a[4],若使用a[4]则会出现下标越界的错误。
#include<stdio.h>
int main()
{
int iArray[3], index;
printf("请输入语文,数学,英语成绩\n");
for (index = 0; index < 3; index++)
{
scanf("%d", &iArray[index]);
}
for (index = 0; index < 3; index++)
{
printf("%d\n", iArray[index]);
}
return 0;
}
2. 一维数组的引用
输入数组->展示数组->展示逆转后的数组
#include<stdio.h>
int main()
{
int iArray[5], index, temp;
printf("Please enter a Array:\n");
for (index = 0; index < 5; index++)
{
scanf("%d", &iArray[index]);
}
printf("Original Array is:\n");
for (index = 0; index < 5; index++)
{
printf("%d ", iArray[index]);
}
printf("\n");
for (index = 0; index < 2; index++)
{
temp = iArray[index];
iArray[index] = iArray[4-index];
iArray[4-index] = temp;
}
printf("Now Array is:\n");
for(index = 0; index< 5; index++)
{
printf("%d ", iArray[index]);
}
printf("\n");
return 0;
}
// 变量temp用来实现数据间的转换
for (index = 0; index < 2; index++)
{
temp = iArray[index];
iArray[index] = iArray[4-index];
iArray[4-index] = temp;
}
二、二维数组
1. 二维数组的定义
二维数组的声明与一维数组相同,
数组元素类型 数组名字[常量表达式1][常量表达式2];
其中“常量表达式1”被称为行下标,“常量表达式2”被称为列下标
2. 二维数组的引用
#include<stdio.h>
int main()
{
int a[4][2];
int i, j;
for (i = 0; i < 4; i++)
{
for (j = 0; j < 2; j++)
{
printf("a[%d][%d]=", i, j);
scanf("%d", &a[i][j]);
}
}
printf("输出二维数组:\n");
for (i = 0; i < 4; i++)
{
for (j = 0; j < 2; j++)
{
printf("%d\t", a[i][j]);
}
printf("\n");
}
int b[2][4];
for (j = 0; j < 2; j++)
{
for (i = 0; i < 4; i++)
{
b[j][i] = a[i][j];
}
}
printf("输出转置二维数组:\n");
for (j = 0; j < 2; j++)
{
for (i = 0; i < 4; i++)
{
printf("%d\t", b[j][i]);
}
printf("\n");
}
return 0;
}
三、字符数组
1. 字符数组的定义
符数组的定义与其他数据类型的数组定义类似
char 数组标识符[常量表达式];
因为是字符型数据,所以在数组标识符前所用的类型是char
#include<stdio.h>
int main()
{
char cArray[5]={'H','e','l','l','o'};
int i;
for(i=0;i<5;i++)
{
printf("%c",cArray[i]);
}
printf("\n");
return 0;
}
2. 字符数组的引用
字符数组的引用与其他类型数据引用一样,也是使用下标的形式。
#include<stdio.h>
int main()
{
int i = 0;
char cArray[5] = "Park";
printf("%s\n", cArray);
for (i = 0; i < 5; i++)
{
printf("%c", cArray[i]);
}
printf("\n");
return 0;
}
字符串总是以“\0”作为串的结束符
#include<stdio.h>
int main()
{
int i = 0;
char aArray[] = { 'H','e','l','l','o','\0' };
char bArray[] = { 'H','e','l','l','\0','o' };
char cArray[] = { 'H','e','l','\0','l','o' };
printf("%s\n", aArray);
printf("%s\n", bArray);
printf("%s\n", cArray);
return 0;
}
四、多维数组
多维数组的声明和二维数组相同,只是下标更多
数组元素类型 数组名字[常量表达式1][常量表达式2]...[常量表达式n];
int iArray1[1][2][3];
int iArray2[4][5][6][7];
五、数组的排序算法
选择法排序(selectionSort)
从所谓剩下的元素中选择最小或者最大的依次排列
无论什么数据进去都是 O(n²) 的时间复杂度
算法步骤:
1.在未排序序列中找到最小元素,放到排序序列的起始位置
2.在剩下的元素中寻找最小元素,紧跟着前面的排列
3.重复第二步,直到所有元素均排序完毕。
#include<iostream>
using namespace std;
int main()
{
int a[5] = { 31,42,13,24,35 };
int len = sizeof(a) / sizeof(a[0]);
for (int i = 0; i < len - 1; i++) {
int min = i;
// 每轮需要比较的次数 N-i
for (int j = i + 1; j < len; j++) {
if (a[j] < a[min]) {
// 记录目前能找到的最小值元素的下标
min = j;
}
}
// 将找到的最小值和i位置所在的值进行交换
if (i != min) {
int tmp = a[i];
a[i] = a[min];
a[min] = tmp;
}
}
for (int k = 0; k < 5; k++) {
cout << a[k] << " ";
}
}
冒泡法排序(Bubble Sort)
一次比较两个元素,如果顺序错误就把他们颠倒过来
越小或者越大的数据会经由交换慢慢浮现到数列的顶端
优化:
立一个flag;一遍中没有发生元素的交换则证明该序列已经有序
emmmm,bingmeiyoushenmodayong
1、算法步骤
1.比较相邻的元素,如果1>2,交换
2.对每一对相邻的元素都进行比较,从开始到结尾的最后一对//把最大的交换到末尾
3.重复//之后的第二遍时就不比较最后一个元素了
4.一直重复直到再没有一对元素需要比较
#include<iostream>
using namespace std;
int main()
{
int a[5] = { 31,42,13,24,35 };
int len = sizeof(a) / sizeof(a[0]);
for (int i = 0; i < len - 1; i++) {
for (int j = 0; j < len - 1 - i; j++) {
if (a[j] > a[j + 1]) { // 相邻元素两两对比
int temp = a[j + 1]; // 元素交换
a[j + 1] = a[j];
a[j] = temp;
}
}
}
for (int k = 0; k < 5; k++){
cout << a[k]<<" ";
}
}
交换法排序
#include<iostream>
using namespace std;
int main()
{
int i, j;
int a[5] = { 31,42,13,24,35 };
int iTemp;
for (i = 0; i < 4; i++) //外层循环元素下标为0~3
{
for (j = i + 1; j < 5; j++) //内层循环元素下标为i+1到4
{
if (a[j] < a[i]) //如果当前值比其他值大
{
iTemp = a[i];
a[i] = a[j];
a[j] = iTemp;
}
}
}
for (int k = 0; k < 5; k++) {
cout << a[k] << " ";
}
return 0;
}
插入法排序(insertionSort)
打扑克排序
优化:折半插入
1. 算法步骤
把第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。
从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。
(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)
#include<iostream>
using namespace std;
int main()
{
int a[5] = { 31,42,13,24,35 };
int len = sizeof(a) / sizeof(a[0]);
for (int i = 1; i < len; i++) {
// 记录要插入的数据
int tmp = a[i];
// 从已经排序的序列最右边的开始比较,找到比其小的数
int j = i;
while (j > 0 && tmp < a[j - 1]) {
a[j] = a[j - 1];
j--;
}
// 存在比其小的数,插入
if (j != i) {
a[j] = tmp;
}
}
for (int k = 0; k < 5; k++) {
cout << a[k] << " ";
}
}
折半法排序
#include<iostream>
using namespace std;
void CelerityRun(int left, int right, int array[]);
void CelerityRun(int left, int right, int array[])
{
int i, j;
int middle, iTemp;
i = left;
j = right;
middle = array[(left + right) / 2]; //找中间值
do
{
while ((array[i] < middle) && (i < right)) //从左找小于中值的数
i++;
while ((array[j] > middle) && (j > left)) //从右找大于中值的数
j--;
if (i <= j) //找到了一对值
{
iTemp = array[i];
array[i] = array[j];
array[j] = iTemp;
i++;
j--;
}
} while (i <= j); //如果两边的下标交错,就
//递归左半边
if (left < j)
CelerityRun(left, j, array);
//递归右半边
if (right > i)
CelerityRun(i, right, array);
}
int main()
{
int i;
int a[5] = { 31,42,13,24,35 };
CelerityRun(0, 4, a);
for (i = 0; i < 5; i++){
printf("%d ", a[i]);
}
return 0;
}
六、字符串处理函数
字符串复制函数(strcpy)
字符串复制函数,将后一个字符串复制到前一个字符串
由于不能像变量一样直接将一个字符串赋值给另一个字符串
这个函数相当于将后一个字符串赋值给前一个字符串
该函数复制定长的字符串到目的字符串中
strcpy(目的字符数组名,源字符数组名);
#include<stdio.h>
int main()
{
char str1[20];
char str2[10];
printf("请输入 str1:\n");
gets_s(str1, 20);
printf("请输入 str2:\n");
gets_s(str2, 10);
printf("\n");
printf("str1 已输入:\n");
puts(str1);
printf("str2 已输入:\n");
puts(str2);
printf("\n");
strcpy_s(str1, 20, str2);
printf("strcpy:\n");
printf("str1:\n");
puts(str1);
printf("str2:\n");
puts(str2);
return 0;
}
字符串连接函数(strcat)
将后一个字符串续接到到前一个字符串
#include<stdio.h>
int main()
{
char str1[20];
char str2[10];
printf("请输入 str1:\n");
gets_s(str1, 20);
printf("请输入 str2:\n");
gets_s(str2, 10);
printf("\n");
printf("str1 已输入:\n");
puts(str1);
printf("str2 已输入:\n");
puts(str2);
printf("\n");
strcpy_s(str1, 20, str2);
printf("strcpy:\n");
printf("str1:\n");
puts(str1);
printf("str2:\n");
puts(str2);
return 0;
}
字符串比较函数(strcmp)
字符串比较函数,比较ASCII值
相同时返回 0,前大于后返回正数,后大于前返回负数
#include<stdio.h>
int main()
{
char str1[20];
char str2[10];
printf("请输入 str1:\n");
gets_s(str1, 20);
printf("请输入 str2:\n");
gets_s(str2, 10);
printf("\n");
printf("str1 已输入:\n");
puts(str1);
printf("str2 已输入:\n");
puts(str2);
printf("\n");
if (strcmp(str1, str2) > 0)
{
printf("str1>str2");
}
else if (strcmp(str1, str2) < 0)
{
printf("str1<str2");
}
else {
printf("str1=str2");
}
return 0;
}
字符串大小写转换(strlwr、strupr)
strlwr()将大写字母转换为小写字母,其他字母不变
strupr()将小写字母转换为大写字母,其他字母不变
#include<stdio.h>
int main()
{
char str1[10];
char str2[10];
gets_s(str1, 10);
gets_s(str2, 10);
printf("已输入:\n");
printf("str1:\n");
puts(str1);
printf("str2:\n");
puts(str2);
printf("\n");
printf("strlwr()函数将大写字母转换为小写字母:\n");
_strlwr_s(str1, 10); // _strlwr_s()函数有变化,要给出字符串的长度
puts(str1);
printf("\n");
printf("strupr()函数将小写字母转换为大写字母:\n");
_strupr_s(str2, 10); // _strupr_s()函数有变化,要给出字符串的长度
puts(str2);
return 0;
}
获取字符串长度(strlen)
#include<stdio.h>
int main()
{
char str1[10];
int len;
printf("请输入str1:\n");
gets_s(str1, 10);
len = strlen(str1); // 返回值为字符串的长度,不包含“\0”
printf("该字符串的长度为:%d\n", len);
return 0;
}
七、打印杨辉三角
#include<stdio.h>
#define LINE 9 // 宏定义打印的行数
int main()
{
int i;
int j;
int a[LINE][LINE] = { 0 }; // 初始化
// 首列与对角线元素
for (i = 0; i < LINE; i++)
{
a[i][i] = 1; // 对角线元素全为 1
a[i][0] = 1; // 第一列元素全为 1
}
// 其余元素
for (i = 2; i < LINE; i++)
{
for (j = 1; j < i; j++)
{
a[i][j] = a[i - 1][j - 1] + a[i - 1][j];
}
}
// 输出
for (i = 0; i < LINE; i++)
{
for (int k = 1; k < (LINE - i); k++)
{
printf(" "); // 左边打印空格,使原本的直角三角形打印为等腰三角形
}
for (j = 0; j < i+1; j++) // 每行的元素个数刚好等于行下标加 1(即第n行有n个元素)
{
printf("%3d ", a[i][j]);
}
printf("\n");
}
return 0;
}