Go数据结构(一)线性表·单链表

 方法:

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`,以保证插入新节点的正确性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值