第六章数组

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

例6-8 顺序检索
“检索”与“分类”是互相联系在一起的, 检索” 分类”是互相联系在一起的, 也是计算机科学中研究的一类重要课题。 也是计算机科学中研究的一类重要课题。 我们仍以整数组A为背景介绍两种较常见的 我们仍以整数组A 算法 A已经按递增排序。 已经按递增排序。
13
检索思想
int data[6];
j
2
4
11
3
a[0] 、... 、a[j] 、a[i] 、a[j+1] 、... 、a[i-1] a[i开始 for(i=1;i<n;i++) 结束 求位置 j ,使 a[j] <= a[i] < a[j+1] 把 a[i] 插到 a[j] 和 a[j+1] 之间
9
为a[i] 寻找适当位置使a[j]<=a[i]<a[j+1] 寻找适当位置使a[j]<=a[i]<a[j+1] 只要从a[i-1]开始向前 只要从a[i-1]开始向前,用a[i]与序列上的元素逐一 开始向前, a[i]与序列上的元素逐一 进行比较,直到找到满足条件的位置为止(当然j 进行比较,直到找到满足条件的位置为止(当然j不 能超过序列A的第一个位置) 能超过序列A的第一个位置) 开始 for(i=1;i<n;i++) 结束 j=i-1求位置 j ,使 求位置 a[j] <= a[i] < a[j+1] (a[j]>a[i])&&(j>=0) j=j-1 把 a[i] 插到 a[j] 和 a[j+1] 之间
14
#include <stdio.h> 顺序检索 #define L 5 for (j=0;j<n && key!=a[j] ;j++) ; int seq_search(int n,int a[ ],int key){……}//函数定义 函数定义 void main(){ 运行结果演示 return j int a[L]; int i,key; 结束 printf("please input the vector[5]:\n"); for(i=0;i<L;i++) scanf("%d",&a[i]); int search (int n, int a[ inputkey ){ // key为检索关键字 (int key为检索关键字 printf("\nplease ], int the keyword:"); int j ; /* 返回位置 */ scanf("%d",&key); for (j=0; j<n && key!=a[j]; j++) ; if( (i= seq_search(L,a,key) 函数调用 return j; for (j=0;j<10;j++) ; )<L)//函数调用 printf("find %d a[%d]\n",key,i); } sum+=j; 循环控制部分后边没有循环体, 注意:第三行语句。 注意 循环控制部分后边没有循环体 else :第三行语句。在for循环控制部分后边没有循环体, for (j=0; j<n && key!=a[j]; j++) 仅使用一个分号“ 仅使用一个分号“;”。 %d\n",key); printf("not find { , 一个孤立的分号,不缀在任何符号之后,称为“空语句” 一个孤立的分号; }不缀在任何符号之后,称为“空语句”。 } 空语句表示无任何操作,只占有一个语句位置。 空语句表示无任何操作,只占有一个语句位置。
8
使 a[0]、... 、a[i] 递增 、
使 a[0] 、a[1] 、... 、a[i-1] 、a[i] 递增 a[i– a[0]、a[1]、... 、a[i-1]递增 a[0]、a[1]、 a[i-1]递增 – 需要在其中找到一个适当位置来放a[i] 需要在其中找到一个适当位置来放a[i] 则应该首先找到一个j 则应该首先找到一个j , 使 a[j]<=a[i]<a[j+1] a[j]<=a[i]< 然后,把a[i]插到序列 然后, a[i]插到序列
2
4
11
3
10
把a[i]插到a[j]和a[j+1]之间 a[i]插到 插到a[j]和a[j+1]之间 a[j+1]、a[j+2]、 a[j+1]、a[j+2]、... 、a[i-1]顺序向后串 a[i-1]顺序向后串 分别送入a[j+2]、 分别送入a[j+2]、a[j+3] 、... 、a[i]中 a[i]中 然后把 a[i] 送入 a[j+1] 中即可 为了向后串, 为了向后串,必须先记录 a[i] j=i-1 开始 for(i=1;i<n;i++) 结束 a[j]>a[i])&&(j>=0) j=j-1 a[k+1] = for(k=i-1;k>=j+1;k--) a[k] 把 a[i] 插到 a[j+1]=r a[j] 和 a[j+1] 之间
数组下标: 数组下标:
1 45 89 90 123 149
0 1 2 3 4 5
欲检索的数:key=89 函数返回2 欲检索的数: 函数返回 欲检索的数: 欲检索的数:key=88 函数返回6 函数返回
顺次用欲检索的关键字值key与数组A中元素a[0]、 顺次用欲检索的关键字值key与数组A中元素a[0]、 与数组 a[1]、 a[1]、... 、a[n-1]逐一进行比较。 a[n-1]逐一进行比较 逐一进行比较。 找到一个j key==a[j]: 找到一个j使key==a[j]: 位置为j 函数search带着 返回; 位置为j,函数search带着j返回; 带着j 直到结束,没有使key==a[j]的 存在: 直到结束,没有使key==a[j]的j存在: 未找到,函数search带回值的 带回值的j 未找到,函数search带回值的j值将大于等于 n。
15
例6-9 对半检索
“对半检索”亦称“两分法检索”。在检索过程中 对半检索”亦称“两分法检索” 用到三个变量: 用到三个变量: lower : 记录检索区间下界,初值是0 ; 记录检索区间下界,初值是0 upper : 记录检索区间上界,初值是n-1 ; 记录检索区间上界,初值是n j: 标记当前检索位置。 标记当前检索位置。
6
11
2
3
1
2
11
3
1
2
3
11
1
1
2
3
11
7
当子序列只有一个元素a[0]时 当子序列只有一个元素a[0]时,它自然递增 这样,一个个向该子序列加元素,每加一个元素后, 这样,一个个向该子序列加元素,每加一个元素后, 都使新的子序列仍保持递增; 都使新的子序列仍保持递增; 直到将最后一个元素a[n-1]加入子序列为止 直到将最后一个元素a[n-1]加入子序列为止,便完 加入子序列为止, 成了对序列A 成了对序列A的排序 开始 for(i=1;i<n;i++) 结束
例6-6 对整数组A进行 冒泡法排序 对整数组A
冒泡法排序思想
– 从头至尾扫描被排序数组A (i 从 0 到 n-2),比较A数组 从头至尾扫描被排序数组A 2),比较A 的所有相邻元素 a[i] 、a[i+1] a[i]>a[i+1]则交换 则交换a[i]、 若a[i]>a[i+1]则交换a[i]、a[i+1] – 如此反复进行,直到某一次扫描,没有数据交换为止, 如此反复进行,直到某一次扫描,没有数据交换为止, 便完成了对数组A 便完成了对数组A的排序 – 至多扫描n次就可以使数组A完成排序,所以该算法能 至多扫描n 就可以使数组A完成排序, 够终止。 够终止。
16
检索思想令j=(lower+upper)/2 检索思想令j=(lower+upper)/2 – key==a[j]: 找到,位置为j;函数search返回j 找到,位置为j;函数search返回 返回j j;函数 – key<a[j]: key在a[lower]与a[j]之间 key在a[lower]与a[j]之间 检索区间缩小一半,upper=j检索区间缩小一半,upper=j-1 – key>a[j]: key在a[j]与a[upper]之间, key在a[j]与a[upper]之间, 之间 检索区间缩小一半,lower=j+1 检索区间缩小一半,lower=j+1 重复上述过程。重复的终止条件为 重复上述过程。 upperupper-lower < 0 ,表示未找到,返回 -1 。 表示未找到, lower upper lower upper
1
第一轮: 第一轮 下标 0
7 4 1 6 5 4 1 6 5 7
4 7 1 6 5 1 4 6 5 7
4 1 7 6 5 1 4 5 6 7
4 1 6 7 5
第三轮: 第三轮
4 1 6 5 7 1 4 5 6 72
1 2 3 4
Baidu Nhomakorabea第二轮: 第二轮
用bool型变量flag标志一次扫描过程中是否有数据交换 bool型变量 型变量flag标志一次扫描过程中是否有数据交换 判断是否需要进行下一轮扫描步骤 – 每次扫描开始令 flag=false ,假设没有数据交换 – 然后,当有数据交换时令 flag=true 然后, – 最后在一遍扫描结束后: 最后在一遍扫描结束后: 若 flag==true 则说明本次扫描有数据交换,还 则说明本次扫描有数据交换, 应进行下一次扫描 否则扫描终止
3
冒泡排序 flag=true flag=false
while(flag)
for(i=0;i<n-1; i++)
a[i]>a[i+1]
交换 a[i],a[i+1] flag=true
结束
4
#include <stdio.h> #define L 5
运行结果演示
void sortofup ( int n, int a[ ] ) { int i,r ; void main(){ bool data[L]; int flag ; flag = true ; int i; while ( flag ) { input the vector[5]:\n"); printf("please flag = false ; for(i=0;i<L;i++) for ( scanf("%d",&data[i]); i=0 ; i<n-1 ; i++ ) if ( a[i] >函数调用 a[i+1] ){ sort(L,data); //函数调用 r = a[i] ; printf("after sort:\n"); a[i] = for(i=0;i<L;i++) a[i+1] ; a[i+1] = r ; printf("%4d",data[i]); flag=true; printf("\n"); } } } }
11
r=a[i]
2
j
4 3
3
11 11 4 3
#include <stdio.h> a[ ] ) { void sort ( int n, int #define Li, j,k,r ; int 5 void sort(( int n,int a[ i++{……}//函数定义 函数定义 for i=1 ; i<n ; ] ) ) void main(){ 寻找适当位置使a[j]<=a[i]<a[j+1]*/ /*为 { /*为a[i] 寻找适当位置使a[j]<=a[i]<a[j+1]*/ int data[L];; j = i-1 int i;while ( (a[j]>a[i])&&(j>=0) ) printf("please input the vector[5]:\n"); j=j-1 ; for(i=0;i<L;i++) /*把a[i]插到 和a[j+1]之间 /*把a[i]插到a[j]和a[j+1]之间*/ 插到a[j] 之间* scanf("%d",&data[i]); r=a[i]; sort(L,data); //函数调用 函数调用 for ( k=i-1 ; k>=j+1 ; k-- ) printf("after sort:\n"); 运行结果演示 a[k+1] = a[k] ; for(i=0;i<L;i++) a[j+1]=r; printf("%4d",data[i]); } printf("\n"); } } 12
5
例6-7 用“逐步增加递增子序列”法 逐步增加递增子序列” 对 整数组A 整数组A进行排序
排序思想
– 把数组A看成一个序列 把数组A a[0]、a[1]、 a[0]、a[1]、... 、a[i-1] 、a[i]、... 、a[n-1] a[ia[i]、 a[n– 假设下面子序列已经是递增 a[0] 、a[1] 、... 、a[i-1] a[i– 给上述子序列再加一个元素a[i] 给上述子序列再加一个元素a[i] 若有办法使子序列 a[0] 、a[1] 、... 、a[i-1] 、a[i] a[i仍是递增的便可以完成对A的排序。 仍是递增的便可以完成对A的排序。
相关文档
最新文档