github.com/qiuhoude/go-web@v0.0.0-20220223060959-ab545e78f20d/algorithm/datastructures/linkedlist/signle_linkedlist.go (about) 1 package linkedlist 2 3 import ( 4 "fmt" 5 "strings" 6 ) 7 8 /* 9 单链表 10 */ 11 12 type ListNode struct { 13 next *ListNode 14 value interface{} 15 } 16 17 func NewListNode(v interface{}) *ListNode { 18 return &ListNode{nil, v} 19 } 20 21 func (this *ListNode) GetNext() *ListNode { 22 return this.next 23 } 24 25 func (this *ListNode) GetValue() interface{} { 26 return this.value 27 } 28 29 func (this *ListNode) String() string { 30 return fmt.Sprintf("%v", this.value) 31 } 32 33 type LinkedList struct { 34 head *ListNode 35 length uint 36 } 37 38 func NewLinkedList() *LinkedList { 39 return &LinkedList{NewListNode(nil), 0} 40 } 41 42 func (this *LinkedList) Len() uint { 43 return this.length 44 } 45 46 //在某个节点后面插入节点 47 func (this *LinkedList) InsertAfter(p *ListNode, v interface{}) bool { 48 if p == nil { 49 return false 50 } 51 newNode := NewListNode(v) 52 oldNext := p.next 53 p.next = newNode 54 newNode.next = oldNext 55 this.length++ 56 return true 57 } 58 59 //在某个节点前面插入节点 60 func (this *LinkedList) InsertBefore(p *ListNode, v interface{}) bool { 61 if p == nil || p == this.head { 62 return false 63 } 64 cur := this.head.next 65 pre := this.head 66 for ; cur != nil; cur = cur.next { 67 if cur == p { 68 break 69 } 70 pre = cur 71 } 72 if cur == nil { // 没有找到 73 return false 74 } 75 newNode := NewListNode(v) 76 pre.next = newNode 77 newNode.next = cur 78 this.length++ 79 return true 80 } 81 82 // 反转链表 83 func (this *LinkedList) Reverse() { 84 cur := this.head.next 85 var pre *ListNode = nil 86 var tmp *ListNode = nil 87 for cur != nil { 88 tmp = pre 89 pre = cur 90 cur = cur.next 91 pre.next = tmp 92 } 93 /*for ; cur != nil; { 94 tmp = cur.next 95 cur.next = pre 96 pre = cur 97 cur = tmp 98 }*/ 99 this.head.next = pre 100 } 101 102 //在链表头部插入节点 103 func (this *LinkedList) InsertToHead(v interface{}) bool { 104 return this.InsertAfter(this.head, v) 105 } 106 107 //在链表尾部插入节点 108 func (this *LinkedList) InsertToTail(v interface{}) bool { 109 cur := this.head 110 for ; cur.next != nil; cur = cur.next { 111 } 112 return this.InsertAfter(cur, v) 113 } 114 115 //通过索引查找节点 116 func (this *LinkedList) FindByIndex(index uint) *ListNode { 117 if index >= this.length { 118 return nil 119 } 120 cur := this.head 121 for i := uint(0); cur.next != nil; i++ { 122 cur = cur.next 123 if i == index { 124 return cur 125 } 126 } 127 return nil 128 } 129 130 func (this *LinkedList) DeleteNode(p *ListNode) bool { 131 if p == nil { 132 return false 133 } 134 cur := this.head.next 135 pre := this.head 136 for ; cur != nil; cur = cur.next { 137 if cur == p { 138 break 139 } 140 pre = cur 141 } 142 if cur == nil { 143 return false 144 } 145 146 pre.next = cur.next 147 cur.next = nil 148 this.length-- 149 return true 150 } 151 152 // 判断单链表是否有环 153 // 思路: 快 慢 指针,不断往后移动,只要快慢指针指向同位置说明有环 154 func (this *LinkedList) HasCycle() bool { 155 if nil != this.head { 156 slow := this.head 157 fast := this.head 158 for nil != fast && nil != fast.next { 159 slow = slow.next 160 fast = fast.next.next 161 if slow == fast { 162 return true 163 } 164 } 165 } 166 return false 167 168 } 169 170 // 找到中间节点 当有 len值时 直接 len>0; index=len/2 171 func (this *LinkedList) FindMidNode2() *ListNode { 172 if this.length <= 0 { 173 return nil 174 } 175 index := this.length / 2 176 return this.FindByIndex(uint(index)) 177 } 178 179 // 找到中间节点 180 func (this *LinkedList) FindMidNode() *ListNode { 181 if this.head.next == nil { 182 return nil 183 } 184 fast := this.head 185 slow := this.head 186 for fast != nil && fast.next != nil { 187 fast = fast.next.next 188 slow = slow.next 189 } 190 if fast != nil { 191 slow = slow.next 192 } 193 return slow 194 } 195 196 func (this *LinkedList) String() string { 197 var sb strings.Builder 198 cur := this.head.next 199 sb.WriteString("head ") 200 for ; cur != nil; cur = cur.next { 201 _, _ = fmt.Fprintf(&sb, "->%v", cur.GetValue()) 202 } 203 sb.WriteString(" tail") 204 return sb.String() 205 } 206 207 /* 208 两个有序单链表合并, 归并排序的链表结构可以此 209 */ 210 func MergeSortedList(l1, l2 *LinkedList) *LinkedList { 211 if l1 == nil && l2 == nil { 212 return nil 213 } 214 nL := NewLinkedList() 215 cur := nL.head 216 cur1 := l1.head.next 217 cur2 := l2.head.next 218 for cur1 != nil && cur2 != nil { 219 if cur1.value.(int) > cur2.value.(int) { 220 cur.next = cur2 221 cur2 = cur2.next 222 } else { 223 cur.next = cur1 224 cur1 = cur1.next 225 } 226 cur = cur.next 227 } 228 if cur1 != nil { 229 cur.next = cur1 230 } else if cur2 != nil { 231 cur.next = cur2 232 } 233 234 return nL 235 } 236 237 // 拷贝值的方式 重新创建新列表 238 func MergeSortedList2(l1, l2 *LinkedList) *LinkedList { 239 if l1 == nil && l2 == nil { 240 return nil 241 } 242 nL := NewLinkedList() 243 244 cur1 := l1.head.next 245 cur2 := l2.head.next 246 for cur1 != nil && cur2 != nil { 247 if cur1.value.(int) > cur2.value.(int) { 248 nL.InsertToTail(cur2.value) 249 cur2 = cur2.next 250 } else { 251 nL.InsertToTail(cur1.value) 252 cur1 = cur1.next 253 } 254 } 255 for cur1 != nil || cur2 != nil { 256 if cur1 != nil { 257 nL.InsertToTail(cur1.value) 258 cur1 = cur1.next 259 } 260 if cur2 != nil { 261 nL.InsertToTail(cur2.value) 262 cur2 = cur2.next 263 } 264 } 265 return nL 266 } 267 268 /* 269 删除倒数第N个节点 270 思路: 还是快 慢 双指针, 让快指针先走n部,然后快慢指针同时走, 快指针到尾部就结束 271 此时慢指针下一个node就是要目标node 272 */ 273 func (this *LinkedList) DeleteBottomN(n int) { 274 if n <= 0 || nil == this.head || nil == this.head.next { 275 return 276 } 277 // 相聚 278 fast := this.head 279 for i := 1; i <= n && fast != nil; i++ { 280 fast = fast.next 281 } 282 283 if nil == fast { 284 return 285 } 286 287 slow := this.head 288 for nil != fast.next { 289 slow = slow.next 290 fast = fast.next 291 } 292 slow.next = slow.next.next 293 }