2

So having not waited for an answer in this topic, I decided to implement my data structure.
The problem I encountered: when sorting small lists, everything is fine, but when sorting a list with a size of 487 items, a stack overflow occurs in the merge method.

Here are the parts of the code responsible for sorting.
Any ideas?

private function mergeSort($node) {
        if ($node == null || $node->next == null) {
            return $node;
        }

        $second = $this->split($node);

        $node = $this->mergeSort($node);
        $second = $this->mergeSort($second);

        return $this->merge($node, $second);
    }

private function split(Word $word) {
        $fast = $word;
        $slow = $word;
        while ($fast->next !== null && $fast->next->next !== null) {
            $fast = $fast->next->next;
            $slow = $slow->next;
        }
        $temp = $slow->next;
        $slow->next = null;
        return $temp;
    }

private  function merge($first, $second) {
        if ($first === null) {
            return $second;
        }

        if ($second === null) {
            return $first;
        }

        if ($first->begin < $second->begin) {
            $first->next = $this->merge($first->next, $second);
            $first->next->prev = $first;
            $first->prev = null;
            return $first;
        } else {
            $second->next = $this->merge($first, $second->next);
            $second->next->prev = $second;
            $second->prev = null;
            return $second;
        }
    }

Usage:

//some code here 

$sortedLinedList = $linkedList->mergeSort($linkedList->head);
// stack overflow happens

Update: I found out that the stack overflow does not always directly depend on the number of items in the list. Sometimes the stack can overflow with 350 elements, and sometimes with 487. Perhaps it depends on the data of the list itself. The only place where I use the node data directly is the comparison in the merge method. Maybe it happens because the variable "begin" contains the value of float type? I tried this:

round($first->begin, 2) < round($second->begin, 2)

but It didn't help me :(

Roman Andreev
  • 444
  • 3
  • 6
  • 18
  • `$node = $this->mergeSort($node);` calls the function recursively without change. – B.Letz Jun 04 '19 at 12:16
  • StackOverflow would occur to me too in that instance. – Peter Jun 04 '19 at 12:18
  • @B.Letz Hmm, but in this case, I am really not changing the node, I should change to one of the following nodes the `next` pointer to `null`. Isn't it? – Roman Andreev Jun 04 '19 at 12:21
  • If a function calls itself without changing any of the parameters, it will lead to an infinite loop of calling itself. Hence a Stack Overflow occurs – B.Letz Jun 04 '19 at 12:31
  • @B.Letz In fact, the parameters change because the node in the middle of the list changes its `next` pointer to `null`, thereby reducing the list by half. I mean the `split` function that I call before `$node = $this->mergeSort($node);` And I also want to note that on small data sets of 200-300 elements everything works fine – Roman Andreev Jun 04 '19 at 12:34
  • A recursive merge is going to cause stack overflow for a large list. An iterative (looping) merge function should be used instead. – rcgldr Jun 04 '19 at 13:44
  • @rcgldr I found out the stack is overflowing with 487 items in the list. I think it's a really normal case when stack overflowing with 2^256 items in the list, but 487 items seem too little – Roman Andreev Jun 04 '19 at 14:07
  • I don't know php, so I wouldn't know about it's stack limitations. I would still recommend changing the merge function from recursive to iterative. – rcgldr Jun 05 '19 at 07:13
  • @rcgldr Most of the algorithms that I saw on Google, YouTube and SO are a recursive merge. My stack overflows with less than 500 items. Why in examples on phyton, c ++, java, the same code works fine, but in PHP  it doesn’t work correctly? Maybe all the same error somewhere in my code? – Roman Andreev Jun 05 '19 at 07:21
  • Take a look at the merge function used in the 2 way bottom up merge sort, which is the second code example in [this answer](https://stackoverflow.com/questions/34844613/34845789#34845789) . The last example is a 4 way bottom up merge sort, not as common. Most libraries use some variation of bottom up merge sort for a stable sort, such as a hybrid insertion / merge sort. – rcgldr Jun 05 '19 at 14:29

0 Answers0