算法设计技巧与分析-学习笔记


Chapter 1-----Basic Concepts in Algorithmic Analysis


1)Binary Search

  • Problem Description
    Let A[1…n] be a sequence of n elements. Consider the problem of determining whether a given element x is in A.
  • Input
  1. An array A[1…n] of n elements sorted in nondecreasing order;
  2. x;
  • Output
    j if x=A[j], and 0 otherwise;
  • Pseudo code
    1. low←1; high←n; j←0;
    2. while (low<=high) and (j=0)
    3.     mid←⌊low+high)/2;
    4.     if x=A[mid] then j←mid;
    5.     else if x<A[mid] then high←mid–1;
    6.     else low←mid+1;
    7. end while;
    8. return j;
    
  • Complexity
    Max: ⌊log n⌋+1
    Min: 1
    Average: log n
  • C++ code
    #include <iostream>
    using namespace std;
    
    //二分查找,返回元素所在位置 
    int Binary_Search(int A[],int len,int x){
        int low = 0,high = len;
        while(low <= high){
            int mid = (low+high)/2;
            if(x == A[mid]){
                return (mid+1);
            }
            else if(x > A[mid]){
                low = mid+1; 
            }
            else{
                high = mid-1;
            }
        }
    }
    
    int main(){  
        int A[] = {1,4,5,7,8,9,10,12,15,22,23,27,32,35};
        cout<<Binary_Search(A,14,22)<<endl; 
        return 0;
    } 
    

2)Merging Two Sorted Lists

  • Problem Description
    Suppose we have an array A[1…m] and three indices p, q, and r, with 1 <= p <= q < r <= m,
    such that both the subarrays A[p…q] and A[q+1…r] are individually sorted in nondecreasing order.
    We want to rearrange the elements in A so that the elements in the subarray A[p…r] are sorted in nondecreasing order.
  • Input
  1. A[1…m];
  2. p, q, and r, and 1 <= p <= q < r <= m, such that both A[p…q] and A[q+1…r] are sorted individually in nondecreasing order;
  • Output
    A[p…r] contains the result of merging the two subarrays A[p…q] and A[q+1…r];
  • Pseudo code
    1. s←p; t←q+1; k←p;
    2. while s<=q and t<=r
    3.     if A[s]<=A[t] then 
    4.         B[k]←A[s];
    5.         s←s+1;
    6.     else 
    7.         B[k]←A[t];
    8.         t←t+1;
    9.     end if;
    10.   k←k+1;
    11. end while;
    12. if s=q+1 then B[k…r]←A[t…r]
    13. else B[k…r]←A[s…q]
    14. end if
    15. A[p…r]←B[p…r]
    
  • Number of Comparisons
    Max : n-1 (n=n1+n2)
    Min : n1
    Average : ⌊n/2⌋ ~ n-1
  • Number of Assignments
    2n
  • C++ code
    #include <iostream>
    using namespace std;
    
    //归并两个有序数组
    int *Merge_Lists(int *list_A,int A_len,int *list_B,int B_len,int *list_merged){
        int A_s = 0,B_t = 0;
        int k;
        for(k = 0;A_s<A_len && B_t<B_len;k++){
            if(list_A[A_s] <= list_B[B_t]){
                list_merged[k] = list_A[A_s];
                A_s++;
            }
            else{
                list_merged[k] = list_B[B_t];
                B_t++;
            } 
        }
        if(A_s == A_len)
            for(;B_t<B_len;B_t++,k++)
                list_merged[k] = list_B[B_t];
        else
            for(;A_s<A_len;A_s++,k++)
                list_merged[k] = list_A[A_s];
        return list_merged;
    }
    
    int main(){  	
        int A[5] = {1,4,6,8,9},B[8] = {2,5,7,12,45,46,49,61};
        int mergedList[13];
        Merge_Lists(A,5,B,8,mergedList);
        for(int i = 0;i<13;i++)
            cout<<*(mergedList+i)<<" ";
        return 0;
    } 
    

3)Selection Sort

  • Problem Description
    Let A[1…n] be an array of n elements.
    First, we find the minimum element and store it in A[1].
    Next, we find the minimum of the remaining n-1 elements and store it in A[2].
    We continue this way until the second largest element is stored in A[n-1].

  • Input
    A[1…n];

  • Output
    A[1…n] sorted in non-decreasing order;

  • Pseudo code

    3. for i←1 to n-1
    4.     k←i;
    5.     for j←i+1 to n
    6.         if A[j]<A[k] then k←j;
    7.     end for;
    8.     if k≠i then interchange A[i] and A[k];
    9. end for;
    
  • Number of Comparisons
    n ( n − 1 ) 2 \frac{n(n-1)}{2} 2n(n1)

  • Number of Assignments
    Max: 3(n-1)
    Min: 0

  • C++ code

    #include <iostream>
    using namespace std;
    
    void Selection_Sort(int *A,int A_len){
    	int min_pos;
    	for(int i = 0;i<A_len-1;i++){
    		min_pos = i;
    		for(int j = i+1;j<A_len;j++){
    			if(*(A+j)<*(A+min_pos)){
    				min_pos = j;
    			}
    		}
    
    		if(min_pos != i){
    			int temp = *(A+i);
    			*(A+i) = *(A+min_pos);
    			*(A+min_pos) = temp;
    		}
    	}
    }
    
    int main(){  
    	//Selection Sort
    	int A[10] = {3,9,7,569,58,642,3,5,8,65};
    	for(int i = 0;i<10;i++)
    		cout<<*(A+i)<<" ";
    	cout<<endl;
    
    	Selection_Sort(A,10);
    
    	for(int i = 0;i<10;i++)
    		cout<<*(A+i)<<" ";
    	cout<<endl;
    	return 0;
    } 
    

4)Insertion Sort

  • Problem Description
    We begin with the subarray of size 1, A[1], which is already sorted.
    Next, A[2] is inserted before or after A[1] depending on whether it is smaller than A[1] or not.
    Continuing this way, in the i th iteration, A[i] is inserted in its proper position in the sorted subarray A[1 … i-1].
    This is done by scanning the elements from index i-1 down to 1, each time comparing A[i] with the element at the current position.
    In each iteration of the scan, an element is shifted one position up to a higher index.
    This process of scanning, performing the comparison and shifting continues until an element less than or equal to A[i] is found, or when all the sorted sequence so far is exhausted.
    At this point, A[i] is inserted in its proper position, and the process of inserting element A[i] in its proper place is complete.
  • Input
    A[1…n];
  • Output
    A[1…n] sorted in non-decreasing order;
  • Pseudo code
    1. for i←2 to n
    2.     x←A[i];
    3.     j←i-1;
    4.     while (j>0) and (A[j]>x)
    5.         A[j+1]←A[j];
    6.         j←j-1;
    7.     end while;
    8.     A[j+1]←x;
    9. end for;
    
  • Number of Comparisons
    Max: n ( n − 1 ) 2 \frac{n(n-1)}{2} 2n(n1)
    Min: n-1
  • Number of Assignments
    Max: n ( n − 1 ) 2 + 2 ( n − 1 ) \frac{n(n-1)}{2}+2(n-1) 2n(n1)+2(n1)
    Min: (n-1)+(n-1)
    Others: Number of Comparisons+(n-1)
  • C++ code
    #include <iostream>
    using namespace std;
    
    //插入排序
    void Insertion_Sort(int *A,int A_len){
    	for(int i = 1;i<A_len;i++){
    		int x = A[i];
    		int j = i-1;
    		while(j>=0 && A[j]>x){
    			A[j+1] = A[j];
    			j--;
    		}
    		A[j+1] = x;
    	}
    }
    
    int main(){  
    	int A[10] = {3,9,7,569,58,642,3,5,8,65};
    	for(int i = 0;i<10;i++)
    		cout<<*(A+i)<<" ";
    	cout<<endl;
    	Insertion_Sort(A,10);
    	for(int i = 0;i<10;i++)
    		cout<<*(A+i)<<" ";
    	cout<<endl;
    	return 0;
    } 
    

5)Bottom-Up Merge Sorting

  • Question Description
    Let A be an array of n elements that is to be sorted.
    We first merge ⌊n/2⌋ consecutive pairs of elements to yield ⌊n/2⌋ sorted sequences of size 2.
    If there is one remaining element, then it is passed to the next iteration.
    Next, we merge ⌊n/4⌋ pairs of consecutive 2-element sequences to yield ⌊n/4⌋ sorted sequences of size 4.
    If there are one or two remaining elements, then they are passed to the next iteration.
    If there are three elements left, then two (sorted) elements are merged with one element to form a 3-element sorted sequence.
    Continuing this way, in the jth iteration, we merge ⌊n/2j⌋ pairs of sorted sequences of size 2j-1 to yield ⌊n/2j⌋ sorted sequences of size 2j.
    If there are k remaining elements, where 1<=k<=2j-1, then they are passed to the next iteration.
    If there are k remaining elements, where 2j-1<k<2j, then these are merged to form a sorted sequence of size k.
  • Input
    An array A[1…n] of n elements;
  • Output
    A[1…n] sorted in nondecreasing order;
  • Pseudo code
    1. t←1;
    2. while t<n
    3.     s←t; t←2s; i←0;
    4.     while i+t≤n
    5.         MERGE(A, i+1, i+s, i+t);
    6.         i←i+t;
    7.     end while;
    8.     if i+s<n then MERGE(A, i+1, i+s, n);
    9. end while;
    
  • Number of Comparisons
    Max: n logn - n + 1
    Min: (n log n)/2
  • Number of Assignments
    2n logn
  • C++ code
    #include <iostream>
    using namespace std;
    
    //归并排序
    void MERGE(int *A,int p,int q,int r){
    	p--;q--;r--;
    	int B[r-p+1];
    	int s = p;
    	int t = q+1;
    	int k = 0;
    	while(s<=q && t<= r){
    		if(A[s]<=A[t]){
    			B[k] = A[s];
    			s++;
    		}
    		else{
    			B[k] = A[t];
    			t++;
    		}
    		k++;
    	}
    
    	if(s == q+1){
    		for(;t<=r;t++,k++)
    			B[k] = A[t];
    	}
    	else{
    		for(;s<=q;s++,k++)
    			B[k] = A[s];
    	}
    
    	for(int i = 0;i<k && p<=r;i++,p++){
    		A[p] = B[i];
    	}
    }
    
    void Bottom_Up_Merge_Sort(int *A,int A_len){
    	int merge_size = 1,array_size,i;
    	while(merge_size<A_len){
    		array_size = merge_size;
    		merge_size = 2*array_size;
    		for(i = 0;i+merge_size<=A_len;i += merge_size){
    			MERGE(A,i+1,i+array_size,i+merge_size);
    		}
    
    		if(i+array_size < A_len)
    			MERGE(A,i+1,i+array_size,A_len);
    	}	
    }
    
    int main(){  
    	int A[10] = {3,9,7,569,58,642,3,5,8,65};
    	for(int i = 0;i<10;i++)
    		cout<<*(A+i)<<" ";
    	cout<<endl;
    	Bottom_Up_Merge_Sort(A,10);
    	for(int i = 0;i<10;i++)
    		cout<<*(A+i)<<" ";
    	cout<<endl; 
    	
    	return 0;
    } 
    
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值