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. 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 ...

  2. C语言通用双向循环链表操作函数集

    说明 相比Linux内核链表宿主结构可有多个链表结构的优点,本函数集侧重封装性和易用性,而灵活性和效率有所降低.     可基于该函数集方便地构造栈或队列集.     本函数集暂未考虑并发保护. 一  ...

  3. 【C语言教程】“双向循环链表”学习总结和C语言代码实现!

    双向循环链表 定义 双向循环链表和它名字的表意一样,就是把双向链表的两头连接,使其成为了一个环状链表.只需要将表中最后一个节点的next指针指向头节点,头节点的prior指针指向尾节点,链表就能成环儿 ...

  4. GO语言学习——切片三 append()方法为切片添加元素、切片的扩容策略、使用copy()函数复制切片、从切片中删除元素

    append()方法为切片添加元素 注意:通过var声明的零值切片可以在append()函数直接使用,无需初始化. var s []int s = append(s, 1, 2, 3) append( ...

  5. 3204: 数组做函数参数--排序函数2--C语言

    3204: 数组做函数参数--排序函数2--C语言 时间限制: 1 Sec  内存限制: 128 MB提交: 211  解决: 143[提交][状态][讨论版][命题人:smallgyy] 题目描述 ...

  6. 3203 数组做函数参数----排序函数--C语言版

    3203: 数组做函数参数----排序函数--C语言版 时间限制: 1 Sec  内存限制: 128 MB提交: 253  解决: 151[提交][状态][讨论版][命题人:smallgyy] 题目描 ...

  7. C++排序函数sort/qsort使用

    问题描述:        C++排序函数sort/qsort的使用 问题解决:           (1)sort函数使用   注:           sort函数,参数1为数组首地址,参数2是数组 ...

  8. C++ 排序函数 sort(),qsort()的使用方法

    想起来自己天天排序排序,冒泡啊,二分查找啊,结果在STL中就自带了排序函数sort,qsort,总算把自己解脱了~ 所以自己总结了一下,首先看sort函数见下表: 函数名 功能描写叙述 sort 对给 ...

  9. linux makefile字符串操作函数 替换subst、模式替换patsubst、去首尾空格strip、查找字符串findstring、过滤filter、反过滤filter-out、排序函数sort、取单词word、取单词串wordlist、个数统计words

    1.1       字符操作函数使用 在Makefile中可以使用函数来处理变量,从而让我们的命令或是规则更为的灵活和具有智能.make所支持的函数也不算很多,不过已经足够我们的操作了.函数调用后,函 ...

随机推荐

  1. HTML连载19-子元素选择器&交集选择器

    一.子元素选择器 1.定义:找到指定标签中所有特定的直接子元素,然后设置属性 2.格式: 标签名称一>标签名称2{ 属性:值: } 3.释义:先找到叫做“标签名称1”的标签,然后在这个标签中查找 ...

  2. 【Linux】一步一步学Linux——VMware虚拟机三种网络模式详解(07)

    目录 00. 目录 01. 虚拟网络连接组件 02. 常见网络连接配置 03. 桥接模式 04. NAT 模式 05. 仅主机模式 06. 自定义模式 07. 附录 00. 目录 @ 01. 虚拟网络 ...

  3. 并发编程-concurrent指南-阻塞队列-优先级的阻塞队列PriorityBlockingQueue

    PriorityBlockingQueue是一个支持优先级的无界阻塞队列. 它使用了和类 java.util.PriorityQueue 一样的排序规则.你无法向这个队列中插入 null 值. 所有插 ...

  4. 003-python基础-字符类型

    基本数据类型(int,bool,str) 1.基本数据数据类型: int 整数 str 字符串. 一般不存放大量的数据 bool 布尔值. 用来判断. True, False list 列表.用来存放 ...

  5. HDU 6043:Colorful Tree(树上统计所有路径总颜色数)***

    题目链接 题意 给出一棵有n个结点的树,每个结点有一个颜色,问在这棵树的所有路径中,每条路径的颜色数求和是多少. 思路 求每种颜色的贡献可以转化为总的和减去每种颜色在哪些路径上没有出现的贡献,一个颜色 ...

  6. SCUT 125 :笔芯回文(DP)

    https://scut.online/p/125 125. 笔芯回文 题目描述 bxbx有一个长度一个字符串SS,bxbx可以对其进行若干次操作. 每次操作可以删掉一个长度为k(1 \leq k \ ...

  7. Linux环境下虚拟环境virtualenv安装和使用(转)

    virtualenv用于创建独立的Python环境,多个Python相互独立,互不影响,它能够: 1. 在没有权限的情况下安装新套件 2. 不同应用可以使用不同的套件版本 3. 套件升级不影响其他应用 ...

  8. 单个单选框radio 点击选中点击取消选中

    $("input:radio").click(function(){ var domName = $(this).attr('name');//获取当前单选框控件name 属性值 ...

  9. 使用OpenAPI构建更智能的API

    像OpenAPI这样的API描述规范是一个关键工具,您应该尽可能地将其好好掌握,记录和执行API的工作由计算机和开发人员完成:OpenAPI 3.0现在允许额外的表现力,可以让机器为我们做更多有用的工 ...

  10. 跨站脚本攻击(存储型xss)笔记(二)

    测试目标字段:页面下方的红色框位置. 由于编辑状态是编辑器,所以有可能出现跨站! 我插了个input然而并没有当代码执行 可能有些测试人员就认为被过滤掉了,因为尝试了各种尖括号.js事件.转义.编码等 ...