方法:
type LinkedListMethods interface {
LinkedListInsert(index int, nodeValue int) bool
DisplayLinkedList()
LinkedListTailInsert(n int) bool
LinkedListDelete(index int) bool
ListLength() int
IsEmpyte() bool
}
程序代码:
package main
import "fmt"
type LinkedListMethods interface {
LinkedListInsert(index int, nodeValue int) bool
DisplayLinkedList()
LinkedListTailInsert(n int) bool
LinkedListDelete(index int) bool
ListLength() int
IsEmpyte() bool
}
type LNode struct {
data int
next *LNode
}
func initLinkedList() (L *LNode) {
// 操作结果:构造一个空的单链表L
/********** Begin **********/
L = &LNode{}
return
/********** End **********/
}
func (L *LNode) LinkedListInsert(index int, nodeValue int) bool {
// 在带头结点的单链线性表L的第i个元素之前插入元素e
/********** Begin **********/
if index <= 0 {
return false
}
j := 0
for j < index-1 && L != nil { // 防止断链
j++
L = L.next
}
if L == nil {
return false
} else {
s := &LNode{data: nodeValue, next: L.next}
L.next = s
return true
}
}
func (L *LNode) LinkedListTailInsert(n int) bool {
r := L //r始终指向终端结点,开始时指向头结点
for i := 0; i < n; i++ {
s := &LNode{} //创建新结点s
s.data = i
r.next = s //将结点s插入结点r之后
r = s //下次循环时 r 就会指向新插入的节点 s,从而可以继续插入下一个元素 每次循环都会移动r尾指针
}
r.next = nil //终端结点next域置为NULL
return true
}
func (L *LNode) DisplayLinkedList() {
p := L.next
for p != nil {
fmt.Print(p.data, " ")
p = p.next
}
fmt.Println()
}
func (L *LNode) IsEmpyte() bool {
if L.next == nil {
return true
}
return false
}
func (L *LNode) ListLength() int {
i := 0
for L.next != nil {
i++
L = L.next
}
return i
}
func (L *LNode) LinkedListDelete(index int) bool {
temp := L
for j := 0; j < index-1; j++ {
temp = temp.next
if temp == nil || temp.next == nil {
return false
}
}
temp.next = temp.next.next
return true
}
func main() {
var LinkedList LinkedListMethods = &LNode{}
LinkedList.LinkedListTailInsert(50)
//LinkedList = initLinkedList()
//LinkedList.LinkedListInsert(1, 3)
//LinkedList.LinkedListInsert(2, 4)
//LinkedList.LinkedListInsert(3, 5)
LinkedList.DisplayLinkedList()
fmt.Println(LinkedList.ListLength())
LinkedList.LinkedListDelete(3)
LinkedList.DisplayLinkedList()
}
重点讲一下尾插法:
函数使用一个指针 `r` 始终指向终端结点,开始时 `r` 指向头结点。 然后使用一个 `for` 循环从 0 到 `n-1` 插入元素。在每次循环中,创建一个新的结点 `s`,并将其值设置为当前插入的元素序号 `i`。然后将 `s` 插入到 `r` 之后,即 `r.next = s`。最后将 `r` 更新为 `s`,以便下次循环时能够插入下一个元素。 循环结束后,将终端结点的 `next` 域设置为 `NULL`,表示链表的尾部。 最后,函数返回 `true` 表示插入成功。
在单链表的尾插法中,每次循环都需要将 `r` 更新为 `s`,这是为了保证每次循环都能正确地插入新节点到链表的尾部。 在尾插法中,`r` 始终指向链表的终端节点,即最后一个节点。每次循环都会创建一个新节点 `s`,并将其值设置为当前插入的元素序号 `i`。然后,将 `s` 插入到 `r` 之后,即 `r.next = s`。 接下来,将 `r` 更新为 `s`,即 `r = s`。这样,下次循环时 `r` 就会指向新插入的节点 `s`,从而可以继续插入下一个元素。 通过这种方式,每次循环都可以在链表的尾部插入一个新的节点,直到插入了所有需要的节点为止。最后,将终端节点的 `next` 域设置为 `NULL`,表示链表的尾部。 如果不将 `r` 更新为 `s`,则每次循环结束后,`r` 仍然指向原来的终端节点,无法正确地插入新节点到链表的尾部。因此,每次循环都需要将 `r` 更新为 `s`,以保证插入新节点的正确性。