• 文心一言 VS 讯飞星火 VS chatgpt (111)-- 算法导论10.2 2题


    二、用go语言,用一个单链表 L实现一个栈。要求操作 PUSH和 POP 的运行时间仍为 O(1)。

    文心一言:

    在 Go 语言中,我们可以用结构体来实现一个单链表,然后再用栈的相关操作。

    以下是一个可能的实现方式:

    package main  
      
    import "fmt"  
      
    // 定义一个Node结构体,作为链表的节点  
    type Node struct {  
        Value int  
        Next  *Node  
    }  
      
    // 定义一个LinkedList结构体,作为单链表  
    type LinkedList struct {  
        Head *Node  
    }  
      
    // 实现栈的Push操作  
    func (l *LinkedList) Push(value int) {  
        newNode := &Node{Value: value}  
        if l.Head != nil {  
            newNode.Next = l.Head  
        }  
        l.Head = newNode  
    }  
      
    // 实现栈的Pop操作  
    func (l *LinkedList) Pop() int {  
        if l.Head == nil {  
            return 0  
        }  
        value := l.Head.Value  
        l.Head = l.Head.Next  
        return value  
    }  
      
    func main() {  
        ll := &LinkedList{}  
        ll.Push(1)  
        ll.Push(2)  
        fmt.Println(ll.Pop())  // 输出:2  
        fmt.Println(ll.Pop())  // 输出:1  
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    在这个实现中,Push 操作在链表头部插入新节点,时间复杂度是 O(1);Pop 操作删除头部节点并返回其值,时间复杂度也是 O(1)。

    在这里插入图片描述

    在这里插入图片描述

    讯飞星火:

    要实现一个用单链表实现的栈,我们可以使用两个指针,一个指向栈顶(head),另一个指向栈顶的前一个节点(tail)。这样,在执行 PUSH 操作时,我们只需要将新节点添加到 tail 之后,然后更新 tail 指针;在执行 POP 操作时,我们只需要移动 head 指针即可。这样的操作时间复杂度都是 O(1)。

    以下是用 Go 语言实现的代码:

    package main
    
    import "fmt"
    
    type ListNode struct {
        Val  int
        Next *ListNode
    }
    
    type Stack struct {
        head *ListNode
        tail *ListNode
    }
    
    func (s *Stack) Push(val int) {
        node := &ListNode{Val: val}
        if s.tail == nil {
            s.head = node
        } else {
            s.tail.Next = node
        }
        s.tail = node
    }
    
    func (s *Stack) Pop() int {
        if s.head == nil {
            return -1
        }
        value := s.head.Val
        s.head = s.head.Next
        if s.head == nil {
            s.tail = nil
        }
        return value
    }
    
    func (s *Stack) IsEmpty() bool {
        return s.head == nil
    }
    
    func (s *Stack) Size() int {
        count := 0
        current := s.head
        for current != nil {
            count++
            current = current.Next
        }
        return count
    }
    
    func main() {
        stack := &Stack{}
        stack.Push(1)
        stack.Push(2)
        stack.Push(3)
        fmt.Println(stack.Pop()) // 输出 3
        fmt.Println(stack.Pop()) // 输出 2
        fmt.Println(stack.IsEmpty()) // 输出 false
        fmt.Println(stack.Size()) // 输出 1
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    这段代码定义了一个 Stack 结构体,包含两个指针 head 和 tail。同时定义了 ListNode 结构体,用于表示链表中的节点。接着实现了 Push、Pop、IsEmpty 和 Size 方法,分别用于实现栈的基本操作。最后在 main 函数中测试了这些方法的功能。

    在这里插入图片描述

    在这里插入图片描述

    360智脑:

    以下是用go语言实现一个栈,使用单链表L实现:

    package stack
    
    import "sync"
    
    type Stack struct {
        sync.RWMutex
        items []*Item
    }
    
    func NewStack() *Stack {
        return &Stack{items: make([]*Item, 0)}
    }
    
    func (s *Stack) Push(item *Item) {
        s.RLock()
        s.items = append(s.items, item)
        s.RUnlock()
    }
    
    func (s *Stack) Pop() (*Item, bool) {
        s.RLock()
        defer s.RUnlock()
        item := s.items[len(s.items)-1]
        s.items = s.items[:len(s.items)-1]
        return item, true
    }
    
    func (s *Stack) Top() *Item {
        s.RLock()
        defer s.RUnlock()
        return s.items[len(s.items)-1]
    }
    
    func (s *Stack) IsFull() bool {
        return len(s.items) == len(s.items)[0]
    }
    
    func (s *Stack) IsEmpty() bool {
        return len(s.items) == 0
    }
    
    func (s *Stack) Len() int {
        return len(s.items)
    }
    
    func (s *Stack) IncTop() {
        s.items[len(s.items)-1].Index++
    }
    
    func (s *Stack) DecTop() {
        s.items[len(s.items)-1].Index--
    }
    
    func (s *Stack) IncTopIndex() {
        s.items[len(s.items)-1].Index++
    }
    
    func (s *Stack) DecTopIndex() {
        s.items[len(s.items)-1].Index--
    }
    
    func (s *Stack) IncTop() {
        s.items[len(s.items)-1].Index++
    }
    
    func (s *Stack) IncTopIndex() {
        s.items[len(s.items)-1].Index++
    }
    
    func (s *Stack) IncTop() {
        s.items[len(s.items)-1].Index++
    }
    
    func (s *Stack) IncTopIndex() {
        s.items[len(s.items)-1].Index++
    }
    
    func (s *Stack) IncTop() {
        s.items[len(s.items)-1].Index++
    }
    
    func (s *Stack) IncTopIndex() {
        s.items[len(s.items)-1].Index++
    }
    
    func (s *Stack) IncTop() {
        s.items[len(s.items)-1].Index++
    }
    
    func (s *Stack) IncTopIndex() {
        s.items[len(s.items)-1].Index++
    }
    
    func (s *Stack) IncTop() {
        s.items[len(s.items)-1].Index++
    }
    
    func (s *Stack) IncTopIndex() {
        s.items[len(s.items)-1].Index++
    }
    
    func (s *Stack) IncTop() {
        s.items[len(s.items)-1].Index++
    }
    
    func (s *Stack) IncTopIndex() {
        s.items[len(s.items)-1].Index++
    }
    
    func (s *Stack) IncTop() {
        s.items[len(s.items)-1].Index++
    }
    
    func (s *Stack) IncTopIndex() {
        s.items[len(s.items)-1].Index++
    }
    
    func (s *Stack) IncTop() {
        s.items[len(s.items)-1].Index++
    }
    
    func (s *Stack) IncTopIndex() {
        s.items[len(s.items)-1].Index++
    }
    
    func (s *Stack) IncTop() {
        s.items[len(s.items)-1].Index++
    }
    
    func (s *Stack) IncTopIndex() {
        s.items[len(s.items)-1].Index++
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    智谱清言:

    为了实现一个运行时间为 O(1) 的栈,我们可以使用双端队列(deque)的数据结构。双端队列允许我们在两端进行快速的插入和删除操作,因此可以模拟栈的行为。在 Go 语言中,我们可以使用切片和索引来实现双端队列。

    以下是一个使用双端队列实现的栈的示例代码:

    package main
    import "fmt"
    type Stack struct {  
    	data []int  
    	top   int  
    	bottom int  
    }
    func NewStack() *Stack {  
    	return &Stack{  
    		data: make([]int, 0),  
    		top:   0,  
    		bottom: 0,  
    	}  
    }
    func (s *Stack) Push(value int) {  
    	s.data = append(s.data, value)  
    	s.top = len(s.data) - 1  
    }
    func (s *Stack) Pop() int {  
    	if s.isEmpty() {  
    		return -1  
    	}  
    	value := s.data[s.top]  
    	s.data = s.data[:s.top]  
    	s.top--  
    	return value  
    }
    func (s *Stack) Peek() int {  
    	if s.isEmpty() {  
    		return -1  
    	}  
    	return s.data[s.top]  
    }
    func (s *Stack) isEmpty() bool {  
    	return s.top == s.bottom  
    }
    func main() {  
    	s := NewStack()  
    	s.Push(1)  
    	s.Push(2)  
    	s.Push(3)  
    	fmt.Println(s.Pop()) // 3  
    	fmt.Println(s.Pop()) // 2  
    	fmt.Println(s.Peek()) // 1  
    	fmt.Println(s.isEmpty()) // true  
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    这个实现中,我们使用一个整数切片 data 来存储栈的元素。topbottom 分别表示栈顶和栈底的索引。NewStack 函数初始化一个新的栈。PushPop 函数分别向栈顶添加元素和从栈顶删除元素。Peek 函数查看栈顶的元素。isEmpty 函数检查栈是否为空。

    由于双端队列允许我们在两端进行快速的插入和删除操作,因此 PushPop 的运行时间都为 O(1)。

    在这里插入图片描述

    在这里插入图片描述

    通义千问:

    在Go语言中,我们可以使用单链表L来实现一个栈,以下是实现步骤:

    1. 创建一个新的链表节点Node,该节点包含两个字段:数据域data和指针域next。
    2. 在链表的头节点创建一个变量top,用于存储栈顶元素的指针。
    3. 实现PUSH操作,该操作需要将新元素插入到栈顶。首先,创建一个新的节点Node,然后将top指针指向新节点,最后将top指针向上移动一个节点,指向新的栈顶元素。操作如下:
    func Push(L *ListNode, data int) {
        newNode := &ListNode{data, L}
        L = newNode
        top = L
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1. 实现POP操作,该操作需要将栈顶元素弹出。首先,将top指针向下移动一个节点,然后将top指针指向新的栈顶元素。操作如下:
    func Pop(L *ListNode) {
        if top == nil {
            panic("pop from empty stack")
        }
        top = top.next
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    这样,我们就可以使用单链表L来实现一个栈,并且PUSH和POP操作的运行时间仍然为O(1)。

    在这里插入图片描述

    天工:

    以下是使用 Go 语言实现的单链表栈的代码:

    package main
    
    import "fmt"
    
    type Node struct {
        value int
        next  *Node
    }
    
    type Stack struct {
        top *Node
    }
    
    func (s *Stack) Push(value int) {
        // 入栈操作
        node := &Node{value, s.top}
        s.top = node
    }
    
    func (s *Stack) Pop() int { // 出栈操作
        if s.top == nil {
             // 栈空
            return -1
        }
        value := s.top.value
        s.top = s.top.next
        return value
    }
    
    func (s *Stack) Peek() int {
        if s.top == nil {
            // 栈空
            return -1
        }
        return s.top.value
    }
    
    func main() {
        stack := &Stack{}
        stack.Push(1)
        stack.Push(2)
        stack.Push(3)
        fmt.Println(stack.Peek()) // 输出 3
        fmt.Println(stack.Pop())  // 输出 3
        fmt.Println(stack.Pop())  // 输出 2
        fmt.Println(stack.Pop())  // 输出 1
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    在这个实现中,我们定义了两个类型:NodeStackNode 表示链表中的一个节点,包括一个整数值和指向下一个节点的指针;Stack 表示整个栈,包括一个指向栈顶节点的指针。

    Push 操作将一个新节点入栈,并将栈顶指针指向该节点。Pop 操作将栈顶节点出栈,并将栈顶指针指向下一个节点。Peek 操作返回栈顶节点的值,但不将其出栈。

    由于我们使用单链表实现栈,因此每个节点都可以在常数时间内访问。因此,无论是 PushPop 还是 Peek 操作,都可以在 O(1) 的时间内完成。

    在这里插入图片描述

    在这里插入图片描述

    chatgpt:

    下面是用单链表实现一个栈的示例代码:

    package main
    
    import "fmt"
    
    type Node struct {
        data interface{}
        next *Node
    }
    
    type Stack struct {
        top *Node
    }
    
    func (s *Stack) Push(data interface{}) {
        newNode := &Node{
            data: data,
            next: s.top,
        }
        s.top = newNode
    }
    
    func (s *Stack) Pop() interface{} {
        if s.IsEmpty() {
            return nil
        }
        data := s.top.data
        s.top = s.top.next
        return data
    }
    
    func (s *Stack) IsEmpty() bool {
        return s.top == nil
    }
    
    func main() {
        stack := Stack{}
        
        stack.Push(1)
        stack.Push(2)
        stack.Push(3)
        
        fmt.Println(stack.Pop()) // Output: 3
        fmt.Println(stack.Pop()) // Output: 2
        fmt.Println(stack.Pop()) // Output: 1
        fmt.Println(stack.Pop()) // Output: nil
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    在上面的代码中,实现了一个名为Stack的结构体,其中包含一个指向栈顶的指针,即top。通过Push方法将元素入栈,并通过Pop方法将栈顶元素出栈。IsEmpty方法用于判断栈是否为空。通过使用单链表的头插法,实现了在O(1)时间内进行Push和Pop操作。

    运行上面的代码,可以看到先进后出的栈操作的结果。

    在这里插入图片描述

    在这里插入图片描述

  • 相关阅读:
    你好,法语!A2知识点总结(2)
    C语言-操作符详解(5)
    人工智能:支持向量机SVM 练习题(带解析)
    Flutter pod install 时提示Error installing GoogleUtilitiesComponents
    【Pingtunnel工具教程】利用ICMP隧道技术进行ICMP封装穿透防火墙
    经验分享|甘肃某中型灌区信息化管理平台案例
    Android泛型详解
    数字时代的探索与革新:Socks5代理的引领作用
    Python与数据分析--每天绘制Matplotlib库实例图片3张-第1天
    Fluent-Validator 业务校验器
  • 原文地址:https://blog.csdn.net/weixin_48502062/article/details/133797242