亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Go實(shí)現(xiàn)List、Set、Stack、Deque等數(shù)據(jù)結(jié)構(gòu)的操作方法

 更新時(shí)間:2024年12月05日 10:44:52   作者:NPE~  
Go語(yǔ)言團(tuán)隊(duì)的一個(gè)核心目標(biāo)是保持語(yǔ)言的簡(jiǎn)單性,他們認(rèn)為,如果一個(gè)功能可以用簡(jiǎn)單的組合來(lái)實(shí)現(xiàn),那就沒(méi)有必要把它放進(jìn)標(biāo)準(zhǔn)庫(kù)里,本文給大家介紹Go實(shí)現(xiàn)List、Set、Stack、Deque等數(shù)據(jù)結(jié)構(gòu)的操作方法,感興趣的朋友跟隨小編一起看看吧

Go實(shí)現(xiàn)List、Set、Stack、Deque等數(shù)據(jù)結(jié)構(gòu)

完整代碼地址(歡迎大家??):https://github.com/ziyifast/ziyifast-code_instruction/tree/main/go-demo/go-data-structure
大家有接觸過(guò)除Go其他語(yǔ)言(如:Java)可能就會(huì)想為什么Go沒(méi)有像deque、stack、set、list這些常見(jiàn)的數(shù)據(jù)容器。尤其是對(duì)于那些習(xí)慣了用這些容器解決LeetCode問(wèn)題的同學(xué)來(lái)說(shuō),就更為不便。

1 為什么Go原生不提供這些容器:為了簡(jiǎn)潔

Go語(yǔ)言自誕生以來(lái)就有著非常明確的目標(biāo),那就是簡(jiǎn)潔、高效、并發(fā)。為了實(shí)現(xiàn)這些目標(biāo),Go在設(shè)計(jì)上做了很多取舍。

  • 簡(jiǎn)單性:Go語(yǔ)言團(tuán)隊(duì)的一個(gè)核心目標(biāo)是保持語(yǔ)言的簡(jiǎn)單性。他們認(rèn)為,如果一個(gè)功能可以用簡(jiǎn)單的組合來(lái)實(shí)現(xiàn),那就沒(méi)有必要把它放進(jìn)標(biāo)準(zhǔn)庫(kù)里。
  • deque、stack、set、list這些數(shù)據(jù)結(jié)構(gòu)雖然常用,但它們并不是編寫(xiě)高效、可維護(hù)代碼的唯一途徑。通過(guò)組合切片和映射,開(kāi)發(fā)者可以實(shí)現(xiàn)絕大多數(shù)需要的數(shù)據(jù)結(jié)構(gòu)。
  • 鼓勵(lì)最佳實(shí)踐:Go語(yǔ)言推崇一種“最小驚奇”的設(shè)計(jì)原則。也就是說(shuō),代碼應(yīng)該盡可能地容易理解和預(yù)測(cè)。標(biāo)準(zhǔn)庫(kù)的設(shè)計(jì)哲學(xué)之一就是提供最少但足夠的工具,讓開(kāi)發(fā)者能夠按照最佳實(shí)踐來(lái)編寫(xiě)代碼。
  • 這個(gè)哲學(xué)避免了標(biāo)準(zhǔn)庫(kù)的膨脹,同時(shí)確保了代碼的清晰性和可維護(hù)性。
  • 社區(qū)的力量:Go語(yǔ)言的生態(tài)系統(tǒng)非常活躍,有很多高質(zhì)量的第三方庫(kù)可以提供你需要的高級(jí)數(shù)據(jù)結(jié)構(gòu)。如果標(biāo)準(zhǔn)庫(kù)包含了所有可能需要的數(shù)據(jù)結(jié)構(gòu),那它將變得非常龐大且難以維護(hù)。

相反,通過(guò)社區(qū)貢獻(xiàn),Go可以保持核心的簡(jiǎn)潔,同時(shí)又不失靈活性。

2 實(shí)現(xiàn)

完整代碼地址:https://github.com/ziyifast/ziyifast-code_instruction/tree/main/go-demo/go-data-structure

雖然Go語(yǔ)言沒(méi)有內(nèi)置這些高級(jí)數(shù)據(jù)結(jié)構(gòu),但通過(guò)組合使用切片和映射,我們依然可以實(shí)現(xiàn)幾乎所有需要的數(shù)據(jù)結(jié)構(gòu)。

  • 而且,這種方式更符合Go語(yǔ)言簡(jiǎn)潔、高效的設(shè)計(jì)哲學(xué)。
  • 最重要的是,這也讓我們更加理解這些數(shù)據(jù)結(jié)構(gòu)的內(nèi)部實(shí)現(xiàn),而不僅僅是簡(jiǎn)單地調(diào)用現(xiàn)成的API。

所以,下次再遇到類似的問(wèn)題,大家也可以自己試試看實(shí)現(xiàn)這些數(shù)據(jù)結(jié)構(gòu),既能提升編碼能力,又能更深入地理解Go語(yǔ)言的設(shè)計(jì)理念。

List

思路:對(duì)于列表來(lái)說(shuō),通常需要有Add、Remove等操作,其實(shí)golang原生的切片就很接近切片,因此我們簡(jiǎn)單做封裝即可

package main
import (
	"errors"
	"fmt"
)
/*
	List:
		- NewList(): 創(chuàng)建一個(gè)新的列表
		- Add(element): 在列表末尾添加元素
		- Remove(index): 根據(jù)索引移除元素
		- Size(): 返回列表的大小
		- Get(index): 根據(jù)索引獲取元素
		- IsEmpty(): 判斷列表是否為空
		- Clear(): 清空列表
		- GetFirst(): 獲取第一個(gè)元素
		- GetLast(): 獲取最后一個(gè)元素
		- RemoveLast(): 移除最后一個(gè)元素
		- AddFirst(element): 在列表開(kāi)頭添加元素
		- RemoveFirst(): 移除第一個(gè)元素
		...
*/
type List struct {
	data []interface{}
}
// NewList 創(chuàng)建一個(gè)新的列表
func NewList() *List {
	return &List{
		data: []interface{}{},
	}
}
// Add 在列表末尾添加元素
func (l *List) Add(v interface{}) {
	l.data = append(l.data, v)
}
// Remove 根據(jù)索引移除元素
func (l *List) Remove(index int) error {
	if index < 0 || index >= len(l.data) {
		return errors.New("index out of bounds")
	}
	l.data = append(l.data[:index], l.data[index+1:]...)
	return nil
}
// Size 返回列表的大小
func (l *List) Size() int {
	return len(l.data)
}
// Get 根據(jù)索引獲取元素
func (l *List) Get(index int) (interface{}, error) {
	if index < 0 || index >= len(l.data) {
		return nil, errors.New("index out of bounds")
	}
	return l.data[index], nil
}
// IsEmpty 判斷列表是否為空
func (l *List) IsEmpty() bool {
	return len(l.data) == 0
}
// Clear 清空列表
func (l *List) Clear() {
	l.data = []interface{}{}
}
// GetFirst 獲取第一個(gè)元素
func (l *List) GetFirst() (interface{}, error) {
	if l.IsEmpty() {
		return nil, errors.New("list is empty")
	}
	return l.data[0], nil
}
// GetLast 獲取最后一個(gè)元素
func (l *List) GetLast() (interface{}, error) {
	if l.IsEmpty() {
		return nil, errors.New("list is empty")
	}
	return l.data[len(l.data)-1], nil
}
// AddFirst 在列表開(kāi)頭添加元素
func (l *List) AddFirst(v interface{}) {
	l.data = append([]interface{}{v}, l.data...)
}
// RemoveFirst 移除第一個(gè)元素
func (l *List) RemoveFirst() error {
	if l.IsEmpty() {
		return errors.New("list is empty")
	}
	l.data = l.data[1:]
	return nil
}
// RemoveLast 移除最后一個(gè)元素
func (l *List) RemoveLast() error {
	if l.IsEmpty() {
		return errors.New("list is empty")
	}
	l.data = l.data[:len(l.data)-1]
	return nil
}
func main() {
	list := NewList()
	// 測(cè)試 Add 和 Get
	list.Add(1)
	list.Add(2)
	list.Add(3)
	value, err := list.Get(1)
	if err != nil {
		fmt.Println("Error:", err)
	} else {
		fmt.Println("Value at index 1:", value) // 輸出: Value at index 1: 2
	}
	// 測(cè)試 Remove
	err = list.Remove(1)
	if err != nil {
		fmt.Println("Error:", err)
	} else {
		fmt.Println("Size after remove:", list.Size()) // 輸出: Size after remove: 2
	}
	// 測(cè)試 GetFirst 和 GetLast
	first, err := list.GetFirst()
	if err != nil {
		fmt.Println("Error:", err)
	} else {
		fmt.Println("First element:", first) // 輸出: First element: 1
	}
	last, err := list.GetLast()
	if err != nil {
		fmt.Println("Error:", err)
	} else {
		fmt.Println("Last element:", last) // 輸出: Last element: 3
	}
	// 測(cè)試 AddFirst 和 RemoveFirst
	list.AddFirst(0)
	first, err = list.GetFirst()
	if err != nil {
		fmt.Println("Error:", err)
	} else {
		fmt.Println("First element after addFirst:", first) // 輸出: First element after addFirst: 0
	}
	err = list.RemoveFirst()
	if err != nil {
		fmt.Println("Error:", err)
	} else {
		fmt.Println("Size after removeFirst:", list.Size()) // 輸出: Size after removeFirst: 2
	}
	// 測(cè)試 RemoveLast
	err = list.RemoveLast()
	if err != nil {
		fmt.Println("Error:", err)
	} else {
		fmt.Println("Size after removeLast:", list.Size()) // 輸出: Size after removeLast: 1
	}
	// 測(cè)試 Clear
	list.Clear()
	fmt.Println("Is list empty after clear?", list.IsEmpty()) // 輸出: Is list empty after clear? true
}

Stack

Stack最大的特點(diǎn)就是:先進(jìn)后出,這里底層存儲(chǔ)我們也可以采用切片來(lái)進(jìn)行封裝

package main
import (
	"fmt"
)
/*
  Stack:
	- Push(item): 入棧
	- Pop(): 出棧
	- Peek(): 返回棧頂元素,但不刪除它
	- IsEmpty(): 判斷棧是否為空
	- Search(item): 搜索 item 元素在棧中的位置,如果沒(méi)找到,返回 -1
	- Clear(): 清空棧
	...
*/
type Stack struct {
	data []interface{}
}
func NewStack() *Stack {
	return &Stack{
		data: []interface{}{},
	}
}
// Push 入棧
func (s *Stack) Push(v interface{}) {
	s.data = append(s.data, v)
}
// Pop 出棧
func (s *Stack) Pop() interface{} {
	if len(s.data) == 0 {
		return nil
	}
	val := s.data[len(s.data)-1]
	s.data = s.data[:len(s.data)-1]
	return val
}
// Peek 返回棧頂元素,但不刪除它
func (s *Stack) Peek() interface{} {
	if len(s.data) == 0 {
		return nil
	}
	return s.data[len(s.data)-1]
}
// IsEmpty 判斷棧是否為空
func (s *Stack) IsEmpty() bool {
	return len(s.data) == 0
}
// Search 搜索 item 元素在棧中的位置,如果沒(méi)找到,返回 -1
func (s *Stack) Search(v interface{}) int {
	for index, value := range s.data {
		if value == v {
			return index
		}
	}
	return -1
}
// Clear 清空棧
func (s *Stack) Clear() {
	s.data = []interface{}{}
}
func main() {
	stack := NewStack()
	// 測(cè)試 Push 和 Peek
	stack.Push(1)
	stack.Push(2)
	stack.Push(3)
	fmt.Println("Top element:", stack.Peek()) // 輸出: Top element: 3
	// 測(cè)試 Pop
	fmt.Println("Popped element:", stack.Pop())         // 輸出: Popped element: 3
	fmt.Println("Top element after pop:", stack.Peek()) // 輸出: Top element after pop: 2
	// 測(cè)試 IsEmpty
	fmt.Println("Is stack empty?", stack.IsEmpty()) // 輸出: Is stack empty? false
	// 測(cè)試 Search
	fmt.Println("Index of 2:", stack.Search(2)) // 輸出: Index of 2: 1
	fmt.Println("Index of 3:", stack.Search(3)) // 輸出: Index of 3: -1
	// 測(cè)試 Clear
	stack.Clear()
	fmt.Println("Is stack empty after clear?", stack.IsEmpty()) // 輸出: Is stack empty after clear? true
}

Deque

Deque雙端隊(duì)列:前后都可以進(jìn)出

package main
import (
	"container/list"
	"fmt"
)
/*
	Deque:
		- PushFront: 在隊(duì)列前端插入元素
		- PushBack: 在隊(duì)列后端插入元素
		- PopFront: 從隊(duì)列前端移除并返回元素
		- PopBack: 從隊(duì)列后端移除并返回元素
		...
*/
// Deque 雙端隊(duì)列結(jié)構(gòu)體
type Deque struct {
	data *list.List
}
// NewDeque 創(chuàng)建一個(gè)新的雙端隊(duì)列
func NewDeque() *Deque {
	return &Deque{data: list.New()}
}
// PushFront 在隊(duì)列前端插入元素
func (d *Deque) PushFront(value interface{}) {
	d.data.PushFront(value)
}
// PushBack 在隊(duì)列后端插入元素
func (d *Deque) PushBack(value interface{}) {
	d.data.PushBack(value)
}
// PopFront 移除并返回隊(duì)列前端的元素
func (d *Deque) PopFront() interface{} {
	front := d.data.Front()
	if front != nil {
		d.data.Remove(front)
		return front.Value
	}
	return nil
}
// PopBack 移除并返回隊(duì)列后端的元素
func (d *Deque) PopBack() interface{} {
	back := d.data.Back()
	if back != nil {
		d.data.Remove(back)
		return back.Value
	}
	return nil
}
func main() {
	deque := NewDeque()
	// 測(cè)試 PushFront 和 PushBack
	deque.PushBack(1)
	deque.PushFront(2)
	deque.PushBack(3)
	deque.PushFront(4)
	// 測(cè)試 PopFront
	fmt.Println("Popped from front:", deque.PopFront()) // 輸出: Popped from front: 4
	fmt.Println("Popped from front:", deque.PopFront()) // 輸出: Popped from front: 2
	// 測(cè)試 PopBack
	fmt.Println("Popped from back:", deque.PopBack()) // 輸出: Popped from back: 3
	fmt.Println("Popped from back:", deque.PopBack()) // 輸出: Popped from back: 1
	// 測(cè)試空隊(duì)列的情況
	fmt.Println("Popped from front on empty deque:", deque.PopFront()) // 輸出: Popped from front on empty deque: <nil>
	fmt.Println("Popped from back on empty deque:", deque.PopBack())   // 輸出: Popped from back on empty deque: <nil>
	// 再次測(cè)試 PushFront 和 PushBack
	deque.PushFront(5)
	deque.PushBack(6)
	// 測(cè)試 PeekFront 和 PeekBack
	fmt.Println("Front element:", deque.PopFront()) // 輸出: Front element: 5
	fmt.Println("Back element:", deque.PopBack())   // 輸出: Back element: 6
}

Set

package main
import (
	"fmt"
	"sync"
)
/*
 Set: 可以去除重復(fù)元素
	- Add: 添加元素
	- Remove: 刪除元素
	- Contains: 檢查元素是否存在
	- IsEmpty: 判斷集合是否為空
	- Clear: 清空集合
	- Iterator: 返回一個(gè)迭代器通道
	...
*/
type Set struct {
	mu   sync.RWMutex
	data map[interface{}]bool
}
// NewSet 創(chuàng)建一個(gè)新的集合
func NewSet() *Set {
	return &Set{
		data: make(map[interface{}]bool),
	}
}
// Add 添加元素到集合
func (s *Set) Add(value interface{}) {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.data[value] = true
}
// Remove 從集合中刪除元素
func (s *Set) Remove(value interface{}) {
	s.mu.Lock()
	defer s.mu.Unlock()
	delete(s.data, value)
}
// Contains 檢查元素是否存在于集合中
func (s *Set) Contains(value interface{}) bool {
	s.mu.RLock()
	defer s.mu.RUnlock()
	return s.data[value]
}
// IsEmpty 判斷集合是否為空
func (s *Set) IsEmpty() bool {
	s.mu.RLock()
	defer s.mu.RUnlock()
	return len(s.data) == 0
}
// Clear 清空集合
func (s *Set) Clear() {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.data = make(map[interface{}]bool)
}
// Iterator 返回一個(gè)迭代器通道
func (s *Set) Iterator() <-chan interface{} {
	ch := make(chan interface{})
	go func() {
		defer func() {
			if r := recover(); r != nil {
				fmt.Println("Recovered in Iterator:", r)
			}
			close(ch)
		}()
		s.mu.RLock()
		defer s.mu.RUnlock()
		for k := range s.data {
			ch <- k
		}
	}()
	return ch
}
func main() {
	set := NewSet()
	// 測(cè)試 Add 和 Contains
	set.Add(1)
	set.Add(2)
	set.Add(3)
	fmt.Println("Contains 1:", set.Contains(1)) // 輸出: Contains 1: true
	fmt.Println("Contains 4:", set.Contains(4)) // 輸出: Contains 4: false
	// 測(cè)試 Remove
	set.Remove(2)
	fmt.Println("Contains 2 after remove:", set.Contains(2)) // 輸出: Contains 2 after remove: false
	// 測(cè)試 IsEmpty
	fmt.Println("Is set empty?", set.IsEmpty()) // 輸出: Is set empty? false
	// 測(cè)試 Clear
	set.Clear()
	fmt.Println("Is set empty after clear?", set.IsEmpty()) // 輸出: Is set empty after clear? true
	// 測(cè)試 Iterator
	set.Add(1)
	set.Add(2)
	set.Add(3)
	fmt.Println("Elements in set:")
	for i := range set.Iterator() {
		fmt.Println(i)
	}
	// 其他測(cè)試代碼
	data := make([]int, 2, 20)
	data[0] = -1
	fmt.Println("Length of data:", len(data))   // 輸出: Length of data: 2
	fmt.Println("Capacity of data:", cap(data)) // 輸出: Capacity of data: 20
}

更多的數(shù)據(jù)結(jié)構(gòu),比如LinkedList等,大家可以自行下來(lái)嘗試一下。

3 代碼地址

完整代碼地址(歡迎大家??):https://github.com/ziyifast/ziyifast-code_instruction/tree/main/go-demo/go-data-structure

到此這篇關(guān)于Go實(shí)現(xiàn)List、Set、Stack、Deque等數(shù)據(jù)結(jié)構(gòu)的文章就介紹到這了,更多相關(guān)Go List、Set、Stack、Deque數(shù)據(jù)結(jié)構(gòu)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Golang 實(shí)現(xiàn)Socket服務(wù)端和客戶端使用TCP協(xié)議通訊

    Golang 實(shí)現(xiàn)Socket服務(wù)端和客戶端使用TCP協(xié)議通訊

    這篇文章主要介紹了Golang 實(shí)現(xiàn)Socket服務(wù)端和客戶端使用TCP協(xié)議通訊,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • Go位集合相關(guān)操作bitset庫(kù)安裝使用

    Go位集合相關(guān)操作bitset庫(kù)安裝使用

    這篇文章主要為大家介紹了Go位集合相關(guān)操作bitset庫(kù)安裝使用,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • Go語(yǔ)言截取字符串函數(shù)用法

    Go語(yǔ)言截取字符串函數(shù)用法

    這篇文章主要介紹了Go語(yǔ)言截取字符串函數(shù)用法,實(shí)例分析了Go語(yǔ)言操作字符串的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-02-02
  • Golang實(shí)現(xiàn)http重定向https

    Golang實(shí)現(xiàn)http重定向https

    這篇文章介紹了Golang實(shí)現(xiàn)http重定向https的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-07-07
  • Golang實(shí)現(xiàn)SSH、SFTP操作小結(jié)

    Golang實(shí)現(xiàn)SSH、SFTP操作小結(jié)

    在日常的一些開(kāi)發(fā)場(chǎng)景中,我們需要去和遠(yuǎn)程服務(wù)器進(jìn)行一些通信,本文主要介紹了Golang實(shí)現(xiàn)SSH、SFTP操作小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-04-04
  • Golang收支記賬程序詳細(xì)編寫(xiě)過(guò)程

    Golang收支記賬程序詳細(xì)編寫(xiě)過(guò)程

    這篇文章主要介紹了Golang實(shí)現(xiàn)收支記賬程序流程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2022-12-12
  • golang fmt格式“占位符”的實(shí)例用法詳解

    golang fmt格式“占位符”的實(shí)例用法詳解

    在本篇文章里小編給大家整理的是一篇關(guān)于golang fmt格式“占位符”的實(shí)例用法詳解內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。
    2021-07-07
  • golang中使用sync.Map的方法

    golang中使用sync.Map的方法

    這篇文章主要介紹了golang中使用sync.Map的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-06-06
  • Go實(shí)現(xiàn)字符串與數(shù)字的高效轉(zhuǎn)換

    Go實(shí)現(xiàn)字符串與數(shù)字的高效轉(zhuǎn)換

    在軟件開(kāi)發(fā)的世界里,數(shù)據(jù)類型轉(zhuǎn)換是一項(xiàng)基礎(chǔ)而重要的技能,尤其在Go語(yǔ)言這樣類型嚴(yán)格的語(yǔ)言中,正確高效地進(jìn)行類型轉(zhuǎn)換對(duì)于性能優(yōu)化和代碼質(zhì)量至關(guān)重要,本文給大家介紹了Go實(shí)現(xiàn)字符串與數(shù)字的高效轉(zhuǎn)換,需要的朋友可以參考下
    2024-02-02
  • golang 實(shí)用庫(kù)gotable的具體使用

    golang 實(shí)用庫(kù)gotable的具體使用

    使用gotable框架以實(shí)現(xiàn)在CLI命令行界面中打印表格。本文就介紹一下golang 實(shí)用庫(kù)gotable的使用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07

最新評(píng)論