漫画算法-学习笔记(04)

漫画算法-小灰的算法之旅(04)

1. 什么是数据存储的物理结构呢?

数组和链表都是在内存中实实在在存在的存储结构。逻辑结构是一个抽象的概念,它依赖于物理结构而存在。

线性结构非线性结构
逻辑结构顺序表、栈、队列树、图
顺序存储结构链式存储结构
物理结构数组链表

栈和队列,都属于逻辑结构,它们的物理实现既可以利用数组,也可以利用链表来完成。

2. 什么是栈

栈(stack):是一种线性数据结构,它就像一个放入乒乓球的圆筒容器,栈中的元素只能先入后出(First In Last Out)。最早进入的元素存放的位置叫做栈底(bottom),最后进入的元素存放的位置叫作栈顶(top)

栈这种数据结构既可以用数组来实现,也可以用链表来实现。栈的基本操作是入栈出栈

入栈

入栈操作(push)就是把新元素放入栈中,只允许从栈顶一侧放入元素,新元素的位置将会成为新的栈顶(top).

出栈

出栈操作(pop) 就是把元素从栈中弹出,只有栈顶元素才允许出栈,出栈元素的前一个元素将会成为新的栈顶

代码实现
用数组实现栈
// 不确定变量类型和结构,使用了interface
type Stack struct {
	data []interface{}
}

func (s *Stack) Len() int {
	return len(s.data)
}
func (s *Stack) Cap() int {
	return cap(s.data)
}

func (s *Stack) IsEmpty() bool {
	return len(s.data) == 0

}

// 入栈
func (s *Stack) Push(value interface{}) {
	//将 新元素追加到栈顶
	s.data = append(s.data, value)
}

func (s *Stack) Pop() (interface{}, error) {
	theStack := s
	if len(theStack.data) == 0 {
		return nil, errors.New("Out of index ,len is 0")
	}
	//获取到栈顶元素
	popValue := theStack.data[theStack.Len()-1]
	//更换新到栈顶元素
	theStack.data = theStack.data[:theStack.Len()-1]
	s = theStack
	return popValue, nil
}
//获取栈顶元素
func (s *Stack) Top() (interface{}, error) {

	if s.IsEmpty() {
		return nil, errors.New("Out of index, len is 0")
	}
	return s.data[len(s.data)-1], nil
}

func main(){
  var myStack Stack
	myStack.Push(1)
	myStack.Push("test")
	log.Println("stack len is :",myStack.Len())
	pop, _ := myStack.Pop()
	log.Println("stack pop value is :",pop)
	log.Println(" pop stack after len is :",myStack.Len())
}
使用单链表实现栈
type LinklistStack struct {
	headNode *Node
}

type Node struct {
	data interface{}
	next *Node
}

func (l LinklistStack) IsEmpty() bool {
	return l.headNode==nil
}

//初始化一个栈
func New() *LinklistStack {
	return &LinklistStack{nil}
}

// 链表的头插法 入栈
func (l *LinklistStack) push(value interface{})  {
	newNode :=&Node{
		data: value,
	}
	newNode.next=l.headNode
	l.headNode=newNode
}

func (l *LinklistStack)pop() (interface{},error)  {

	if l.IsEmpty() {
		return nil,errors.New("栈以空")
	}
	popValue :=l.headNode.data
	l.headNode=l.headNode.next
	return popValue,nil

}

func (l *LinklistStack) Traverse() {

	if l.IsEmpty() {
		log.Println("栈已空")
		return
	}
	currentNode :=l.headNode
	for currentNode!=nil {
		log.Printf("%v\t",currentNode.data)
		currentNode=currentNode.next
	}
}

func main(){
  
  log.Println(" linklistStack ")
	stack := New()
	stack.push(123)
	stack.push("test")
	stack.push("hello")
	stack.Traverse()
	value, _ := stack.pop()
	log.Println("stack.pop() value is ",value)
	stack.Traverse()
}
时间复杂度

入栈和出栈只会影响到最后一个元素,不涉及其他元素的整体移动,所以无论是以数组还是以链表实现,入栈和出栈的时间复杂度都为O(1)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值