数组

| 这个作业属于哪个班级 | C语言--网络2011/2012 |
| ---- | ---- | ---- |
| 这个作业的地址 | C博客作业04--数组 |
| 这个作业的目标 | 学习数组相关内容 |
| 姓名 | 吕以晴 |



0.展示PTA总分(0----2)


1.本章学习总结(3分)

1.1 学习内容总结

⭐数组中如何查找数据

有序数组

  • 二分法

采用二分法,将最中间的数与用户输入的数进行比较,逐步缩小所求数在数组中的区间(+1或-1),直至匹配,或得出无法找到的结论。

无序数组


无序数组没有规律,它的查找只能线性进行,通过循环将数组中的前后元素逐个比较。

#include <stdio.h>
#define MAX 20
int main()
{
	int n;//输入n个整数
	int x;//需要找到的数字
	int arr[MAX];//定义数组用于储存输入的整数
	int flag = 1;

	scanf("%d %d", &n,&x);

	for (int i = 0; i < n; i++)//输入数组的各个元素
	{
		scanf("%d", &arr[i]);
	}

	for (int i = 0; i < n; i++)//遍历数组,寻找数字x
	{
		if (arr[i] == x)//找到所需数字
		{
			printf("%d", i);
			flag = 0;
			break;
		}
	}
	if (flag)//遍历数组后仍未寻到所需数字
	{
		printf("Not Found");
	}
	
	return 0;
}

⭐数组中如何插入数据


输入一个数x,将数组中的元素与x逐一比较,如果其大于x,则记录该元素的下标i,然后此元素下标和其后的元素的下标都加一,即后移一位,然后将x赋值给数组的那个下标arr[i]。

#include <stdio.h>
#define MAX 10
int main()
{
	int n,x;
	int temp;
	int arr[MAX];
	
	//输入
	scanf("%d", &n);//输入个数
	for (int i = 0; i < n; i++)//循环输入数组元素
	{
		scanf("%d", &arr[i]);
	}
	scanf("%d", &x);//输入需插入的数

	//插入排序
	if (x >= arr[n - 1])//插在尾
		{
			arr[n] = x;
		}

	else if (x <= arr[0])//插在头
	{
		for (int i = n; i > 0; i--)
		{
			arr[i] = arr[i - 1];
		}
		arr[0] = x;
	}
	else//插在中间
	{
		for (int i = 0; i < n; i++)
		{
			if ((arr[i] <= x && arr[i + 1] > x) || x <= arr[i])
			{
				for (int j = n; j > i + 1; j--)
				{
					arr[j] = arr[j - 1];
				}
				arr[i + 1] = x;
				break;
			}
		}
	}
	//输出数组元素
	int flag = 1;
	for (int i = 0; i <= n; i++)
	{
		printf("%d ", arr[i]);
	}

	return 0;
}

⭐数组中如何删除数据


输入一个数x,将数组中的元素与x逐一比较,若某一数组元素等于x,则记录该元素的下标i,且其后的数据都向前移位,实现覆盖第i项数据。

#include <stdio.h>
#define MAX 100
int main()
{
	int n;//表示数组元素个数
	int arr[MAX];
	int k;//表示删除次数
	int x;//表示每行删掉的数
	int num;

	//输入
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
	{
		scanf("%d", &arr[i]);
	}
	scanf("%d", &k);

	//删除元素
	num = n;//数组元素个数
	for (int i = 1; i <= k; i++)//删除次数
	{
		scanf("%d", &x);
		for (int i = x - 1; i < num - 1; i++)
		{
			arr[i] = arr[i + 1];
		}
		num -= 1;
	}

	//输出
	for (int i = 0; i < n - k; i++)
	{
		if (i == 0)//第一次输出,前不带空格
			printf("%d", arr[i]);
		else
			printf(" %d", arr[i]);
	}

	return 0;
}

⭐数组中目前学到排序方法及主要思路

  • 冒泡法

从当前元素起,向后依次比较每一对相邻元素,若逆序则交换。对所有元素均重复以上步骤,直至最后一个元素。

上方gif动图来自网络,某大佬博主

#include <stdio.h>
#define MAX 255 /*数组长度上限*/

void bubbleSort (int arr[], int len) 
{
    int temp;
    int i, j;
    for (i=0; i<len-1; i++) /* 外循环为排序趟数,len个数进行len-1趟 */
        for (j=0; j<len-1-i; j++) { /* 内循环为每趟比较的次数,第i趟比较len-i次 */
            if (arr[j] > arr[j+1]) { /* 相邻元素比较,若逆序则交换(升序为左大于右,降序反之) */
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
}
 
int main (void) {
    int arr[ARR_LEN] = {3,5,1,-7,4,9,-6,8,10,4};
    int len = 10;
    int i;
     
    bubbleSort (arr, len);
    for (i=0; i<len; i++)
        printf ("%d\t", arr[i]);
    printf("\n");
     
    return 0;
}
  • 选择法

每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到全部待排序的数据元素排完。

上方gif动图来自网络,某大佬博主

#include <stdio.h>
void swap(int *a,int *b) 
{
    int temp = *a;
    *a = *b;
    *b = temp;
}
void selectionSort(int arr[], int len) 
{
    int i,j;
 
    for (i = 0 ; i < len - 1 ; i++) 
    {
        int min = i;
        for (j = i + 1; j < len; j++)     
            if (arr[j] < arr[min])
                min = j; 
           swap(&arr[min], &arr[i]);    
    }
}

冒泡法与选择法的区别


  • 冒泡算法,每次比较如果发现较小的元素在后面,就交换两个相邻的元素。
  • 而选择排序算法先并不急于调换位置,先从a[0]开始逐个检查,看哪个数最小就记下该数的下标i,等一次遍历后,再把a[i]和a[0]对调,这时a[0]到a[10]中最小的数据就换到了最前面的位置。
  • 即选择排序每扫描一遍数组,只需要一次交换,而冒泡可能需要很多次。

⭐数组做枚举用法


用0-N的整形数字做下标可读性不高,为解决这个问题,我们可以使用枚举变量作为下标来访问数组。

enum color{black,white,red,blue,green}; //类型定义
enum color{black,white,red,blue,green} color1; //定义变量
enum color{black,white,red,blue,green} colorx[2]; //定义枚举类型的数组变量
  • enum 是枚举,也就说如果变量的类型为enum, 那么它的取值只可以是这个枚举中的一种。

⭐哈希数组用法


将一大类数据用已知的hash函数进行分类,映射到固定大小的数组中。

#include<stdio.h>//此处参考借用了网络上的哈希查找案例
 
#define LEN 13
#define N 11
int data[N]={10,9,8,7,5,4,6,3,2,1,95};   //原始数据;
int hash[LEN]={0};   //哈希表,初始化为0;
 
void Create()
{
	for(int i=0;i<N;i++)  //循环将原始数据保存到哈希表中;
	{
		//将关键字插入到哈希表hash中;
		int j=data[i]%13;  //计算哈希地址;
		while(hash[j])  //元素位置已被占用;
			j=(++j)%LEN;  //线性探测法解决冲突;
		hash[j]=data[i];
	}
}
int Haxi_Sou(int key)
{
	int i=key%LEN;  //计算哈希地址;
	while(hash[i]&&hash[i]!=key)   //判断是否冲突;
		i=(++i)%LEN;   //线性探测法解决冲突;
	if(hash[i]==0)  //查找到开放单元,表示查找失败;
		return -1;  //返回失败值;
	else
		return i;   //返回对应的元素下标;
}
int main(void)
{
	int key;
	Create();  //调用函数创建哈希表;
	printf("哈希表中各元素的值:");
	for(int i=0;i<LEN;i++)
		printf("%d ",hash[i]);
	printf("\n");
	printf("输入查找的关键字;");
	scanf("%d",&key);
 
	int pos=Haxi_Sou(key);  //调用函数在哈希表中查找;
	if(pos>0)
		printf("查找成功,该关键字在数组中的下标为 %d !!!",pos);
	else
		printf("查找失败!!!");
	printf("\n");
	return 0;
}

⭐字符数组、字符串特点及编程注意事项

  • 要数组传入一个函数作判断时,需传入数组名和数组长度。
    eg
int arr[10];
scanf("%d",&n);
ChooseSort(arr,n)//传入的为数组名arr,而不是arr[]
void ChooseSort(int date[],int n)或(int *p,int n
  • static int a[10],可将数组元素全部初始化为0。
  • 字符串的输出"%s",字符的输出"%c"。
  • 字符串常量:用一对双引号""括起来的字符序列。
  • \0--字符串结束符,其等于0,所以判断最后一个元素时可写成s[i]!=0或s[i]!='\0'(注意为单引号,'\0')。
  • 字符数组的最后一个元素是'\0',所以char s[N]="Happy"的数组长度为6(还有一个'\0')。
  • "a"为字符串,在内存中占两个字节(a,\0);'a'为字符,在内存中只占一个字节(a)。
  • 输入:fgets(buf,10,stdin)//buf为数组名,10为数组的最大长度,可接收空格及其他字符。
    当读取 (n-1) 个字符时,或者读取到换行符时,或者到达文件末尾时,它会停止,具体视情况而定。


2.PTA实验作业(7分)

2.1 将数组中的数逆序存放

⭐2.1.1 伪代码

⭐2.1.2 代码截图

⭐2.1.3 找一份同学代码比较,说明各自代码特点

对比与反思


  • 我的代码与该同学的代码的区别主要是对逆序的处理方法不同。
  • 该同学在输入数组元素后采用逆序的方法直接输出(即从n开始--),而我是采用了两两交换的方法(第一位与最后一位交换,第二位与倒数第二位交换......)对数组重新赋值,最后再输出数组元素。
  • 相比之下,我的方法显得更为繁琐,多了许多无意义的步骤,我会争取在后面的编程中改进,写题前尽量思考简便的做法。

2.2 鞍点

⭐2.2.1 伪代码


⭐2.2.2 代码截图


⭐2.2.3 请说明和超星视频做法区别,各自优缺点


  • 大体思路相同,均是先找到一行中的最大元素,然后循环判断其与在所在的列上的其他元素,若其是所在列的最小值,则为鞍点,反之不是鞍点。
  • 我的写法与超星相似,但在变量名的设计上还有待提高。
  • 我们应该注意的是循环中用于标志是否为鞍点的变量flag需在每次循环时重赋值,否则会影响结果。

2.3 切分表达式

⭐2.3.1 伪代码


⭐2.3.2 代码截图


⭐2.3.3 请说明和超星视频做法区别,各自优缺点


  • 超星使用了continue语句来提前结束循环,以减少程序运行时间,大大提高了程序的效率。
  • 超星将切分表达式所需的代码分装成不同的功能函数,使主函数更加简洁,同时使代码更加清晰易懂,便于读者阅读。
  • 我对运算符的分类比超星更少,但没有想到可以使用continue语句,编程能力仍需提高,同时超星上的变量命名及功能函数的分装也是我所欠缺的部分。
posted @ 2020-12-13 22:42  noyiie  阅读(101)  评论(0编辑  收藏  举报
// 侧边栏目录 // https://blog-static.cnblogs.com/files/douzujun/marvin.nav.my1502.css