【问题标题】:How do I count the number of swaps (inversions) and comparisons in my merge sort code for my Linked List?如何计算链接列表的合并排序代码中的交换(反转)和比较次数?
【发布时间】:2022-01-09 06:46:40
【问题描述】:

这是我的合并排序的代码: 这是合并函数

node* Merge(node* h1, node* h2, int &comp, int &swaps){ node *t1 = new node; node *t2 = new node; node *temp = new node;


// Return if the first list is empty.
if(h1 == NULL)
    return h2;

// Return if the Second list is empty.
if(h2 == NULL)
    return h1;

t1 = h1;

// A loop to traverse the second list, to merge the nodes to h1 in sorted way.
while (h2 != NULL)
{
    // Taking head node of second list as t2.
    t2 = h2;

    // Shifting second list head to the next.
    h2 = h2->next;
    t2->next = NULL;

    // If the data value is lesser than the head of first list add that node at the beginning.
comp++;
    if(h1->data > t2->data)
    {
        t2->next = h1;
        h1 = t2;
        t1 = h1;
        continue;
    }

    // Traverse the first list.
    flag:
    if(t1->next == NULL)
    {
        t1->next = t2;
        t1 = t1->next;
    }
    // Traverse first list until t2->data more than node's data.
    else if((t1->next)->data <= t2->data)
    {
        t1 = t1->next;
        goto flag;
    }
    else
    {
        // Insert the node as t2->data is lesser than the next node.
        temp = t1->next;
        t1->next = t2;
        t2->next = temp;
  
    }
}

// Return the head of new sorted list.
return h1;

}

这是调用合并函数的合并排序函数。我不知道是否应该将比较和交换计数器放在合并或合并排序中,也不知道将它们放在函数中的哪个位置。

void MergeSort(node **head, int &comp, int &swaps)

{

node *first = new node;
node *second = new node;
node *temp = new node;
first = *head;
temp = *head;




// Return if list have less than two nodes.
if(first == NULL || first->next == NULL)
{
    return;
}
else
{
    // Break the list into two half as first and second as head of list.
    while(first->next != NULL)
    {
        first = first->next;
        if(first->next != NULL)
        {
            temp = temp->next;
            first = first->next;
        }
    }
    second = temp->next;
    temp->next = NULL;
    first = *head;
}

// Implementing divide and conquer approach.
MergeSort(&first, comp, swaps);
MergeSort(&second, comp, swaps);

// Merge the two part of the list into a sorted one.      
*head = Merge(first, second, comp, swaps);

}

我不确定在哪里放置我的交换和比较计数器来计算合并排序进行的交换和比较的数量?

【问题讨论】:

  • 我的意思是,在你交换或比较之后,对吧?
  • 好吧,mergesort 并没有真正做交换,所以...

标签: c++ mergesort


【解决方案1】:

对于比较,您可以为每次比较增加一个计数器。

在冒泡排序的情况下,交换次数与反转次数相同,但归并排序不进行交换,所以需要的是反转次数。

Inversions 是数组中数组 [i] > 数组 [j] 且 i

int InversionCount(int array[], int n)
{
    int count = 0;
    for (int i = 0; i < n - 1; i++)
        for (int j = i + 1; j < n; j++)
            if (array[i] > array[j])
                count++;
    return count;
}

一个典型的合并步骤合并两个已经排序的子数组,array[low to mid-1],array[mid to end-1]。令 i = 左数组的索引(低到中 1)和 j = 右数组的索引(中到尾 1)。如果在合并过程中遇到 array[i] > array[j] 的情况,那么 array[i 到 mid-1] 都将大于 array[j]。看看您是否可以使用它来确定和求和合并排序的合并步骤部分中的反转次数。

要根据问题中的代码对链表执行此操作,请进行以下更改以跟踪每个子列表中的节点数:

node * MergeSortR(node *head, int count, int &comp, int &swaps);

node *MergeSort(node *head, int &comp, int &swaps)
{
    node * ptr = head;
    int count = 0;
    comp = 0;
    swaps = 0;
    while(ptr != NULL){
        count++;
        ptr = ptr->next;
    }
    if(count < 2)
        return head;
    return MergeSortR(head, count, comp, swaps);
}

node * MergeSortR(node *first, int count, int &comp, int &swaps)
{
    if(count < 2)
        return first;
    node * second = first;
    int fstcnt = count/2;
    int sndcnt = count - fstcnt;
    for(int i = 1; i < fstcnt; i++)
        second = second->next;
    node *temp = second;
    second = second->next;
    temp->next = NULL;
    first = MergeSortR(first,  fstcnt, comp, swaps);
    second = MergeSortR(second, sndcnt, comp, swaps);
    return Merge(first, fstcnt, second, sndcnt, comp, swaps);
}

n 个元素的最坏情况(反向排序的元素)反转计数是 n(n-1)/2。如果使用带符号的 32 位整数作为反转计数,则最大列表大小限制为 65536,以避免任何溢出的机会。

【讨论】:

  • 好吧,我只需要交换,不一定是反转。但是我将如何通过将它设置为带有节点的链表来实现它?
  • @SomethingYou - 对于冒泡排序,交换次数与反转次数相同,但合并排序不进行交换,因此您需要的是反转次数。
  • @SomethingYou - 我更新了我的答案以显示如何根据您的代码完成此操作。看看你是否能弄清楚如何做合并部分。
  • 我应该在哪里增加 comp 和 swaps 变量?
  • 不客气,谢谢
猜你喜欢
  • 1970-01-01
  • 2015-07-09
  • 1970-01-01
  • 2018-05-30
  • 2013-03-10
  • 1970-01-01
  • 2015-05-21
  • 2016-10-02
  • 1970-01-01
相关资源
最近更新 更多