zoukankan      html  css  js  c++  java
  • 栈 队列 递归 算法的GO语言实现

    //用数组实现一个顺序栈
    
    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]
    		}
    	}
    }
    
  • 相关阅读:
    [小程序]支付宝小程序GET请求数据并展示列表界面
    [小程序] 支付宝小程序使用list时提示元素不存在
    [GO] gin 框架gorm下使用logrus记录sql语句
    [Git] 强制使用远端仓库代码覆盖本地代码
    [PHP]外观/门面/Facade模式-结构型设计模式
    ansible-playbook根据shell判断状态
    ansible Unarchive
    find文件获得绝对文件路径绝对值
    Tomcat和JVM的性能调优总结
    Jenkins内置环境变量的使用
  • 原文地址:https://www.cnblogs.com/jaychan/p/13096801.html
Copyright © 2011-2022 走看看