单链表的增/改/查操作
·
一条链表并不需要一整块连续的内存空间存储元素。链表的元素可以分散在内存空间的天涯海角,通过每个节点上的next,prev指针,将零散的内存块串联起来形成一个链式结构。
这样做的好处很明显,首先就是可以提高内存的利用效率,链表的节点不需要挨在一起,给点内存 new 出来一个节点就能用,操作系统会觉得这娃好养活。
另外一个好处,它的节点要用的时候就能接上,不用的时候拆掉就行了,从来不需要考虑扩缩容和数据搬移的问题,理论上讲,链表是没有容量限制的(除非把所有内存都占满,这不太可能)。
当然,不可能只有好处没有局限性。数组最大的优势是支持通过索引快速访问元素,而链表就不支持。
type ListNode struct{
Val int
Next *ListNode
}
//我先输入一个数组,转换为一条单链表
func creatLinkedList(arr []int) *listNode {
if arr == nil || len(arr) == 0 {
return nil
}
head := &ListNode(Val: arr[0])]
cur := arr[0]
for i := 1;i<len(arr); i++{
cur.Next = &ListNode{Val: arr[i]}
cur = cur.Next
}
return head
}
ok,现在基于上面的工具函数对链表进行基础操作
首先是单链表的遍历/查找/修改
//创建一条单链表
head := createLinkedList([]int{1,2,3,4,5})
//遍历单链表
for p := head;p != nil; p = p.Next{
fmt.Println(p.Val)
}
接下来进行链表的增操作
第一种情况是:在链表的头部插入新元素
//创建一条单链表
head := createLinkedList([]int{1,2,3,4,5})
//在单链表头部插入一个新节点0
newNode := &ListNode{Val: 0}
newNode.Next = head
head = newNode
第二种情况是:在链表的尾部加入一个新的节点
//还是先创建一条单链表
head := createLinkedList([]int{1,2,3,4,5})
//首先我先定义指针的头
p := head
//然后再走到链表的最后一个节点
for p.Next != nil {
p = p.NExt
}
p.Next = &ListNode{Val: 6}
第三种情况是在单链表中间插入新元素
//创建一条单链表
head := createLinkList([]int{1,2,3,4,5})
//现在需要在第三个节点后面插入一个新节点88
p := head
for i := 0;i<2;i++{
p = p.next
}
newNode := &ListNode{Val: 88}
newNode.next = p.Next
p.Next = newNode
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐
所有评论(0)