chapter11_2 Lua链表与队列
链表
由于table是动态的实体,所以在Lua中实现链表是很方便的。每个节点以一个table来表示,一个“链表”只是节点table中的一个字段。
该字段包含了对其他table的引用。例如,要实现一个基础的列表,其中每个节点具有两个字段:next和value
创建一个链表:
list = nil
list = {next = list,value = v}
--遍历此链表
local l = list
while l do
<访问 l.value >
l = l.next
end
也可以参考之前的一篇文章:Chapter7 迭代器 中的 3、无状态的迭代器 里的例子,实现了链表的初始化和遍历。
至于其他类型的列表,例如双向链表或环形表,都可以使用相同的方法实现。
然而,在Lua中很少需要这类的结构,因为通常存在着一些更简单的方式来表示数据。
例如可以通过一个(几乎无限大的)数组来表示一个栈。
队列与双向队列
在Lua中实现队列的一种简单方法是使用table库的函数insert和remove。这两个函数可以在一个数组的任意位置插入或删除元素。
并且根据操作要求移动后续元素。对于较大的结构,移动的开销是很大的。
一个高效的实现是使用两个索引,分别用于首尾的两个元素:
function ListNew()
return {first = ,last = -}
end
为了避免污染全局名称空间,将在一个table内部定义所有的队列操作,这个table且称为List,将上例重写:
List = {}
function List.new()
return {first = ,last = -} --这里没有看懂,为什么这样初始化?是为了下面popfirst操作中的first>last 的判断 为false,表示空队列吗?以后再深入了解
end
现在可以在常量时间内完成在两端插入或删除元素了(以下函数有点像操作Lua栈,first索引表示栈底,last表示栈顶,先这样理解吧,以后弄明白了再回来修改):
function List.pushfirst(list , value)
local first = list.first - --从头push后,就要让头往下涨1
list.first = first --表示list["first"] = first
list[first] = value --表示first这个变量在表中的值,这两者容易搞混
end function List.pushlast(list, value)
local last = list.last + --push后,last就要往上增长1
list.last = last
list[last] = value
end function List.popfirst(list)
local first = list.first
if first > list.last then error("list is empty") end
local value = list[first]
list[first] = nil --允许垃圾回收
list.first = first + --弹出后,first就要往上加1
return value
end function List.poplast(list)
local last = list.last
if list.first > last then error("list is empty") end
local value = list[last]
list[last] = nil --允许垃圾回收
list.last = last - --弹出后,,last就要往下减1
return value
end
如果希望该结构能严格地遵循队列的操作规范,那么只调用pushlast和popfirst就可以了。
chapter11_2 Lua链表与队列的更多相关文章
- Java数据结构——用双端链表实现队列
//================================================= // File Name : LinkQueue_demo //---------------- ...
- Lua中实现队列(高效方式)
转自http://www.cnblogs.com/stephen-liu74/archive/2012/06/25/2417894.html 在Lua中实现队列的简单方法是使用table库函数inse ...
- 教你如何使用Java手写一个基于链表的队列
在上一篇博客[教你如何使用Java手写一个基于数组的队列]中已经介绍了队列,以及Java语言中对队列的实现,对队列不是很了解的可以我上一篇文章.那么,现在就直接进入主题吧. 这篇博客主要讲解的是如何使 ...
- 利用 C++ 单向链表实现队列
利用C++ 单向链表实现数据结构队列,其实和上一篇基本内容相同,仅仅是插入的时候在链表的尾部插入,取元素都是一样的,都从头部取. #pragma once #include "stdio.h ...
- 队列queue(2):链表实现队列
基本概念 队列是只允许在一端进行插入操作,另一端进行删除操作的线性表. 我们规定,允许删除的叫做队首"head",允许插入的叫做队尾"tail". 基本操作 我 ...
- Java之使用链表实现队列
import java.util.Iterator; import java.util.NoSuchElementException; /** * 使用链表来实现队列 * 1.考虑结点的结构,包括当前 ...
- 并发编程-concurrent指南-阻塞队列-链表阻塞队列LinkedBlockingQueue
LinkedBlockingQueue是一个基于链表的阻塞队列. 由于LinkedBlockingQueue实现是线程安全的,实现了先进先出等特性,是作为生产者消费者的首选. LinkedBlocki ...
- 使用python实现数组、链表、队列、栈
引言 什么是数据结构? 数据结构是指相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成. 简单来说,数据结构就是设计数据以何种方式组织并存储在计算机中. 比如:列表,集合和字 ...
- 链表实现队列(python)
# -*- coding: utf-8 -*- from collections import deque class Node(object): def __init__(self, value=N ...
随机推荐
- DHCP源码分析--主流程
DHCP 服务器,客户端代码都采用了统一的事件轮询(event loop),包含了任务处理消息,定时器消息,socke收发消息等等. static struct { isc_appmethods_t ...
- img 转化成iso镜像的办法
最近在使用KVM启用虚拟机,然后将里面的环境和配置 配置成我们公司需要的环境,再打包成iso镜像,之后再次生成新的虚拟机. 但是KVM启动出的镜像生成的是img镜像 ,需要将img镜像转换成iso镜像 ...
- es5 中类的2种基本实现方法
function test(){ this.a = 1; this.func = function(){ // var a = 3;下面的this 取的是上面的1,这个不影响 return this. ...
- [SQL基础教程] 2-1 SELECT语句基础
[SQL基础教程] 2-1 SELECT语句基础 列的查询 Syntax SELECT<列名>,..... FROM<表名>; SELECT col_1, col_2 FROM ...
- mysql中datetime和timestamp的区别
原文地址:http://database.51cto.com/art/200905/124240.htm 相同 显示 TIMESTAMP列的显示格式与DATETIME列相同.换句话说,显示宽度固定在1 ...
- MySQL数据库安装(CentOS操作系统/tar.gz方式)
1. 上传Mysql安装包“mysql-5.5.40-linux2.6-x86_64.tar.gz”到部署机,位置任意: 2. 将Mysql安装包解压到其所在目录,命令如下: -linux2.-x86 ...
- HDU 5795 A Simple Nim(SG打表找规律)
SG打表找规律 HDU 5795 题目连接 #include<iostream> #include<cstdio> #include<cmath> #include ...
- Cocoapod安装使用和常见问题(转载)
1.cocoapod的按照,cocoapod是运行在ruby环境下的,在ruby环境的 ,像cocoapod这样的开源项目时放在放在rubygems服务器上面的,但国内访问https://ruby ...
- PEiD 0.95 全插件中文绿色版
软件名称: PEiD 0.95 软件语言: 简体中文 授权方式: 免费软件 运行环境: Win8 / Win7 / Vista / WinXP 软件大小: 4.4MB 图片预览: 软件简介: PEiD ...
- js获取计算的样式(非行间样式)
function getStyle(obj, attr){ if(obj.currentStyle){ style = obj.currentStyle[attr]; //兼容IE8以下 }else{ ...