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  }