package linkedlist
import (
"fmt"
)
type ListNode struct {
Data interface{}
Next *ListNode
}
type LinkedList struct {
head *ListNode
length uint
}
func NewListNode(v interface{}) *ListNode {
return &ListNode{v, nil}
}
func (this *ListNode) GetNext() *ListNode {
return this.Next
}
func (this *ListNode) GetValue() interface{} {
return this.Data
}
func NewLinkedList() *LinkedList {
return &LinkedList{NewListNode(0), 0}
}
//Insert new node after specific Node
func (this *LinkedList) InsertAfter(p *ListNode, v interface{}) bool {
if p == nil {
return false
}
newNode := NewListNode(v)
oldNextNode := p.Next
p.Next = newNode
newNode.Next = oldNextNode
this.length++
return true
}
//Insert new node before specific Node
func (this *LinkedList) InsertBefore(p *ListNode, v interface{}) bool {
if p == nil || p == this.head {
return false
}
cur := this.head.Next
pre := this.head
for nil != cur {
if cur == p {
break
}
pre = cur
cur = cur.Next
}
if cur == nil {
return false
}
newNode := NewListNode(v)
pre.Next = newNode
newNode.Next = cur
this.length++
return true
}
//Insert new node on list head
func (this *LinkedList) InsertToHead(v interface{}) bool {
return this.InsertAfter(this.head, v)
}
//Insert new node on list tail
func (this *LinkedList) InsertToTail(v interface{}) bool {
cur := this.head
for nil != cur.Next {
cur = cur.Next
}
return this.InsertAfter(cur, v)
}
//Find node by index
func (this *LinkedList) FindByIndex(index uint) *ListNode {
if index > this.length {
return nil
}
cur := this.head.Next
var i uint = 1
for ; i < index; i++ {
cur = cur.Next
}
return cur
}
//Delete node by specific node
func (this *LinkedList) DeleteNodeByNode(p *ListNode) bool {
if nil == p {
return false
}
cur := this.head.Next
pre := this.head
for cur != p {
if cur == nil {
return false
}
pre = cur
cur = cur.Next
}
pre.Next = cur.Next
this.length--
return true
}
//Delete node by index
func (this *LinkedList) DeleteNodeByIndex(v uint) bool {
if v > this.length {
return false
}
cur := this.head.Next
pre := this.head
var i uint = 1
for ; i < v; i++ {
pre = cur
cur = cur.Next
}
pre.Next = cur.Next
this.length--
return true
}
//https://www.cnblogs.com/TimLiuDream/p/9932494.html
func (this *LinkedList) ReverseList_V1() bool {
if this.length == 0 {
return false
}
cur := this.head.Next
var pre *ListNode
for cur != nil {
fmt.Println("-->1--", cur, cur.Next, pre)
pre, cur, cur.Next = cur, cur.Next, pre
fmt.Println("-->2--", pre, cur, cur.Next)
}
this.head.Next = pre
return true
}
func (this *LinkedList) ReverseList_V2() bool {
if this.length == 0 {
return false
}
firstNode := this.head.Next //save first node and finally set next is nil
//reverse from second node
pre := firstNode //上一个结点的指针
cur := firstNode.Next
var next *ListNode
for cur != nil {
next = cur.Next
cur.Next = pre
pre = cur
cur = next
}
this.head.Next = pre
firstNode.Next = nil
return true
}
func (this *LinkedList) Print() {
cur := this.head.Next
format := ""
for nil != cur {
format += fmt.Sprintf("%+v", cur)
cur = cur.Next
if cur != nil {
format += "->"
}
}
fmt.Println("LinkedList lenth:", this.length, "\n", format)
}
package linkedlist
import (
"fmt"
"testing"
)
func TestInsertToHead(t *testing.T) {
l := NewLinkedList()
for i := 0; i < 10; i++ {
l.InsertToHead(i + 1)
}
l.Print()
}
func TestInsertToTail(t *testing.T) {
l := NewLinkedList()
for i := 0; i < 10; i++ {
l.InsertToTail(i + 1)
}
l.Print()
}
func TestInsertBefore(t *testing.T) {
l := NewLinkedList()
for i := 0; i < 10; i++ {
l.InsertToTail(i + 1)
}
beforNode := l.head.Next
l.InsertBefore(beforNode, 11)
l.Print()
}
func TestFindByIndex(t *testing.T) {
l := NewLinkedList()
for i := 0; i < 10; i++ {
l.InsertToTail(i + 1)
}
l.Print()
findNode := l.FindByIndex(2)
fmt.Println(findNode)
}
func TestDeleteNodeByNode(t *testing.T) {
l := NewLinkedList()
for i := 0; i < 10; i++ {
l.InsertToTail(i + 1)
}
l.Print()
findNode := l.FindByIndex(2)
l.DeleteNodeByNode(findNode)
l.Print()
}
func TestDeleteNodeByIndex(t *testing.T) {
l := NewLinkedList()
for i := 0; i < 10; i++ {
l.InsertToTail(i + 1)
}
l.Print()
t.Log(l.DeleteNodeByIndex(9))
l.Print()
}
func TestReverseList_V1(t *testing.T) {
l := NewLinkedList()
for i := 0; i < 10; i++ {
l.InsertToTail(i + 1)
}
l.Print()
t.Log(l.ReverseList_V1())
l.Print()
}
func TestReverseList_V2(t *testing.T) {
l := NewLinkedList()
for i := 0; i < 10; i++ {
l.InsertToTail(i + 1)
}
l.Print()
t.Log(l.ReverseList_V2())
l.Print()
}