算法导论部分代码实现1

第一次上机

第一题

分治策略

//输入数组S,目标值x,找出是否存在两数之和等于x


#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
//归并排序,时间复杂度 n l o g n
void merge(vector<int> &T,int p,int q,int r)
{
    // int n1=q-p+1;
    // int n2=r-q; 
    //左闭右开区间,故需+1,右端
    vector<int> L(T.begin()+p,T.begin()+q+1);//p~q
    vector<int> R(T.begin()+q+1,T.begin()+r+1);//q+1~r
    //initialize L,R
    L.insert(L.end(), numeric_limits<int>::max());
    R.insert(R.end(), numeric_limits<int>::max());
    int i=0,j=0;
    int left=L.size(),right=R.size();
    //n
    for(int k=p;k<=r;k++)
    {
        if(L[i]<=R[j]&&i<left)
        {
            T[k]=L[i];
            i+=1;
        }
        else if(j<right){
            T[k]=R[j];
            j+=1;
        }
    }
}
//采用了分治策略思想,分解部分时间复杂度为lgn
void merge_sort(vector<int> &T,int p,int r)
{
    int q;
     if(p<r)
    {
        q=(p+r)/2;
        merge_sort(T,p,q);
        merge_sort(T,q+1,r);
        merge(T,p,q,r);
    }

}
//二分查找,lgn
bool Binary_search(vector<int> &T,int target,int p,int q)
{
    while(p<q)
    {
        //左闭右开区间
        int mid=p+(q-p)/2;
        if(T[mid]==target) return 1;
        else if(T[mid]>target)
        {
            q=mid;
        }
        else{
            p=mid+1;
        }
    }
    return 0;
}
void print(vector<int> &T)
{
    for(int i=0;i<T.size();i++)
    {
        cout<<T[i]<<" ";
    }
}
int main()
{
    //int a;
    vector<int> S={14,48,64,42,8,1,9,13,7,88};
    //int x=15;
    int x=99;
    /* vector<int> S;
    int x;
    cout<<"请输入目标x:"<<endl;
    cin>>x;
    //创建数组,初始化
    cout<<"请输入数组S(以q结束数组输入):"<<endl;
    //输入
    while(cin>>a) 
    {
        S.push_back(a);
    } */
    //input finish symbol
    //定义常量,将vector数组赋值给定长数组,时间复杂度n
    int length=S.size(); 
    // cout<<length<<endl;
    //n l o g n
    merge_sort(S,0,length-1);
    //n l o g n
    for(int i=0;i<length;i++)
    {
        int b=Binary_search(S,x-S[i],i+1,length-1);
        if(b)
        {
         
            cout<<"数组S中存在两个元素之和为x"<<endl;
            return 0;
        }
    }
    cout<<"数组S中不存在两数之和等于x"<<endl;
    return 0;
}


第二题

堆排序,优先队列

// maximums(S):return the maximal element
// extract(S):extract the maximal element
// increase key(S,x,k):increase the value of an value
// insert(S,x):insert a new element
//优先队列,堆排序实现
#include<iostream>
using namespace std;
int length;
int heap_size;
// int A[100];
const int INF8 = 0xc0c0c0c0; //无穷小
// #define max_size 100;
void print(int a[])
{
    for(int i=1;i<=heap_size;i++)
    {
        cout<<a[i]<<" ";
    }
    cout<<endl;
}
//堆维护
void max_heapify(int a[],int i)
{
    int l=2*i;
    int r=2*i+1;
    int largest,temp;
    if(l<=heap_size&&a[l]>a[i])
    {
        largest=l;
    }
    else largest=i;
    if(r<=heap_size&&a[r]>a[largest])
    {
        largest=r;
    }
    if(largest!=i)
    {
        temp=a[i];
        a[i]=a[largest];
        a[largest]=temp;
        max_heapify(a,largest);
    }
}

//build max-heap
void build_max_heap(int a[])
{
    // int heap_size;
    heap_size=length;
    int i;
    for(i=length/2;i>=1;i--)
    {
        max_heapify(a,i);
    }
}

//堆排序,nl o g n
void heapsort(int a[])
{
    int temp;
    build_max_heap(a);
    for(int i=length;i>=2;i--)
    {
        temp=a[1];
        a[1]=a[heap_size];
        a[heap_size]=temp;
        heap_size=heap_size-1;
        max_heapify(a,1);
    }
    heap_size=length;
}
//优先队列
// maximums(S):return the maximal element/   n
int heap_maxnum(int a[])
{
    return a[1];
}
//extract(S):extract the maximal element:返回最大值,并删除这个元素
int heap_extract_max(int a[])
{
    if(heap_size<1)
    {
        cout<<"heap error"<<endl;
        return 0;
    }
    int max=a[1];
    a[1]=a[heap_size];
    heap_size-=1;
    length-=1;
    max_heapify(a,1);
    return max;
}
// increase key(S,x,k):increase the value of an value 增加第i个数的值,向上堆回溯//lgn
void heap_increase_key(int a[],int i,int key)
{
    if(key<a[i])
    {
        cout<<"new key is smaller than current key"<<endl;
    }
    else
    {
        a[i]=key;
        int temp;
        while(i>1&&a[i/2]<a[i])
        {
            //swap(a[i/2],a[i]);
            temp=a[i/2];
            a[i/2]=a[i];
            a[i]=temp;
            i=i/2;
        }
    }
}
//insert(S,x):insert a new element:增加一个元素 lgn
void max_heap_insert(int a[],int key)
{
    heap_size+=1;
    a[heap_size]=INF8;
    heap_increase_key(a,heap_size,key);
    length+=1;
}

int main()
{
    //输入数组的长度
    /* cout<<"please input length of array:"<<endl;
    cin>>length;
    //初始化数组
    int A[100];
    cout<<"please input the array:"<<endl;
    for(int i=1;i<=length;i++)
    {
        cin>>A[i];
    } */
    int A[10]={1,9,15,18,13,52,64,35,71,48};
    length=9;
    //heapsort
    heapsort(A);
    print(A);
    //返回最大值
    int tag;
    build_max_heap(A);
    tag=heap_maxnum(A);
    cout<<tag<<endl;
    print(A);
    //提取最大值:返回最大值并删除
    int max_number;
    build_max_heap(A);
    max_number=heap_extract_max(A);
    cout<<max_number<<endl;
    print(A);
    //增大第i个元素的值为key
    build_max_heap(A);
    int key,n;
    cout<<"请输入所需增大值的位置n与要增大到的值key;"<<endl;
    cin>>n;
    cin>>key;
    heap_increase_key(A,n,key);
    print(A);
    //在大顶堆中插入一个元素
    int insert_number;
    cout<<"请输入要插入的值:"<<endl;
    cin>>insert_number;
    build_max_heap(A);
    max_heap_insert(A,insert_number);
    //结束
    print(A);
    return 0;
}

第三题

快排,普通&随机

// 3.Implement Quicksort and 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.
//1)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<stdlib.h>
#include<time.h>
using namespace std;
//common qk_sort  最坏情况n^2,最好情况nl o g n;   
int partition(int a[],int p,int r)
{
    int x=a[r];
    int i=p-1;
    for(int j=p;j<r;j++)
    {
        if(a[j]<=x)
        {
            i+=1;
            swap(a[i],a[j]);
        }
    }
    swap(a[i+1],a[r]);
    return i+1;
}
void qk_sort(int a[],int p,int r)
{
    int q;
    if(p<r)
    {
        q=partition(a,p,r);
        qk_sort(a,p,q-1);
        qk_sort(a,q+1,r);
    }
}

//random qk_sort// n l o g n避免了最坏情况
int random_partition(int a[],int p,int r)
{
    int i=p+rand()%(r-p+1);
    swap(a[i],a[r]);
    int n;
    n=partition(a,p,r);
    return n;
}

void random_qk_sort(int a[],int p,int r)
{
    int q;
    if(p<r)
    {
        q=random_partition(a,p,r);
        random_qk_sort(a,p,q-1);
        random_qk_sort(a,q+1,r);
    }
}

//输出数组
void print(int a[])
{
    for(int i=0;i<10;i++)
    {
        cout<<a[i]<<" ";
    }
    cout<<endl;
}
//main函数
int main()
{
    //int a[10]={1,3,8,4,12,48,5,64,34,98};
    int a[10]={10,9,8,7,6,5,4,3,2,1};
    print(a);
    // qk_sort(a,0,9);
    random_qk_sort(a,0,9);
    print(a);
    return 0;
}

第四题

分治

/* 4.	Give a divide and conquer algorithm for the following problem: 
you are given two sorted lists of size m and n, 
and are allowed unit time access to the ith element of each list. 
Give an O(lg m + lgn) time algorithm for computing the kth largest element in the union of the two lists. 
(For simplicity, you can assume that the elements of the two lists are distinct). */
#include<iostream>
#include<vector>
#include<cstdio>
using namespace std;
int m[8]={1,5,7,9,12,15,16,17};
int n[10]={2,3,8,13,18,19,43,51,67,69};
// 时间复杂度为lgm+lgn
int find_kth_number(int ml,int mr,int nl,int nr,int k)
{
    int m_mid=(ml+mr)/2;
    int n_mid=(nl+nr)/2;
    if(ml>mr) return n[nl+k-1];
    if(nl>nr) return m[ml+k-1];
    if(m[m_mid]>n[n_mid])
    {
        if(k<=m_mid-ml+n_mid-nl+1)
        {
            return find_kth_number(ml,m_mid-1,nl,nr,k);
        }
        else
        {
            return find_kth_number(ml,mr,n_mid+1,nr,k-n_mid+nl-1);
        }
    }
    else
    {
        if(k<=n_mid-nl+m_mid-ml+1)
        {
            return find_kth_number(ml,mr,nl,n_mid-1,k);
        }
        else
        {
            return find_kth_number(m_mid+1,mr,nl,nr,k-m_mid+ml-1);
        }
    }
}
int main()
{
   /*  int m[8]={1,5,7,9,12,15,16,17};
    int n[10]={2,3,8,13,18,19,43,51,67,69}; */
    int m_length=sizeof(m)/sizeof(m[0]);
    //int m_length=end(m)-begin(m);
    //int n_length=end(n)-begin(n);
    int n_length=sizeof(n)/sizeof(n[0]);
    int k,kth_number;
    cout<<"请输入K值:"<<endl;
    cin>>k;
    kth_number=find_kth_number(0,m_length-1,0,n_length-1,k);
    cout<<kth_number<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值