算法设计题1

更新时间:2023-07-14 06:09:49 阅读: 评论:0

出2个算法设计题,每个20分。
1. a[0:n-1]是有n个元素的数组,k(0≤kn-1)是一个非负整数。试设计一个算法将子数组a[0:k-1]和a[k:n-1]换位。要求算法在最坏情况下耗时O(n),且只用到O(1)的辅助空间。
初步思考:最简单的方法就是循环(n-k-1)次,将a数组的末尾数字插入到a[0]之前。
具体做法:法一:(1) 首先开辟一个额外空间temp用于存放每一次a数组的末尾数据。
              (2) temp <- a[n-1]
              (3) 将a[0: n-2] 每个数据都依次向后移动一位赋值给a[1: n-1]。
              (4) a[0] <- temp
              (5) 循环执行(2) -(4) 步 (n-k+1)次。
代价分析: 时间代价—— O((n-1)*(n-k+1))  即O(n^2)数量级;空间代价——O(1)
法二:如果a[0 : k] 与 a[k+1 : n-1] 正好长度相等,则可以直接一一对应交换即可。 当然,这
道题的难点就在于k并不一定是a数组的中间位置。即便如此,但是仍然可以交换:
    如果a[0 : k].length< a[k+1 : n-1].length, 则可以将a[0 : k] 与 a[k+1 : n-1] 中最后一部分大小相同的数据交换:
                                            |--------  a[k+1 : n-1] -----------|
                            a[0:k]      a[k+1 : n-k-2]      a[n-k-1 : n-1] 
    其中  a[0:k] 与  a[n-k-1 : n-1]  长度相同,因此完全可以一一对应交换成:
                              |------  a[0 : n-k-2] -------|秋天的祝福语
                            a[0:k]        a[k+1 : n-k-2]    a[n-k-1 : n-1]
    交换完成以后,则a[n-k-1 : n-1] 已经交换到位,而a[0 : n-k-2 ]还需要进一步这样递归交换。
源代码如下:
C代码
1 格列喹酮片说明书#include<stdio.h>  
2  
3 //交换数组的两段大小相等的范围的对应数据  
4 //a[low1] <->a[low2]  a[low1+1]<->a[low2+1]  ... a[high1] <-> a[high2]  
5 void s a[],int low1,int high1,int low2,int high2){ 
6  
7     int temp; 
8     while(low1<=high1){ 
9         temp=a[low1]; 
10         a[low1]=a[low2]; 
11         a[low2]=temp; 
12         low1++; 
13         low2++; 
14     } 
15
16  
17 //利用分治算法, 每次选择最小的数组进行换位  
18 void patition(int a[], int low, int k, int high){ 
19  
20     if(low<high){ 
21         if((k-low+1)==(high-k)) 
22             s); 
23         el if((k-low+1)<(high-k)){ 
24             s); 
25             patition(a,low,k,low+high-k-1); 
26         } 
27         el
28             s); 
29             patition(a,high+low-k,k,high); 
30         } 
31     } 
32  
33
34 //测试  
35 int main(){ 
36     int a[]={0,1,2,3,4,5,6,7,8,9,10,11,12,13}; 
37     patition(a,0,4,13); 
38     for(int i=0;i<14;i++){ 
桂花茶功效39         printf("%d  ",a[i]); 
40     } 
41     return 0; 
42
[c] view plaincopy
43 真情真爱#include<stdio.h> 
44  
45 //交换数组的两段大小相等的范围的对应数据 
46 //a[low1] <->a[low2]  a[low1+1]<->a[low2+1]  ... a[high1] <-> a[high2] 
47 void s a[],int low1,int high1,int low2,int high2){ 
48  
49     int temp; 
50     舌尖上的中国观后感while(low1<=high1){ 
51         temp=a[low1]; 
52         a[low1]=a[low2]; 
53         a[low2]=temp; 
54         low1++; 
55         low2++; 
56     } 
57
58  
59 //利用分治算法, 每次选择最小的数组进行换位 
60 void patition(int a[], int low, int k, int high){ 
61  
62     if(low<high){ 
63         if((k-low+1)==(high-k)) 
64             s); 
65         el if((k-low+1)<(high-k)){ 
66             s); 
67             patition(a,low,k,low+high-k-1); 
68         } 
cofco69         el
70             s); 
71             patition(a,high+low-k,k,high); 
72         } 
73     } 
74  
75
76 //测试 
77 int main(){  中月
78     int a[]={0,1,2,3,4,5,6,7,8,9,10,11,12,13}; 
79     patition(a,0,4,13); 
80     for(int i=0;i<14;i++){ 
81         printf("%d  ",a[i]); 
82     } 
83     return 0; 
84
        这样的时间复杂度为O(n),而且交换数据的时候只需要O(1)的额外空间。
2. 设子数组a[0:k-1]和a[k:n-1]已经排好序k(0≤kn-1)。试设计一个合并这两个子数组为排好序的数组a[0:n-1]的算法。要求算法在最坏情况下耗时O(n),且只用到O(1)的辅助空间。
1)向右循环换位合并
向右循环换位合并算法首先用二分搜索算法在数组段a[k:n-1]中搜索a[0]的插入位置,即找到位置p使得a[p]<a[0]<=a[p+1]。数组段a[0:p]向右循环换位p-k+1个位置,使得a[k-1]移动到a[p]的位置。此时,原数组a[0]及其左边的所有元素均已经排好序。对剩余的数组元素重复上述过程,直到只剩下一个数组段,此时整个数组已经排好序。
    代码如下所示。
1 #include <iostream>
2 using namespace std;
3
4 #define MAXNUM 100
5
6 //下面函数将数组段a[s:t活跃度]中元素循环右移位k个位置
7 void shiftright(int a[], int s, int t, int k)
8 {
9     int i = 0;
10     int j = 0;
11     for(i = 0; i < k; i++)
12     {
13         int tmp = a[t];
14         for(j = t; j > s; j--)
15         {
16             a[j] = a[j-1];
17         }
18         a[s] = tmp;
19     }
20 }
21
22 //下面函数用于在数组段中a[left:right]中搜索元素x的插入位置
23 int binarySearch(int a[], int x, int left, int right)
24 {
25     int mid;
26     while(left <= right)
27     {
28         mid = left + (right - left)/2;
29         if(x == a[mid])
30         {
31             return mid;
32         }
33         if(x > a[mid])
34         {
35             left = mid + 1;
36         }
37         el
38         {
39             right = mid - 1;
40         }
41     }
42     if(x > a[mid])
43     {
44         return mid;
45     }
46     el
47     {
48         return mid - 1;
49     }
50 }
51
52 //向右循环移位合并算法
53 //length:数组的长度
54 void mergefor(int a[], int k, int length)
55 {
56     //merge a[0:k-1] and a[k:n-1]
57     int i = 0;
58     int j = k;
59     while(i < j && j < length)
60     {
61         int p = binarySearch(a, a[i], j, length - 1);

本文发布于:2023-07-14 06:09:49,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/1095619.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

上一篇:jicable07_C_5_1_5
下一篇:国外建筑期刊
标签:数组   算法   循环   空间   交换   位置   换位
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图