patterngoMinor
Bottom up mergesort - singly linked list
Viewed 0 times
mergesortbottomsinglylistlinked
Problem
I have written the following program in Go to mergesort a singly linked list. It does bottom up merge sort and hence does not have to find the mid of the linked list. Please review the algorithm and the code for idiomatic Go.
```
package main
import (
"fmt"
)
type node struct {
val int
next *node
}
type list struct {
head *node
}
func newList(arr []int) *list {
if arr == nil || len(arr) == 0 {
return nil
}
l := new(list)
l.head = getNode(arr[0])
prev := l.head
for i := 1; i < len(arr); i++ {
n := getNode(arr[i])
prev.next = n
prev = n
}
return l
}
func printList(n *node) {
for p := n; p != nil; p = p.next {
fmt.Printf("%d ", p.val)
}
}
func getNode(v int) *node {
n := new(node)
n.val = v
return n
}
func skip(n node, len int) (fast node, slow *node) {
counter := 0
fast = n
slow = n
for counter < len {
if fast != nil && fast.next != nil {
fast = fast.next.next
} else if fast != nil {
fast = fast.next
}
if slow != nil {
slow = slow.next
}
counter++
}
return fast, slow
}
func (l *list) mergesort() {
// start with sublength of 1
// compare 0,with 1, 2 with 3
// skip n.next.next for next bunch
sublen := 1
len := 0
counted := false
for !counted || sublen < len {
for n := l.head; n != nil; {
fast, slow := skip(n, sublen)
merge(n, slow, sublen)
if !counted {
len += 2
}
n = fast
}
counted = true
sublen += sublen
}
}
func merge(p node, q node, len int) {
i := p
if q == nil {
// nothing to merge, return
return
}
j := q
ilen := 0
jlen := 0
var head *node
var prev *node
var end *node
var penult *node
for (i != q && ilen < len) && (j != nil
```
package main
import (
"fmt"
)
type node struct {
val int
next *node
}
type list struct {
head *node
}
func newList(arr []int) *list {
if arr == nil || len(arr) == 0 {
return nil
}
l := new(list)
l.head = getNode(arr[0])
prev := l.head
for i := 1; i < len(arr); i++ {
n := getNode(arr[i])
prev.next = n
prev = n
}
return l
}
func printList(n *node) {
for p := n; p != nil; p = p.next {
fmt.Printf("%d ", p.val)
}
}
func getNode(v int) *node {
n := new(node)
n.val = v
return n
}
func skip(n node, len int) (fast node, slow *node) {
counter := 0
fast = n
slow = n
for counter < len {
if fast != nil && fast.next != nil {
fast = fast.next.next
} else if fast != nil {
fast = fast.next
}
if slow != nil {
slow = slow.next
}
counter++
}
return fast, slow
}
func (l *list) mergesort() {
// start with sublength of 1
// compare 0,with 1, 2 with 3
// skip n.next.next for next bunch
sublen := 1
len := 0
counted := false
for !counted || sublen < len {
for n := l.head; n != nil; {
fast, slow := skip(n, sublen)
merge(n, slow, sublen)
if !counted {
len += 2
}
n = fast
}
counted = true
sublen += sublen
}
}
func merge(p node, q node, len int) {
i := p
if q == nil {
// nothing to merge, return
return
}
j := q
ilen := 0
jlen := 0
var head *node
var prev *node
var end *node
var penult *node
for (i != q && ilen < len) && (j != nil
Solution
Just some random notes:
This is usually spelled
Again, can be shortened to
Shorten to
This is a very bad name for a function because it clashes with a built-in. Better change to something like
l := new(list)
l.head = getNode(arr[0])This is usually spelled
l := &list{head: getNode(arr[0])}.n := new(node)
n.val = vAgain, can be shortened to
n := &node{val: v}.var head *node
var prev *node
var end *node
var penult *nodeShorten to
var head, prev, end, penult *node.func appendThis is a very bad name for a function because it clashes with a built-in. Better change to something like
appendList or make it a method.Code Snippets
l := new(list)
l.head = getNode(arr[0])n := new(node)
n.val = vvar head *node
var prev *node
var end *node
var penult *nodefunc appendContext
StackExchange Code Review Q#100519, answer score: 2
Revisions (0)
No revisions yet.