//定义一个结构体模拟数组
type Array struct {
data []interface{} //存放数据
size int //已使用的容量
}
func NewArray(capacity int) *Array{
arr := &Array{}
arr.data = make([]interface{},capacity)
arr.size = 0
return arr
}
//扩容:申请一个新空间,把遍历旧空间,把数据搬运过去
func (this *Array)resize(newCapacity int){
newArr := make([]interface{},newCapacity)
for i:=0; i<this.size; i++ {
newArr[i] = this.data[i]
}
this.data = newArr
}
//增加一个新元素
func (this *Array)add(index int,element interface{}){
if index < 0 || index > this.size {
panic("error index")
}
//已用空间==容量 触发扩容
if len(this.data) == this.size {
this.resize(this.size*2)
}
//把index后的数据全部都后移一个位置
for i:=this.size-1; i>=index; i-- {
this.data[i+1] = this.data[i]
}
this.data[index] = element
this.size++
}
type Node struct {
data interface{}
next *Node
}
type List struct {
head *Node
}
func NewNode(data interface{})*Node{
return &Node{
data:data,
next:nil,
}
}
/**
在指定节点后插入一个数据(要判断传入的节点是否为空)
*/
func (this *List)InsertAfer(node *Node,newValue interface{}) bool{
if node == nil{
return false
}
newNode := NewNode(newValue)
newNode.next = node.next
node.next = newNode
return true
}
/**
插入一个节点(主要需要区分插入的是不是第一个节点)
*/
func (this *List)Insert(newValue interface{}) bool{
newNode := NewNode(newValue)
if this.head == nil{
this.head = newNode
}else{
//循环找最后一个节点
p := this.head
for p.next != nil{
p = p.next
}
//节点的指针变换(关键要防止丢指针)
newNode.next = p.next
p.next = newNode
}
return true
}
/*
删除一个节点
*/
func (this *List)DeleteNode(node *Node) bool{
//链表为空或者传入的节点为空,返回false
if this.head == nil || node == nil {
return false
}
//特殊处理第一个节点
if this.head == node {
this.head = this.head.next
return true
}
//以第二个节点为当前节点
prev := this.head
cur := prev.next
//下一个节点非空 继续往下找
//如果当前节点已经是目标节点才停止
for cur.next != nil && node != cur {
prev = cur
cur = cur.next
}
prev.next = cur.next
return true
}
/**
循环链表(关键是怎么判断到最后一个元素)
*/
type LoopList struct {
head *Node
}
func (this *LoopList) add(value interface{}){
newNode := NewNode(value)
//特殊处理头节点
if this.head == nil{
this.head = newNode
newNode.next = this.head
}else{
p := this.head
//下一个元素是头元素,则该元素是就是要找的尾元素,结束循环
for p.next != this.head {
p = p.next
}
newNode.next = p.next
p.next = newNode
}
}
*/
/**
链表反转
前驱指针和后驱指针构成,每次循环把后驱指针指向到前驱指针
*/
func reverseList(head *ListNode) *ListNode {
//前驱指针默认为空
var pre *ListNode = nil
//把头指针作为当前指针,只要当前指针不为空,表示有数据
var cur = head
for cur != nil {
//临时保存后驱指针
tmp := cur.Next
//后驱指针指向 前一个数据
cur.Next = pre
//更新数据,下一个数据的cur就是当前的pre
pre = cur
cur = tmp
}
//最后一个cur是赋值给了pre,如果返回cur,指针是空的
return pre
}
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
/**
两个有序链表合并成一个
解题思路:
1.用哨兵简化插入
2.两个节点比较,把哨兵指向到数字小的节点,然后节点往后走一步,再重复比较。
3.每次比较后哨兵都要往后走一步,指向到正确的位置
4.走到最后哨兵是停留在最后一个位置,所以需要一开始就保存好哨兵的头
*/
func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode {
//哨兵节点,不存数据,为了插入的时候更方便
preHead := &ListNode{}
//把头节点暂存
result := preHead
//判断哪个节点的数据小,就把哨兵指向该节点,同时该节点偏移到下一个
for l1 != nil && l2 != nil {
if l1.Val < l2.Val{
preHead.Next = l1
l1 = l1.Next
}else{
preHead.Next = l2
l2 = l2.Next
}
//哨兵节点偏移到下一个
preHead = preHead.Next
}
//l1 或者 l2 有剩余数据,直接用哨兵指向他就可以了
if l1 != nil {
preHead.Next = l1
}
if l2 != nil{
preHead.Next = l2
}
//哨兵的后一个节点
return result.Next
}
/**
* 需要考虑奇偶数的情况,奇数fast.Next生效,偶数fast生效
*/
func middleNode(head *ListNode) *ListNode {
slow := head
fast := head
//奇数: 1
//第一轮: fast.Next != nil 生效,循环结束
//偶数: 1 -> 2
//第一轮:slow == 2 ,fast != nil 生效,循环结束
for fast != nil && fast.Next != nil {
slow = slow.Next
fast = fast.Next.Next
}
return slow
}
原文:https://www.cnblogs.com/jaychan/p/13034437.html