GO算法初步

数组中
一种数出现奇数次
其他都是是出现偶数次

找到奇数次的数

两种数出现奇数次
其他都是是出现偶数次

type Number interface {
	int | int64 | byte
}

func findNumber[N Number](myArray []N) {
	//异或操作。
	var a = myArray[0]
	for i := 1; i < len(myArray); i++ {
		a = a ^ myArray[i]
	}
	fmt.Printf("%v", a)
}

func findNumberTwo[N Number](myArray []N) {

}

func main() {
	var myArray = []int{1, 1, 1, 1, 2, 2, 2, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8}
	findNumber[int](myArray)
}

这里实际上是考异或的操作
就是计算机组成原理中的位操作

然后是

初步的排序

冒泡排序
type MyNumber interface {
	int | int64 | int32 | byte | float32 | float64
}


func bubbleSort[M MyNumber](myArray []M) {
	for j := 1; j < len(myArray); j++ {
		for i := 0; i < len(myArray); i++ {
			if myArray[i] > myArray[j] {
				myArray[i], myArray[j] = myArray[j], myArray[i]
			}
		}
	}
	for i, m := range myArray {
		fmt.Printf("%d %d\n", i, m)
	}
}
插入排序
type MyNumber interface {
	int | int64 | int32 | byte | float32 | float64
}
func insertSort[M MyNumber](myArray []M) {
	for i := 1; i < len(myArray); i++ {
		for j := 0; j < i; j++ {
			if myArray[i] < myArray[j] {
				myArray[i], myArray[j] = myArray[j], myArray[i]
			}
		}

	}
	for i, m := range myArray {
		fmt.Printf("%d %d\n", i, m)
	}
}
二分查找

这里有个特殊的地方
我尽量不去使用递归
因为有时候递归不知道变量怎么变化(就是自己写不来递归。和优化递归)
这里二分查找是找到相同元素最左边的地方
如果要最右边的地方。改>=为<=

func dichotomyFind[M MyNumber](myArray []M, find M) int {
	var middle = len(myArray) / 2
	var left = 0
	var right = len(myArray)
	var CPArray = make([]M, len(myArray))
	copy(CPArray, myArray)
	var check = 0
	for {
		//这里多找一一遍。如果两次都一样就跳出循环
		if check != middle {
			check = middle
		} else if check == middle {
			return middle
		}
		if CPArray[middle] >= find {
			right = middle
			middle = (right + left) / 2
		} else if CPArray[middle] < find {
			left = middle + 1
			middle = (right + left) / 2
		}
	}
}

如果不要求最左边最右边
就直接找到就返回

func dichotomyFind[M MyNumber](myArray []M, find M) int {
	var middle = len(myArray) / 2
	var left = 0
	var right = len(myArray)
	var CPArray = make([]M, len(myArray))
	copy(CPArray, myArray)
	for {
		if CPArray[middle] > find {
			right = middle
			middle = (right + left) / 2
		} else if CPArray[middle] < find {
			left = middle + 1
			middle = (right + left) / 2
		} else if CPArray[middle] == find {
			return middle
		}
	}
}

链表

链表的基本

包括单链表、双向链表和循环链表。
创建、增加节点、删除节点、单链表逆置、合并有序链表

快慢指针
额外数据结构记录(哈希表等)

合并有序单链表

判断链表是否有环
回文链表

复制含有随机指针节点的链表
两个单链表相交的一系列问题

定义泛型

```go
type Value interface {
	int | int8 | byte | float64 | float32 | int64
}

//单链表节点
type Node[v Value] struct {
	V    v
	next *Node[v]
}

//双向链表节点
type BidirectionalNode[v Value] struct {
	V v
	F *BidirectionalNode[v]
	N *BidirectionalNode[v]
}

创建链表

func (n *Node[Value]) CreateNormalLinkedList(data []Value) *Node[Value] {
	var tem = n
	for _, datum := range data {
		var newN = new(Node[Value])
		newN.V = datum
		newN.next = nil
		tem.next = newN
		tem = newN
	}
	return n
}

创建环形链表

func (n *Node[Value]) CreateNormalRingList(data []Value, position int) *Node[Value] {
	var tem = n
	var ringNode = n
	for p, datum := range data {
		var newN = new(Node[Value])
		newN.V = datum
		newN.next = nil
		tem.next = newN
		tem = newN
		if p == position {
			ringNode = newN
		}
	}
	tem.next = ringNode
	return n
}

循环输出不是环形代码

func (n *Node[Value]) PrintNormalLinkedList() {
	var tem = n
	for {
		if tem == nil {
			break
		}
		fmt.Printf("%v \n", tem.V)
		tem = tem.next
	}
}

插入

func (n *Node[Value]) InsertInNormal(insert Value, position int) {
	//看插入的位置。因为我这个头结点是记录的长度
	var tem = n
	var one Value = 1
	n.V = add(n.V, one)
	for i := 0; i < (position - 1); i++ {
		tem = tem.next
	}
	if tem.next == nil {
		var newN = new(Node[Value])
		newN.V = insert
		newN.next = nil
		tem.next = newN
	} else if tem.next != nil {
		var newN = new(Node[Value])
		newN.V = insert
		newN.next = tem.next
		tem.next = newN
	}
}

删除

func (n *Node[Value]) DeleteInNormal(delete Value) {
	var tem = n
	var one Value = 1
	n.V = reduce(n.V, one)
	for {
		if tem.next.V == delete {
			break
		} else {
			tem = tem.next
		}
	}
	tem.next = tem.next.next
}

单链表逆置,双指针头插法

func (n *Node[Value]) SinglyLinkedListInversion() {
	var onePointer = n.next.next
	var twoPointer = n.next.next
	var head = n.next
	head.next = nil
	for {
		twoPointer = twoPointer.next
		onePointer.next = head
		head = onePointer
		onePointer = twoPointer
		if twoPointer == nil {
			break
		}
	}
	n.next = head
}

合并有序链表

func Compare[v Value](a v, b v) (result bool) {
	if a >= b {
		result = true
	} else if a < b {
		result = false
	}
	return result
}

func MergeOrderedList[v Value](headOne *Node[v], headTwo *Node[v]) (mergeList *Node[v]) {
	var temOne = headOne.next
	var temTwo = headTwo.next
	mergeList = new(Node[v])
	mergeList.V = add(headOne.V, headTwo.V)
	mergeList.next = nil
	var mergeHead = mergeList
	for {
		if temTwo == nil {
			break
		} else if temOne == nil {
			break
		}
		if Compare(temOne.V, temTwo.V) == true {
			mergeList.next = temTwo
			mergeList = mergeList.next
			temTwo = temTwo.next
		} else if Compare(temOne.V, temTwo.V) == false {
			mergeList.next = temOne
			mergeList = mergeList.next
			temOne = temOne.next
		}
	}
	if temTwo != nil {
		mergeList.next = temTwo
	} else if temOne != nil {
		mergeList.next = temOne
	}
	return mergeHead
}

判断是否有环

额外空间MAP
func RingLinkedListWithMap[v Value](head *Node[v]) (IsRing bool, RingNode *Node[v]) {
	var checkMap = make(map[*Node[v]]int)
	var i = 0
	var tem = head
	for {
		checkMap[tem] = i
		i = i + 1
		tem = tem.next
		if tem == nil {
			IsRing = false
			RingNode = nil
			break
		} else if _, ok := checkMap[tem]; ok == true {
			IsRing = true
			RingNode = tem
			break
		}
	}
	fmt.Printf("%v %v \n", IsRing, RingNode.V)
	return false, RingNode
}
快慢指针
func RingLinkedListWithFastAndSlowPointer[v Value](head *Node[v]) (IsRing bool, RingNode *Node[v]) {
	var slowPointer = head.next
	var fastPointer = head.next
	var tem = head.next
	for {
		slowPointer = slowPointer.next
		fastPointer = fastPointer.next.next
		if fastPointer == nil {
			IsRing = false
			RingNode = nil
			break
		} else if fastPointer == slowPointer {
			IsRing = true
			fastPointer = tem
			for {
				slowPointer = slowPointer.next
				fastPointer = fastPointer.next
				if fastPointer == slowPointer {
					RingNode = fastPointer
					break
				}
			}
			break
		}
	}
	fmt.Printf("%v %v \n", IsRing, RingNode.V)
	return IsRing, RingNode
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值