1005-邓俊辉数据结构学习笔记 5-队列

队列的学习

队列的模拟

使用数组对循环队列进行模拟的时候,必须放弃一个位置。

关于模板类继承之后派生类使用基类接口,需要使用基类的作用域限定。

队列的底层,如果不考虑空间的话,使用vector比较好,否则使用双向链表,主要delete太耗时间。

队列的应用

RoundRobin轮盘机制

RoundRobin

对某项资源进行轮流分配

void RoundRobin()
{
    Queue<int> que;
    while(!serve.close())
    {
        e = que.dequeue();
        serve(e);
        que.enqueue(e);
    }
}

归并排序

其实在做二路归并的时候,我们就使用了队列的思想。在做B和C比较的时候,每次使用的都是头部进行比较。
其中就暗含队列的思想。这次我们直接使用队列的接口,可以更加清晰明了的看出归并排序的思想

void merge(int *arr, int low, int mid, int high)
{
    queue<int> b;
    queue<int> c;
    queue<int> a;
    for(int i = low; i < mid; ++i)
    {
        b.push(arr[i]);
    }
    for(int i = mid; i < high; ++i)
    {
        c.push(arr[i]);
    }
    size_t len = high - low;
    while(a.size() != len)
    {
        if(b.size() && (c.empty() || b.front() <= c.front()))
        {
            a.push(b.front());
            b.pop();
        }
        if(c.size() && (b.empty() || c.front() < b.front()))
        {
            a.push(c.front());
            c.pop();
        }
    }
    for(int i = low; i < high; ++i)
    {
        arr[i] = a.front();
        a.pop();
    }
}

void mergeSort(int * arr, int low, int high)
{
    if(high - low < 2) 
        return ;
    int mid = (low + high) >> 1;
    mergeSort(arr, low, mid);
    mergeSort(arr, mid, high);
    merge(arr, low, mid, high);
}


int main()
{
    const int maxI = 10;
    int arr[maxI] ;
    srand(time(NULL));
    for(int i = 0; i < maxI; ++i)
    {
        arr[i] = rand() % 100;
    }
    for(int i = 0; i < maxI; ++i)
    {
        printf("%3d", arr[i]);
    }
    printf("\n");
    mergeSort(arr, 0, maxI);
    for(int i = 0; i < maxI; ++i)
    {
        printf("%3d", arr[i]);
    }
    printf("\n");
    return 0;
}

唯一要注意的是这里递归基的问题。我们让其在high = low + 1的时候结束递归,因此
mergeSort进行到队列中只有一个元素的时候回去merge。

利用归并排序框架写出求逆序对的方法

在lighthouse中遇到求逆序对的方法,当时使用了暴力求解的方法,结果很明显,超时了。所以刻意学习了新的方法。

void inv(int *arr, int low, int high, int&cnt)
{
    if(high - low < 2)
        return;
    int mid = (high + low) >> 1;
    inv(arr, low, mid, cnt);
    inv(arr, mid, high, cnt);
    cnt += countInv(arr, low, mid, high);
}
void merge(int *arr, int low, int mid, int high)
{
    int i, j, k;
    int lenB = mid - low;
    int lenC = high - mid;
    int * A = arr + low;
    int * B = new int[lenB];
    int * C = arr + mid;
    for(int i = 0; i < lenB; ++i)
        B[i] = A[i];
    for(i=j=k = 0; j < lenB || k < lenC;)
    {
        if(j<lenB && (lenC <= k || B[j] <= C[k]))
            A[i++] = B[j++];
        if(k<lenC && (lenB <= j || C[k] < B[j]))
            A[i++] = C[k++];
    }
}// 上面大致为归并排序基本框架
int countInv(int *arr, int low, int mid, int high)
{
    int i, j, k;
    int cnt = 0;
    int lenB = mid - low;
    int lenC = high - mid;
    int * A = arr + low;
    int * B = new int[lenB];
    int * C = arr + mid;
    for(int i = 0; i < lenB; ++i)
        B[i] = A[i];
    for(i=j=k = 0; j < lenB || k < lenC;)
    {
        if(j<lenB && (lenC <= k || B[j] < C[k]))
        {
            A[i++] = B[j++];
            // 计算顺序对
            if(k < lenC)
                cnt += lenC - k; //如果 k大于B[j],那么k以及后面所有元素则都大于
                //计算顺序对就是从j依次走。注意如果k>=lenC后,此后都为0,没有必要进行计算
        }
        if(k<lenC && (lenB <= j || C[k] <= B[j]))
            A[i++] = C[k++];
            
    }
}// 我们需要的求逆序,需要做一些改动

经过一些小的优化,然后计算逆序对
int countInv(int *arr, int low, int mid, int high)
{
    int i, j, k;
    int cnt = 0;
    int lenB = mid - low;
    int lenC = high - mid;
    int * A = arr + low;
    int * B = new int[lenB];
    int * C = arr + mid;
    for(int i = 0; i < lenB; ++i)
        B[i] = A[i];
    for(i=j=k = 0; j < lenB;)
    {
        if((lenC <= k || B[j] <= C[k]))
            A[i++] = B[j++];
        if(k<lenC && C[k] < B[j]){
            A[i++] = C[k++];
            //如果B[j] > C[k] , 则j以及j以后均大于
            if(j < lenB) // 这个条件已经不需要了
                cnt += lenB - j
            //当B先排完,则之后的C的所有数字均大于B中任何数字,不构成任何逆序对
        }
    }
}// 我们需要的求逆序,需要做一些改动

解释:我们知道首先在归并排序中,俩个数组都是已经有序的情况下进行排序。而路数组本身的顺序对,或者逆序对是不需要计算的。因为在排序这路数组前已经计算过了。只需要计算当前俩个数组间的顺序对逆序对就可以了。

猜你喜欢

转载自blog.csdn.net/weixin_43468441/article/details/83188513
今日推荐