栈
//用数组实现一个顺序栈
type Stack struct{
arr []int
used int
capcity int
}
func NewStack(capicity int) *Stack{
stack := &Stack{}
stack.arr = make([]int,capicity)
stack.used = 0
stack.capcity = capicity
return stack
}
// 入栈操作
func (this *Stack)push(item int)bool{
// 数组空间不够了,直接返回false,入栈失败。
if this.capcity == this.used {
return false
}
// 将item放到下标为used的位置,并且used加一
this.arr[this.used] = item
this.used++
return true
}
// 出栈操作
func (this *Stack)pop() int{
// 栈为空,则直接返回-1
if this.used == 0 {
return -1
}
// 返回下标为used-1的数组元素,并且栈中元素个数used减一
tmp := this.arr[this.used-1]
this.used--
return tmp
}
/**
用哨兵链表实现一个顺序栈
*/
type Node struct {
value int
next *Node
}
type Stack struct {
top *Node
}
//初始化的时候创建一个空的带头节点
func NewStack()*Stack{
stack := &Stack{}
newNode := &Node{}
stack.top = newNode
return stack
}
//入栈
func (this *Stack)push(value int) bool{
newNode := &Node{}
newNode.value = value
//直接把头节点复制给新节点然后把新节点指向到头节点
newNode.next = this.top.next
this.top.next = newNode
return true
}
//出栈
func (this *Stack)pop() int{
//栈空返回-1
if this.top.next == nil {
return -1
}
//获取第一个非带头节点的值,并且把指针往后移
tmp := this.top.next.value
this.top.next = this.top.next.next
return tmp
}
队列
/**
用数组实现一个顺序队列
*/
type Queue struct {
arr []int
head int
tail int
capicity int
}
func NewQueue(capicity int)*Queue{
queue := &Queue{}
queue.arr = make([]int,capicity)
queue.head = 0
queue.tail = 0
queue.capicity = capicity
return queue
}
func (this *Queue)push(value int) bool{
//尾部 == 容量 表示满了
if this.tail == this.capicity {
//如果头部为0 表示没有扩容空间
if(this.head == 0){
return false
}
//把数据批量往前移动
for i:=this.head; i<this.tail; i++{
this.arr[i-this.head] = this.arr[i]
}
}
this.arr[this.tail] = value
//tail变成表示最后一个空的空间
this.tail++
return true
}
func (this *Queue)pop()int{
//需要判断队列是否为空
if this.head == this.tail{
return -1
}
value := this.arr[this.head]
this.head++
return value
}
/**
循环队列
*/
//入队
func (this *LoopQueue) pop() int{
if this.head == this.tail {
return -1
}
value := this.arr[this.head]
this.head = (this.head+1) % this.count
return value
}
//出队
func (this *LoopQueue) push(value int) bool{
//求余其实就是一个0~count的循环条件,相当于在循环旋转
//队列满的条件 tail+1 == head,如果tail+1已经超出范围,需要用求余循环往复
if (this.tail + 1) % this.count == this.head{
return false
}
this.arr[this.tail] = value
//tail往后移动,如果无法后移,则从0开始(通过求余循环)
this.tail = (this.tail+1) % this.count
return true
}
/**
用链表实现一个顺序队列
*/
//主要需要区分链表是否为空的情况
func (this *Queue)push(value int)bool{
newNode := &Node{}
newNode.data = value
if this.head == nil {
this.head = newNode
this.tail = newNode
}else{
//顺序不能换,先把尾节点的next指针指向到新节点,然后更新尾节点
this.tail.next = newNode
this.tail = newNode
}
return true
}
//需要判断链表为空的情况
func (this *Queue)pop()int{
if this.head == nil{
return -1
}
tmp := this.head.data
this.head = this.head.next
return tmp
}
递归
/**
带字典的斐波拉契数列
*/
var note = map[int]int{}
func fib(n int) int {
//如果1和0,直接返回
if n == 1|| n == 0 {
return n
}
//如果有记录到note,直接用Note的值
if value,ok := note[n];ok{
note[n] = value
return value
}
//把结果放到Note
result := fib(n-1)+fib(n-2)
note[n] = result
return note[n]
}
/*
普通版阶乘
e.g. 3=1*2*3
递推公式 n = n * fact(n-1)
中止条件 n == 1
*/
func Factorial(n int)int{
if n == 1 {
return 1
}
return n * Factorial(n-1)
}
/**
优化版:带字典的阶乘
*/
var note = map[int]int{}
func FactOptimize(n int) int {
if n == 1 {
return 1
}
if val,ok := note[n]; ok {
return val
}
result := n * Factorial(n-1)
note[n] = result
return result
}
// 全排列
// 1=>1 1,2=>[2,1][1,2]
//递推公式:print n,funArr(arr,n+1)
//递归结束条件:数组结束n == arr[len-1]
//length个数(无重)的全排列,就是将length个数分别放在第零个位置,再将剩下的length-1个数的全排列加在后面,当length-1=1时为递归的出口
func funArr(arr []int,n int,length int){
//直到数组指针到最后一位,把整个数组打印
if n >= length-1 {
fmt.Println(arr)
return
}else{
for i:=n;i<length;i++{
//n是第一位数,依次把数组中每个数字放到第一个位置
arr[i],arr[n] = arr[n],arr[i]
//然后对n+1后的数字进行全排列
funArr(arr,n+1,length)
//恢复位置
arr[n],arr[i] = arr[i],arr[n]
}
}
}