链表
关于链表的原理已经有一篇链表文章写的很详细了,这篇文章主要侧重于代码的实现,主要使用go实现。
单链表实现
package List
type listNode struct {
val int
next *listNode
}
func newNode(val int) *listNode {
node := new(listNode)
node.val = val
node.next = nil
return node
}
// NewList 初始化一个不带头结点的链表
func NewList(vals []int) *listNode {
var fistNode *listNode
var curNode *listNode
for _, v := range vals {
node := newNode(v)
if curNode == nil {
fistNode = node
curNode = fistNode
continue
}
curNode.next = node
curNode = curNode.next
}
return fistNode
}
// FistAdd 头插
func FistAdd(fistNode *listNode, val int) *listNode{
if fistNode == nil {
return fistNode
}
node := newNode(val)
node.next = fistNode
return node
}
// LastAdd 尾插
func LastAdd(fistNode *listNode, val int) {
if fistNode == nil {
return
}
curNode := fistNode
for curNode.next != nil {
curNode = curNode.next
}
node := newNode(val)
curNode.next = node
return
}
// IndexValAdd 在第一个指定值后插入,若没有,在链表尾部插入
// fistNode 链表第一个节点, indexVal 目标节点值, val 新节点值
func IndexValAdd(fistNode *listNode, indexVal, val int) {
if fistNode == nil {
return
}
curNode := fistNode
for curNode.next != nil && curNode.val != indexVal {
curNode = curNode.next
}
node := newNode(val)
nextNode := curNode.next
node.next = nextNode
curNode.next = node
return
}
// ChangVal 更改目标节点值,若没有,不做改动
// fistNode 链表第一个节点, indexVal 目标节点值, val 目标值
func ChangVal (fistNode *listNode, indexVal, tarVal int) {
if fistNode == nil {
return
}
curNode := fistNode
for curNode != nil && curNode.val != indexVal {
curNode = curNode.next
}
// 判断是走到最后都没有找到对应值还是找到对应值
if curNode == nil{
return
}
curNode.val = tarVal
return
}
// DelNode 删除指定节点,若没有则不删除
func DelNode(fistNode *listNode, indexVal int) {
if fistNode == nil {
return
}
curNode := fistNode
// 查找要删除节点的前一个节点
for curNode.next != nil {
nextNode := curNode.next
if nextNode.val == indexVal {
break
}
curNode = curNode.next
}
if curNode.next == nil {
return
}
nextNode := curNode.next
curNode.next = nextNode.next
}
// Show 不带头节点查
func Show(node *listNode) []int {
if node == nil {
return []int{}
}
valSlice := make([]int, 0, 4)
curNode := node
for curNode != nil {
valSlice = append(valSlice, curNode.val)
curNode = curNode.next
}
return valSlice
}
验证代码
package main
import (
"Data/List"
"fmt"
)
func main() {
// 初始化一个链表
fistNode := List.NewList([]int{1, 2, 3, 4, 5})
fmt.Println("初始化一个链表 :",List.Show(fistNode))
// 对链表进行头插
fistNode = List.FistAdd(fistNode, 0)
fmt.Println("对链表进行头插 0 :",List.Show(fistNode))
// 对链表进行尾插
List.LastAdd(fistNode, 6)
fmt.Println("对链表进行尾插 6 :",List.Show(fistNode))
// 删除指定节点
List.DelNode(fistNode, 3)
fmt.Println("删除指定节点 3 :",List.Show(fistNode))
List.DelNode(fistNode, 3)
fmt.Println("删除指定节点 3 :",List.Show(fistNode))
List.DelNode(fistNode, 3)
fmt.Println("删除指定节点 7 :",List.Show(fistNode))
// 在第一个指定值后插入
List.IndexValAdd(fistNode, 4, 41)
fmt.Println("在第一个指定值后插入,若没有,在链表尾部插入 4 41 :",List.Show(fistNode))
List.IndexValAdd(fistNode, 7, 42)
fmt.Println("在第一个指定值后插入,若没有,在链表尾部插入 7 42 :",List.Show(fistNode))
// 更改目标节点值
List.ChangVal(fistNode, 4, 40)
fmt.Println("更改目标节点值 4 40 :",List.Show(fistNode))
List.ChangVal(fistNode, 7, 43)
fmt.Println("更改目标节点值 7 43 :",List.Show(fistNode))
}
效果图
循环链表实现
package List
import "fmt"
func newCircleNode(val int) *listNode {
node := new(listNode)
node.val = val
node.next = node
return node
}
func NewCircleList(vals []int) *listNode {
var fistNode *listNode
var curNode *listNode
for _, v := range vals {
if curNode == nil {
fistNode = newCircleNode(v)
curNode = fistNode
continue
}
node := newCircleNode(v)
node.next = fistNode
curNode.next = node
curNode = curNode.next
}
return fistNode
}
func isLastNode(fistNode *listNode, node *listNode) bool {
return node.next == fistNode
}
// CircleFistAdd 头插
func CircleFistAdd(fistNode **listNode, val int) {
if fistNode == nil {
return
}
curNode := *fistNode
for !isLastNode(*fistNode, curNode) {
curNode = curNode.next
}
node := newCircleNode(val)
curNode.next = node
node.next = *fistNode
*fistNode = node
}
// CircleLastAdd 尾插
func CircleLastAdd(fistNode *listNode, val int) {
if fistNode == nil {
return
}
curNode := fistNode
for !isLastNode(fistNode, curNode) {
curNode = curNode.next
}
node := newCircleNode(val)
node.next = fistNode
curNode.next = node
}
// CircleIndexValAdd 在第一个指定值后插入,若没有,在链表尾部插入
func CircleIndexValAdd(fistNode *listNode, indexVal,val int) {
if fistNode == nil {
return
}
curNode := fistNode
for !isLastNode(fistNode, curNode) && curNode.val != indexVal {
curNode = curNode.next
}
node := newCircleNode(val)
node.next = curNode.next
curNode.next = node
}
// CircleChangVal 更改目标节点值,若没有,不做改动
func CircleChangVal(fistNode *listNode, indexVal, tarVal int) {
if fistNode == nil {
return
}
curNode := fistNode
for curNode.val != indexVal && !isLastNode(fistNode, curNode) {
curNode = curNode.next
}
if curNode.val == indexVal {
curNode.val = tarVal
return
}
fmt.Printf("节点 %d 不存在\n", indexVal)
}
// CircleDelNode 删除指定节点,若没有则不删除
func CircleDelNode(fistNode *listNode, indexVal int) {
if fistNode == nil {
return
}
curNode := fistNode
for curNode.next.val != indexVal && !isLastNode(fistNode, curNode) {
curNode = curNode.next
}
if curNode.next.val == indexVal {
curNode.next = curNode.next.next
return
}
fmt.Printf("没有该节点 %d \n", indexVal)
}
// CircleShow 查看链表
func CircleShow(fistNode *listNode) {
if fistNode == nil {
return
}
curNode := fistNode
for {
if isLastNode(fistNode, curNode) {
fmt.Printf("val:%d next:%d", curNode.val, curNode.next.val)
break
}
fmt.Printf("val:%d next:%d -> ", curNode.val, curNode.next.val)
curNode = curNode.next
}
fmt.Println()
}
验证代码
package main
import (
"Data/List"
"fmt"
)
func main() {
// 初始化一个环形链表
circleFistNode := List.NewCircleList([]int{1, 2, 3})
fmt.Println("初始化一个链表 :")
List.CircleShow(circleFistNode)
// 对链表进行头插
List.CircleFistAdd(&circleFistNode, 0)
fmt.Println("对链表进行头插 0:")
List.CircleShow(circleFistNode)
// 对链表进行尾插
List.CircleLastAdd(circleFistNode, 4)
fmt.Println("对链表进行尾插 4 :")
List.CircleShow(circleFistNode)
// 删除指定节点
fmt.Println("删除指定节点 3 :")
List.CircleDelNode(circleFistNode, 3)
List.CircleShow(circleFistNode)
fmt.Println("删除指定节点 3 :")
List.CircleDelNode(circleFistNode, 3)
List.CircleShow(circleFistNode)
fmt.Println("删除指定节点 7 :")
List.CircleDelNode(circleFistNode, 7)
List.CircleShow(circleFistNode)
// 在第一个指定值后插入
circleFistNode = List.NewCircleList([]int{1, 2, 3})
fmt.Println("初始化一个链表 :")
List.CircleShow(circleFistNode)
List.CircleIndexValAdd(circleFistNode, 2, 41)
fmt.Println("在第一个指定值后插入,若没有,在链表尾部插入 2 41 :")
List.CircleShow(circleFistNode)
List.CircleIndexValAdd(circleFistNode, 7, 42)
fmt.Println("在第一个指定值后插入,若没有,在链表尾部插入 7 42 :")
List.CircleShow(circleFistNode)
// 更改目标节点值
circleFistNode = List.NewCircleList([]int{1, 2, 3, 4})
fmt.Println("初始化一个链表 :")
List.CircleShow(circleFistNode)
fmt.Println("更改目标节点值 3 40 :")
List.CircleChangVal(circleFistNode, 3, 40)
List.CircleShow(circleFistNode)
fmt.Println("更改目标节点值 7 43 :")
List.CircleChangVal(circleFistNode, 7, 43)
List.CircleShow(circleFistNode)
//
}