Golang 单链表基本操作

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()

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值