...
Run Format

Source file src/container/heap/heap_test.go

Documentation: container/heap

  // Copyright 2009 The Go Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style
  // license that can be found in the LICENSE file.
  
  package heap
  
  import (
  	"math/rand"
  	"testing"
  )
  
  type myHeap []int
  
  func (h *myHeap) Less(i, j int) bool {
  	return (*h)[i] < (*h)[j]
  }
  
  func (h *myHeap) Swap(i, j int) {
  	(*h)[i], (*h)[j] = (*h)[j], (*h)[i]
  }
  
  func (h *myHeap) Len() int {
  	return len(*h)
  }
  
  func (h *myHeap) Pop() (v interface{}) {
  	*h, v = (*h)[:h.Len()-1], (*h)[h.Len()-1]
  	return
  }
  
  func (h *myHeap) Push(v interface{}) {
  	*h = append(*h, v.(int))
  }
  
  func (h myHeap) verify(t *testing.T, i int) {
  	n := h.Len()
  	j1 := 2*i + 1
  	j2 := 2*i + 2
  	if j1 < n {
  		if h.Less(j1, i) {
  			t.Errorf("heap invariant invalidated [%d] = %d > [%d] = %d", i, h[i], j1, h[j1])
  			return
  		}
  		h.verify(t, j1)
  	}
  	if j2 < n {
  		if h.Less(j2, i) {
  			t.Errorf("heap invariant invalidated [%d] = %d > [%d] = %d", i, h[i], j1, h[j2])
  			return
  		}
  		h.verify(t, j2)
  	}
  }
  
  func TestInit0(t *testing.T) {
  	h := new(myHeap)
  	for i := 20; i > 0; i-- {
  		h.Push(0) // all elements are the same
  	}
  	Init(h)
  	h.verify(t, 0)
  
  	for i := 1; h.Len() > 0; i++ {
  		x := Pop(h).(int)
  		h.verify(t, 0)
  		if x != 0 {
  			t.Errorf("%d.th pop got %d; want %d", i, x, 0)
  		}
  	}
  }
  
  func TestInit1(t *testing.T) {
  	h := new(myHeap)
  	for i := 20; i > 0; i-- {
  		h.Push(i) // all elements are different
  	}
  	Init(h)
  	h.verify(t, 0)
  
  	for i := 1; h.Len() > 0; i++ {
  		x := Pop(h).(int)
  		h.verify(t, 0)
  		if x != i {
  			t.Errorf("%d.th pop got %d; want %d", i, x, i)
  		}
  	}
  }
  
  func Test(t *testing.T) {
  	h := new(myHeap)
  	h.verify(t, 0)
  
  	for i := 20; i > 10; i-- {
  		h.Push(i)
  	}
  	Init(h)
  	h.verify(t, 0)
  
  	for i := 10; i > 0; i-- {
  		Push(h, i)
  		h.verify(t, 0)
  	}
  
  	for i := 1; h.Len() > 0; i++ {
  		x := Pop(h).(int)
  		if i < 20 {
  			Push(h, 20+i)
  		}
  		h.verify(t, 0)
  		if x != i {
  			t.Errorf("%d.th pop got %d; want %d", i, x, i)
  		}
  	}
  }
  
  func TestRemove0(t *testing.T) {
  	h := new(myHeap)
  	for i := 0; i < 10; i++ {
  		h.Push(i)
  	}
  	h.verify(t, 0)
  
  	for h.Len() > 0 {
  		i := h.Len() - 1
  		x := Remove(h, i).(int)
  		if x != i {
  			t.Errorf("Remove(%d) got %d; want %d", i, x, i)
  		}
  		h.verify(t, 0)
  	}
  }
  
  func TestRemove1(t *testing.T) {
  	h := new(myHeap)
  	for i := 0; i < 10; i++ {
  		h.Push(i)
  	}
  	h.verify(t, 0)
  
  	for i := 0; h.Len() > 0; i++ {
  		x := Remove(h, 0).(int)
  		if x != i {
  			t.Errorf("Remove(0) got %d; want %d", x, i)
  		}
  		h.verify(t, 0)
  	}
  }
  
  func TestRemove2(t *testing.T) {
  	N := 10
  
  	h := new(myHeap)
  	for i := 0; i < N; i++ {
  		h.Push(i)
  	}
  	h.verify(t, 0)
  
  	m := make(map[int]bool)
  	for h.Len() > 0 {
  		m[Remove(h, (h.Len()-1)/2).(int)] = true
  		h.verify(t, 0)
  	}
  
  	if len(m) != N {
  		t.Errorf("len(m) = %d; want %d", len(m), N)
  	}
  	for i := 0; i < len(m); i++ {
  		if !m[i] {
  			t.Errorf("m[%d] doesn't exist", i)
  		}
  	}
  }
  
  func BenchmarkDup(b *testing.B) {
  	const n = 10000
  	h := make(myHeap, 0, n)
  	for i := 0; i < b.N; i++ {
  		for j := 0; j < n; j++ {
  			Push(&h, 0) // all elements are the same
  		}
  		for h.Len() > 0 {
  			Pop(&h)
  		}
  	}
  }
  
  func TestFix(t *testing.T) {
  	h := new(myHeap)
  	h.verify(t, 0)
  
  	for i := 200; i > 0; i -= 10 {
  		Push(h, i)
  	}
  	h.verify(t, 0)
  
  	if (*h)[0] != 10 {
  		t.Fatalf("Expected head to be 10, was %d", (*h)[0])
  	}
  	(*h)[0] = 210
  	Fix(h, 0)
  	h.verify(t, 0)
  
  	for i := 100; i > 0; i-- {
  		elem := rand.Intn(h.Len())
  		if i&1 == 0 {
  			(*h)[elem] *= 2
  		} else {
  			(*h)[elem] /= 2
  		}
  		Fix(h, elem)
  		h.verify(t, 0)
  	}
  }
  

View as plain text