算法导论 practice1

1、      (2.3.7) Describe a Θ(n lg n)-time algorithm that, given a set S of n integers and another integer x, determines whether or not there exist two elements in S whose sum is exactly x.给定含有n个整型数的集合S和整型数x,确定s中是否存在两个元素的和等于x。算法时间复杂度为c塔nlgn。

 

 

判断是否存在的函数的时间复杂度小于0(nlgn),归并排序的时间复杂度是0(nlgn)。

 

 2 
 3 #include<stdio.h>
 4 #include<stdlib.h>
 5 void merge(int arr[],int low,int mid,int high){
 6      int i,k;
 7      int *tmp=(int*)malloc((high-low+1)*sizeof(int));
 8      int left_low=low;
 9      int left_high=mid;
10      int right_low=mid+1;
11      int right_high=high;
12      for(k=0;left_low<=left_high&&right_low<=right_high;k++)
13      {
14      if(arr[left_low]<=arr[right_low]){
15                                        tmp[k]=arr[left_low++];
16                                        }
17      else{
18           tmp[k]=arr[right_low++];
19           }
20 } 
21      
22      if(left_low<=left_high){
23                              for(i=left_low;i<=left_high;i++){
24                                                               tmp[k++]=arr[i];
25                                                               }
26                              }
27       if(right_low<=right_high){
28                              for(i=right_low;i<=right_high;i++)
29                                                                tmp[k++]=arr[i];
30                                                        }
31                              for(i=0;i<high-low+1;i++)
32                                                       arr[low+i]=tmp[i];
33      
34 }
35 
36 void merge_sort(int a[],int p,int r){
37      int q;
38      if(p<r){
39              q=(p+r)/2;
40              merge_sort(a,p,q);
41              merge_sort(a,q+1,r);
42              merge(a,p,q,r);
43              }
44      }
45 int main(){
46     int a[8]={3,5,8,6,4,1,1};
47     int i,j;
48     int x=10;
49     merge_sort(a,0,6);
50     printf("after Merging-Sort:\n");
51     for(i=0;i<7;i++){
52                      printf("%d",a[i]);
53                      }
54     printf("\n");
55     i=0;j=6;
56     do{
57                  
58                  if(a[i]+a[j]==x){
59                                  printf("exist");
60                                  break;
61                                  }
62                  if(a[i]+a[j]>x)
63                                 j--;
64                  if(a[i]+a[j]<x)
65                                 i++;
66                       }while(i<=j);
67     if(i>j) 
68             printf("not exist");
69     system("pause");
70     return 0;
71     }

 

2、      Implement priority queue.

优先队列

 

 

 

  1  
  2 
  3 #include<stdlib.h>
  4 #include<stdio.h>
  5 #include<math.h>
  6 #define SIZE 7
  7 int PARENT(int i){
  8     return (int)floor(i/2);
  9     }
 10 int LEFT(int i){
 11     return 2*i;
 12     }
 13 int RIGHT(int i){
 14     return 2*i+1;
 15     }
 16 void MAX_HEAPIFY(int arr[],int i){
 17      int l=LEFT(i);
 18      int r=RIGHT(i);
 19      int largest;
 20      if(l<=SIZE&&arr[l]>arr[i]){
 21                                            largest=l;
 22                                            }
 23      else largest=i;
 24      if(r<SIZE&&arr[r]>arr[largest]){
 25                                                  largest=r;
 26                                                  }
 27      if(!largest==i){
 28                     int t;
 29                     t=arr[i];arr[i]=arr[largest];arr[largest]=t;
 30                     MAX_HEAPIFY(arr,i);
 31                     }
 32      }
 33 void BULID_MAX_HEAP(int arr[]){
 34      //SIZE=arr[].length;
 35      for(int i=(int)floor(SIZE/2);i>0;i--){
 36              MAX_HEAPIFY(arr,i);
 37              }
 38      }
 39 void HEAPSORT(int arr[]){
 40      BULID_MAX_HEAP(arr);
 41      int length=SIZE;
 42      for(int i=length;i>1;i--){
 43              int t;
 44              t=arr[1];arr[1]=arr[i];arr[i]=t;
 45              length=length-1;
 46              MAX_HEAPIFY(arr,1);
 47              }
 48      }
 49 
 50 int HEAP_MAXIMUM(int arr[]){
 51     return arr[1];
 52     }
 53 int HEAP_EXTRACT_MAX(int arr[]){
 54     if (SIZE<1){
 55                            printf("error:heap underflow");
 56                            }
 57     int max=arr[1];
 58     arr[1]=arr[SIZE];
 59     int length=SIZE;
 60     length=length-1;
 61     MAX_HEAPIFY(arr,1);
 62     return max;
 63     }
 64 void HEAP_INCREASE_KEY(int arr[],int i,int key){
 65      if(key<arr[i]){
 66                     printf("error:new key is smaller than current key");
 67                     }
 68      arr[i]=key;
 69      while (i>1&&arr[PARENT(i)]<arr[i]){
 70            int t;
 71            t=arr[i];arr[i]=arr[PARENT(i)];arr[PARENT(i)]=t;
 72            i=PARENT(i);
 73            } 
 74      }
 75 void MAX_HEAP_INSERT(int arr[],int key){
 76      int length=SIZE;
 77     length=length+1;
 78      arr[SIZE]=-10000;
 79      HEAP_INCREASE_KEY(arr,SIZE,key);
 80      }
 81 /*int HEAP_MAXIMUM(int arr[]){
 82     BULID_MAX_HEAP(arr[]);
 83     return arr[1];
 84     }
 85     */
 86 int main(){
 87     int arr[7]={3,5,8,6,4,1,1};
 88     int key,i;
 89     HEAPSORT(arr);
 90     printf("堆排序后:");
 91     for(int i=0;i<7;i++){
 92                      printf("%d ",arr[i]);
 93                      }
 94     printf("\n"); 
 95     printf("最大值是:%d\n",HEAP_MAXIMUM(arr));
 96     HEAP_EXTRACT_MAX(arr);
 97     printf("已经去掉最大值\n");
 98     printf("请输入key的值");
 99     scanf("%d",&key); 
100     printf("请输入i的值");
101     scanf("%d",&i);
102     HEAP_INCREASE_KEY(arr,i,key);
103     printf("已经把下标为i的元素值增加到key");
104     system("pause");    
105     return 0;
106 
107     }

 

3、      Implement Quicksort and Randomized Quicksort. Answer the following questions. (1) How many comparisons will Quicksort do on a list of n elements that all have the same value? (2) What are the maximum and minimum number of comparisons will Quicksort do on a list of n elements, give an instance for maximum and minimum case respectively.

实现Quicksoet和Randomized。

实现普通快速排序的两个函数:

 

实现随机快速排序的两个函数:

  

 

请回答1、列表中n个元素的值都相同时,Quicksoet比较几次。

答: (n-1)+(n-2)+…+1=n(n-1)/2

2、列表中有n个元素,比较次数的最大值最小值是多少,分别给出对应情况。

答:最坏情况是枢纽元素把其余数字分的个数区别很大,O(n­­方)

最好情况是枢纽元素恰好是中位数,O(nlgn)

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<math.h>
 4 int PARTITION(int a[],int p,int r){
 5     int x=a[r];
 6     int i=p-1;
 7     int j;
 8     for(j=p;j<r;j++){
 9                      if(a[j]<=x){
10                                  i=i+1;
11                                  int t=a[i];a[i]=a[j];a[j]=t;
12                                  }
13                      } 
14     int t=a[i+1];a[i+1]=a[r];a[r]=t;
15     return i+1;
16     }
17     
18 void QUICKSORT(int a[],int p,int r){
19      int q;
20      if(p<r){
21              q=PARTITION(a,p,r);
22              QUICKSORT(a,p,q-1);
23              QUICKSORT(a,q+1,r);
24              }
25      }
26      
27 int RAN_PAR(int a[],int p,int r){
28     int i=p + rand()%(r-p+1);
29     int t=a[r];a[r]=a[i];a[i]=t;
30     return PARTITION(a,p,r);
31     }
32 void RAN_QUI(int a[],int p,int r){
33      if(p<r){
34              int q=RAN_PAR(a,p,r);
35              RAN_QUI(a,p,q-1);
36              RAN_QUI(a,q+1,r);
37              }
38      }
39 
40 int main(){
41     int a[8]={3,5,8,6,4,1,1};
42     int i;
43     printf("输入1进行QUICKSORT,输入2进行RAN-QUI\n请输入:\n");
44     int k;
45     scanf("%d",&k);
46     
47     if(k==1){ 
48     printf("after QUICKSORT:\n");
49     QUICKSORT(a,0,6);
50     for(i=0;i<7;i++){
51                      printf("%d",a[i]);
52                      }
53     printf("\n");
54     }
55     
56     if(k==2){
57     printf("after RAN-QUI:\n");
58     RAN_QUI(a,0,6);
59     for(i=0;i<7;i++){
60                      printf("%d",a[i]);
61                      }
62     printf("\n");
63     }
64     system("pause");
65     return 0;
66     }

 

4、(8.2) Sorting in place in linear time

Suppose that we have an array of n data records to sort and that the key of each record has the value 0 or 1. An algorithm for sorting such a set of records might possess some subset of the following three desirable characteristics:

1. The algorithm runs in O(n) time.

2. The algorithm is stable.

3. The algorithm sorts in place, using no more than a constant amount of storage space in addition to the original array.

a. Give an algorithm that satisfies criteria 1 and 2 above.

b. Give an algorithm that satisfies criteria 1 and 3 above.

c. Give an algorithm that satisfies criteria 2 and 3 above.

d. Can you use any of your sorting algorithms from parts (a)–(c) as the sorting method used in line 2 of RADIX-SORT, so that RADIX-SORT sorts n records with b-bit keys in O(bn) time? Explain how or why not.

e. Suppose that the n records have keys in the range from 1 to k. Show how to modify counting sort so that it sorts the records in place in O(n+k) time. You may use O(k) storage outside the input array. Is your algorithm stable? (Hint: How would you do it for k = 3?)

线性时间排序假设对一个有n个数据记录的数组进行排序,每个记录的key值是0或1,。设计给其排序的算法,该算法要包含以下3个要求:1、O(N);2、稳定;3、原址排序,使用的空间不能超过原数据的

A、满足1 2

B、满足1 3

C、满足2 3

D、能否将abc中的算法用于基数排序第二行,使其在排序有b个关键字的n个记录时的时间复杂度为o(bn)

E、假设有n条记录,关键字的范围是1-k。怎么修改基数排序使其为o(n+k)的原址排序。除了输入数组外,可以使用o(k)的额外存储。给出的算法稳定么(提示:当k=3时怎么做?)

 

4a计数排序满足o(n)和稳定

 2 
 3 #include<stdio.h>
 4 #include<stdlib.h>
 5 #define A_LENGTH 8
 6 void COUNTING_SORT(int a[],int b[],int k){
 7      int c[6];
 8      for(int i=0;i<k;i++){
 9              c[i]=0;
10              }
11      for(int j=0;j<A_LENGTH;j++){
12              c[a[j]]=c[a[j]]+1;
13              }
14      for(int i=0;i<k;i++){
15              c[i]=c[i]+c[i-1];
16              }
17      for(int j=A_LENGTH-1;j>0;j--){
18              b[c[a[j]]]=a[j];
19              c[a[j]]=c[a[j]]-1;
20             }
21       }
22 int main(){
23     int a[8]={2,5,3,0,2,3,0,3};
24     int b[8]={0,0,0,0,0,0,0,0};
25     COUNTING_SORT(a,b,6);
26     for(int i=0;i<A_LENGTH;i++){
27             printf("%d ",b[i]);
28             }
29             
30     system("pause");
31     return 0;
32     }

 

4b 冒泡排序满足o(n)和原址

 

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 void bubble_sort(int a[],int n)
 4 {
 5     for(int i=0; i<n-1; i++)
 6     {
 7         for(int j=0; j<n-1-i; j++)
 8         {
 9             if(a[j] > a[j+1])
10             {
11                 int temp = a[j];a[j] = a[j+1];a[j+1]=temp;
12             }
13         }
14     }
15 }
16 int main(){
17     int a[8]={4,5,6,3,2,1,8,7};
18     bubble_sort(a,8);
19     printf("冒泡排序最好情况满足o(n)和原址\n");
20     for(int i=0;i<8;i++){
21             printf("%d ",a[i]);
22             }
23     system("pause");
24     return 0;
25     }

 

4c 插入排序满足稳定和原址

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #define N 8
 4 void insert_sort(int a[],int n)
 5 {
 6     for(int i=1; i<n; i++)
 7     {
 8         int j=0;
 9         while( (a[j]<a[i]) && (j<i))
10         {
11             j++;
12         }
13         if(i != j)        {
14             int temp = a[i];
15             for(int k = i; k > j; k--)
16             {
17                 a[k] = a[k-1];
18             }
19             a[j] = temp;
20         }
21     }
22 }
23 int  main()
24 {
25     int num[N] = {4,5,6,3,2,1,8,7};
26     insert_sort(num, N);
27     printf("插入排序满足稳定和原址\n");
28     for(int i=0; i<N; i++)
29         printf("%d  ", num[i]);
30     printf("\n");
31     system("pause");
32     return 0;
33 }

 

4d

计数排序可以,因为其时间复杂度为o(n)且稳定。给定n

个b位数,其中每一个数位有k种可能取值,耗时为c塔n+k,则基数排序耗时c塔(b(n+k)),即o(bn)。

 

4e

当K=3时的示例图:

 

伪代码:

For i=k downto 1{

For(n=a.length;c[k]>0;c[k]--){

                                    A[n]=I;

                                    n--;

}

}

根据c数组记录a中元素出现的次数,在a数组中直接替换,不引入b数组。

posted on 2017-04-14 16:29  olive_gyr  阅读(480)  评论(0编辑  收藏  举报