1.Go语言copy函数、sort排序、双向链表、list操作和双向循环链表
1.1.copy函数
通过copy函数可以把一个切片内容复制到另一个切片中
(1)把长切片拷贝到短切片中
- package main
- import "fmt"
- func main() {
- s1 := []int {1,2}
- s2 := []int{3,4,5,6}
- //copy的是角标,不会增加元切片的长度
- copy(s1,s2)
- fmt.Println(s1) //[3 4]
- fmt.Println(s2) //[3 4 5 6]
- }
(2)把短切片拷贝到长切片中
- package main
- import "fmt"
- func main() {
- s1 := []int {1,2}
- s2 := []int{3,4,5,6}
- //copy的是角标,不会增加元切片的长度
- copy(s2,s1)
- fmt.Println(s1) //[1 2]
- fmt.Println(s2) //[1 2 5 6]
- }
(3)把切片片段拷贝到切片中
- package main
- import "fmt"
- func main() {
- s1 := []int {1,2}
- s2 := []int{3,4,5,6}
- //copy的是角标,不会增加元切片的长度
- copy(s1,s2[1:3])
- fmt.Println(s1) //[[4 5]
- fmt.Println(s2) //[3 4 5 6]
- }
1.2.sort排序
- package main
- import (
- "fmt"
- "sort"
- )
- func main() {
- num := []int{1,7,3,5,2}
- //升序排序
- sort.Ints(num)
- fmt.Println(num) //[1 2 3 5 7]
- //降序排序
- sort.Sort(sort.Reverse(sort.IntSlice(num)))
- fmt.Println(num) //[7 5 3 2 1]
- }
1.3.双向链表
(1)双向链表的结构
双向链表结构中元素在内存中不是紧邻空间,而是每个元素中存放上一个元素和后一个元素的地址
- 第一个元素称为(头)元素,前连接(前置指针域)为nil
- 最后一个元素称为 尾(foot)元素,后连接(后置指针域)尾nil
双向链表的优点
- 在执行新增元素或删除元素时效率高,获取任意一个元素,可以方便的在这个元素前后插入元素
- 充分利用内存空间,实现内存灵活管理
- 可实现正序和逆序遍历
- 头元素和尾元素新增或删除时效率较高
双向链表的缺点
- 链表增加了元素的指针域,空间开销比较大
- 遍历时跳跃性查找内容,大量数据遍历性能低
(2)双向链表容器List
在Go语言标准库的container/list包提供了双向链表List
List结构体定义如下
- root表示根元素
- len表示链表中有多少元素
- // List represents a doubly linked list.
- // The zero value for List is an empty list ready to use.
- type List struct {
- root Element // sentinel list element, only &root, root.prev, and root.next are used
- len int // current list length excluding (this) sentinel element
- }
其中Element结构体定义如下
- next表示下一个元素,使用Next()可以获取到
- prev表示上一个元素,使用Prev()可以获取到
- list表示元素属于哪个链表
- Value表示元素的值,interface()在Go语言中表示任意类型
- // Element is an element of a linked list.
- type Element struct {
- // Next and previous pointers in the doubly-linked list of elements.
- // To simplify the implementation, internally a list l is implemented
- // as a ring, such that &l.root is both the next element of the last
- // list element (l.Back()) and the previous element of the first list
- // element (l.Front()).
- next, prev *Element
- // The list to which this element belongs.
- list *List
- // The value stored with this element.
- Value interface{}
- }
1.4.操作List
(1)直接使用container/list包下的New()新建一个空的List
添加,遍历,取首尾,取中间元素
- package main
- import (
- "container/list"
- "fmt"
- )
- func main() {
- //实例化
- mylist := list.New()
- fmt.Println(mylist)
- //添加
- mylist.PushFront("a") //["a"]
- mylist.PushBack("b") //["a","b"]
- mylist.PushBack("c") //["a","b","c"]
- //在最后一个元素的前面添加
- mylist.InsertBefore("d",mylist.Back()) //["a","b","d","c"]
- mylist.InsertAfter("e",mylist.Front()) //["a","e","b","d","c"]
- //遍历
- for e := mylist.Front(); e != nil; e = e.Next(){
- fmt.Print(e.Value, " ") //a e b d c
- }
- fmt.Println("")
- //取首尾
- fmt.Println(mylist.Front().Value) //a
- fmt.Println(mylist.Back().Value) //c
- //取中间的元素,通过不断的Next()
- n := 3
- var curr *list.Element
- if n > 0 && n <= mylist.Len(){
- if n == 1 {
- curr = mylist.Front()
- }else if n == mylist.Len(){
- curr = mylist.Back()
- }else {
- curr = mylist.Front()
- for i := 1; i < n; i++{
- curr = curr.Next()
- }
- }
- }else {
- fmt.Println("n的数值不对")
- }
- fmt.Println(curr.Value) //b
- }
(2)移动元素
- package main
- import (
- "container/list"
- "fmt"
- )
- func main() {
- //实例化
- mylist := list.New()
- fmt.Println(mylist)
- //添加
- mylist.PushFront("a") //["a"]
- mylist.PushBack("b") //["a","b"]
- mylist.PushBack("c") //["a","b","c"]
- //在最后一个元素的前面添加
- mylist.InsertBefore("d",mylist.Back()) //["a","b","d","c"]
- mylist.InsertAfter("e",mylist.Front()) //["a","e","b","d","c"]
- //移动,把第一个元素一道最后一个元素的前面
- mylist.MoveBefore(mylist.Front(),mylist.Back())
- //mylist.MoveAfter(mylist.Back(),mylist.Front())
- //把最后一个元素移动到最前面
- //mylist.MoveToFront(mylist.Back())
- //把第一个元素移动到最后面
- //mylist.MoveToBack(mylist.Front())
- for e := mylist.Front(); e != nil; e = e.Next(){
- fmt.Print(e.Value, " ") //e b d a c
- }
- }
(3)删除
- mylist.Remove(mylist.Front())
1.5.双向循环列表
(1)循环链表特点是没有节点的指针域为nil,通过任何一个元素都可以找到其它元素
环形链表结构如下
双向循环链表和双向链表区别
- 双向循环链表没有严格意义上的头元素和尾元素
- 没有元素的前连接和后连接为nil
- 一个长度为n的双向循环链表,通过某个元素向某个方向移动,在查找最多n-1次,一定会找到另一个元素
(2)在container/ring包下结构体Ring源码如下
- 官方明确说明了Ring是循环链表的元素,又是环形链表
- 实际使用时Ring遍历就是环形链表第一个元素
- // A Ring is an element of a circular list, or ring.
- // Rings do not have a beginning or end; a pointer to any ring element
- // serves as reference to the entire ring. Empty rings are represented
- // as nil Ring pointers. The zero value for a Ring is a one-element
- // ring with a nil Value.
- //
- type Ring struct {
- next, prev *Ring
- Value interface{} // for use by client; untouched by this library
- }
(3)创建和查看
- package main
- import (
- "container/ring"
- "fmt"
- )
- func main() {
- //r代表整个循环链表,又代表第一个元素
- r := ring.New(5)
- r.Value = 0
- r.Next().Value = 1
- r.Next().Next().Value = 2
- //r.Next().Next().Next().Value = 3
- //r.Next().Next().Next().Next().Value = 4
- r.Prev().Value = 4
- r.Prev().Prev().Value = 3
- //查看元素内容
- //循环链表有几个元素,func就执行几次,i当前执行元素的内容
- r.Do(func(i interface{}) {
- fmt.Print(i, " ") //0 1 2 3 4
- })
- fmt.Println("")
- //取中间元素,用移动
- fmt.Println(r.Move(3).Value) //3
- }
(4)增加
- package main
- import (
- "container/ring"
- "fmt"
- )
- func main() {
- //r代表整个循环链表,又代表第一个元素
- r := ring.New(5)
- r.Value = 0
- r.Next().Value = 1
- r.Next().Next().Value = 2
- //r.Next().Next().Next().Value = 3
- //r.Next().Next().Next().Next().Value = 4
- r.Prev().Value = 4
- r.Prev().Prev().Value = 3
- //增加
- r1 := ring.New(2)
- r1.Value = 5
- r1.Next().Value = 6
- r.Link(r1)
- r.Do(func(i interface{}) {
- fmt.Print(i, " ") //0 5 6 1 2 3 4
- })
- }
(5)删除
- package main
- import (
- "container/ring"
- "fmt"
- )
- func main() {
- //r代表整个循环链表,又代表第一个元素
- r := ring.New(5)
- r.Value = 0
- r.Next().Value = 1
- r.Next().Next().Value = 2
- //r.Next().Next().Next().Value = 3
- //r.Next().Next().Next().Next().Value = 4
- r.Prev().Value = 4
- r.Prev().Prev().Value = 3
- //删除
- r.Unlink(1)
- r.Do(func(i interface{}) {
- fmt.Print(i, " ") //0 2 3 4
- })
- }
删除后面两个
- //删除
- r.Unlink(2)
- r.Do(func(i interface{}) {
- fmt.Print(i, " ") //0 3 4
- })
r.Next()删除
- //删除
- r.Next().Unlink(2)
- r.Do(func(i interface{}) {
- fmt.Print(i, " ") //0 1 4
- })qu
超出范围,取5的余数
- //删除
- r.Unlink(6)
- r.Do(func(i interface{}) {
- fmt.Print(i, " ") //0 2 3 4
- })
1.Go语言copy函数、sort排序、双向链表、list操作和双向循环链表的更多相关文章
- 1.Go-copy函数、sort排序、双向链表、list操作和双向循环链表
1.1.copy函数 通过copy函数可以把一个切片内容复制到另一个切片中 (1)把长切片拷贝到短切片中 ? 1 2 3 4 5 6 7 8 9 10 11 12 package main imp ...
- C语言通用双向循环链表操作函数集
说明 相比Linux内核链表宿主结构可有多个链表结构的优点,本函数集侧重封装性和易用性,而灵活性和效率有所降低. 可基于该函数集方便地构造栈或队列集. 本函数集暂未考虑并发保护. 一 ...
- 【C语言教程】“双向循环链表”学习总结和C语言代码实现!
双向循环链表 定义 双向循环链表和它名字的表意一样,就是把双向链表的两头连接,使其成为了一个环状链表.只需要将表中最后一个节点的next指针指向头节点,头节点的prior指针指向尾节点,链表就能成环儿 ...
- GO语言学习——切片三 append()方法为切片添加元素、切片的扩容策略、使用copy()函数复制切片、从切片中删除元素
append()方法为切片添加元素 注意:通过var声明的零值切片可以在append()函数直接使用,无需初始化. var s []int s = append(s, 1, 2, 3) append( ...
- 3204: 数组做函数参数--排序函数2--C语言
3204: 数组做函数参数--排序函数2--C语言 时间限制: 1 Sec 内存限制: 128 MB提交: 211 解决: 143[提交][状态][讨论版][命题人:smallgyy] 题目描述 ...
- 3203 数组做函数参数----排序函数--C语言版
3203: 数组做函数参数----排序函数--C语言版 时间限制: 1 Sec 内存限制: 128 MB提交: 253 解决: 151[提交][状态][讨论版][命题人:smallgyy] 题目描 ...
- C++排序函数sort/qsort使用
问题描述: C++排序函数sort/qsort的使用 问题解决: (1)sort函数使用 注: sort函数,参数1为数组首地址,参数2是数组 ...
- C++ 排序函数 sort(),qsort()的使用方法
想起来自己天天排序排序,冒泡啊,二分查找啊,结果在STL中就自带了排序函数sort,qsort,总算把自己解脱了~ 所以自己总结了一下,首先看sort函数见下表: 函数名 功能描写叙述 sort 对给 ...
- linux makefile字符串操作函数 替换subst、模式替换patsubst、去首尾空格strip、查找字符串findstring、过滤filter、反过滤filter-out、排序函数sort、取单词word、取单词串wordlist、个数统计words
1.1 字符操作函数使用 在Makefile中可以使用函数来处理变量,从而让我们的命令或是规则更为的灵活和具有智能.make所支持的函数也不算很多,不过已经足够我们的操作了.函数调用后,函 ...
随机推荐
- 使用git提交时报错:error: RPC failed; HTTP 413 curl 22 The requested URL returned error: 413 Request Entity Too Large
Delta compression using up to 4 threads.Compressing objects: 100% (2364/2364), done.Writing objects: ...
- memcached--add使用
memcached是一种管理内存的软件,来动态的分配机器的内存,将需要存储的数据以key-value(键值对)的形式存储在内存中. 1.memcached使用的存储算法是hash算法在内存中存储字符串 ...
- WebGL 着色器偏导数dFdx和dFdy介绍
本文适合对webgl.计算机图形学.前端可视化感兴趣的读者. 偏导数函数(HLSL中的ddx和ddy,GLSL中的dFdx和dFdy)是片元着色器中的一个用于计算任何变量基于屏幕空间坐标的变化率的指令 ...
- 数据库root密码删除
1 打开mysql.exe和mysqld.exe所在的文件夹,复制路径地址 2 打开cmd命令提示符,进入上一步mysql.exe所在的文件夹. 3 输入命令 mysqld --skip-g ...
- Java的一些基础知识,现在回顾一下,毕竟学了那么久!
一.基础知识:1.什么是JVM.JRE和JDK的区别:JVM(Java Virtual Machine):java虚拟机,用于保证java的跨平台的特性,java语言是跨平台,jvm不是跨平台的,jv ...
- 5分钟快速部署PESCMS TEAM 团队任务管理系统开发版
所在的公司也经历过小团队的发展,为了高效率,通常都是面对面交流,很多时候事情谈论过后不久就已经淡忘了.而且工作任务不能全局观察,成员之间基本上都要主动去询问,效率反而低下.所以今天就介绍一款中小团队的 ...
- CodeForces 691D:Swaps in Permutation(并查集)
http://codeforces.com/contest/691/problem/D D. Swaps in Permutation You are given a permutation of ...
- Effective Java第三版(一) ——用静态工厂代替构造器
此文做为<Effective Java>系列的第一篇,所以有必要大概说下此书的特点,当然很多人可能都看过,毕竟是有着Java四大名著之一的大名在外,不过总会有萌新不了解,例如我!<E ...
- Jmeter接口测试实例-牛刀小试
本次测试的是基于HTTP协议的接口,主要是通过Jmeter来完成接口测试,借此熟悉Jmeter的基本操作. 本次实战,我是从网上找的接口测试项目,该项目提供了详细的接口文档,我们可以通过学习接口文档来 ...
- ~~Python文件简单操作~~
进击のpython Python文件操作 在说Python的文件操作之前 我们可以先思考一个问题 平时我们是怎么对电脑中的文件进行操作的呢? 打开电脑⇨找到文件⇨打开文件⇨读文件⇨修改文件⇨保存文件⇨ ...