跳表java代码解释 跳表 java

跳跃表(SkipList)

跳跃表是一种基于有序链表的拓展,简称跳表。

创新互联坚持“要么做到,要么别承诺”的工作理念,服务领域包括:网站设计制作、成都做网站、企业官网、英文网站、手机端网站、网站推广等服务,满足客户于互联网时代的朝阳县网站设计、移动媒体设计的需求,帮助企业找到有效的互联网解决方案。努力成为您成熟可靠的网络建设合作伙伴!

下面正式开始了哦,跟着思路来,非常简单理解:

给定一个有序链表:

1-2-3-5-6-7-8

跳表的思想就是利用了类似索引的思想,提取出链表中的部分关键节点,然后再用二分查找。

上面的有序链表,把奇数作为关键节点提取出来:

上面只是介绍了基本思想,其实还可以继续优化,看到这别担心,难度不会增加,也非常好理解:

既然上面提取了一层节点作为索引,那是不是也可以进一步提取?

有了2级索引后,插入的节点可以先和2级索引比较,确定大体范围;然后再和1级索引比较;最后再回到原链表,找到并插入对应的位置。

节点多的时候还可以进一步提取,保证每一层是上一层节点的一半。提取的极限是同一层只有两个节点的时候,因为一个节点比较没有意义。

到这里,多层链表结构就提取完了,这就是跳跃表。

当大量新节点通过逐层比较插入到链表中后,上层节点就会显得不够用,这就需要从新节点中“提拔”一部分节点到上一层,问题就是“提拔”谁呢(如何选择索引)?

跳表设计者采用了“抛硬币”的方法,随机决定新节点是否提拔。因为跳表的添加和删除的节点是不可预测的,很难用算法保证跳表的索引分布始终均匀。虽然抛硬币的方式不能保证绝对均匀,但大体上是趋于均匀的。

比如说,9插入到链表后,开始分析:

跳跃表插入操作的时间复杂度是O(logN),而这种数据结构所占空间是2N,既空间复杂度是 O(N)。

删除的时候只要在索引层找到要删除的节点,然后删除每一层相同的节点即可。如果某一层删到只剩下一个,那么整层都可以删掉。比如删除5:

跳跃表删除操作的时间复杂度是O(logN)。

跳表维持结构平衡的成本较低,完全靠随机。二叉查找树在多次插入和删除后需要重新保持自平衡。

Redis的五种数据类型之一Sorted-set(zset)这种有序集合,正是对于跳跃表的改进和应用。

还有Java中的ConcurrentSkipListMap和ConcurrentSkipListSet内部都是用跳表的数据结构。

请问如何解释清楚下面的Java代码?

主要实现的是登录验证的过程

首先传入账户名和密码

然后executeQuery查表,就是查和传入的账户名一样的有几条记录

接着if(rs.next())判断(这里有BUG的,因为有可能存在重名的问题,不过这里暂且认为表中名字是唯一的)

如果有查询到的记录,就将表中字段的内容取出来进行赋值

然后temp=1我猜作用应该是标识位,

1标识找到了,也就是账号密码没错

2是找不到,登录密码出错

3表示用户名输错

当密码相同的时候,将其表中字段内容取出来放到arraylist中供后续使用操作

return temp;就是用来返回登录状态的,可以通过判断temp为几知道哪里出错(不过这里只是返回没有做后续处理)

java代码解读

第一个if是判断searchkey是不是空的,如果不是空的,就追加到name字段作为查询条件,like模糊查询

接着第二个if判断如果status的值不为空,就追加到status作为条件

如果status为空,走else分支,从userContext中获取到employee对象,接着判断,如果它的角色不是manager的话

把这个对象的id拿出来,作为seller.Id的条件进行查询

求高手跟我解释下 下面JAVA代码每句代码的意思

就从denglu(...)方法开始讲了,这个方法在声明的时候标识了会throws Exception,表示这个方法中的某些代码可能会抛出异常。

UserDenglu resultUser = null; 构造一个名叫 UserDenglu的类的对象 resultUser,值为null表示没有实例化(只是声明了一个模型,没有在内存中占用位置)。

String sql = ... 这名是定义一个字符串变量,它的值是一个sql语句;语句的意思是: 查询t_denglu表中字段userName值(?为暂留空,后面填)并且password值为(?为暂留空,后面填);

PreparedStatement pstmt = con.prepareStatement(sql); 将sql语句传给con对象(数据库连接对象)的prepareStatement方法得到返回值为 pstmt对象;

pstmt.setString(1, user.getUserName()); 把sql语句中的第一个?参数替换成 user.getUserName()方法的返回值;

pstmt.setString(2, user.getPassword()); 意义与上句类同,替换第二个?参数。

ResultSet rs = pstmt.executeQuery(); 执行数据库查询语句,将查询结果放入rs对象中;

if(rs.next()) 如果rs结果集中还有下一条的话

resultUser = new UserDenglu(); 实例化resultUser对象;

resultUser.setUserName(rs.getString("username"));将数据库结果集中查询到的列名为username的列的值传入 resultUser.setUserName()方法中;

resultUser.setPassword(rs.getString("password"));与上句类同,将password列的值传入到resultUser的setPassword()方法中。

========================================================

这个做的是用户登录功能,该方法中接收一个包含用户输入的用户名和密码的UserDenglu对象,然后用它们来查询数据库中是否有对应用户名和密码对的结果,如果有的话,就登录成功,如果没有,就登录失败。登录失败,该方法返回的是null,如果登录成功,返回的是一个包含数据库中查询出来的用户名和密码的UserDenglu对象。调用这个方法时,可以判断它返回值是否为null来判断是否登录成功(用户名和密码正确)。

java代码解析

一楼的说的够全面了,不过稍有误解.

再来表示抱歉,我对编程语言中的中文名词非常不了解,所以如果以下的回复对你的阅读或者理解造成困难,请见谅.

1.首先,要明白这个问题的答案,需要了解call (pass) by value 和 call (pass) by reference 的区别.简单来说:

call by value通常是复制这个parameter的值去另外一块内存里,然后传给function, 所以在method/function里边对这个变量的所有变更,实际上都是对复制过来的镜像进行操作,不会对原本的variable有任何影响.

call by reference是将parameter的reference传给function,简单点理解就是直接把variable传给function.所以说这个variable的值是可以被function改变的.这个用法在c/c++中非常常见,用法是variable_name.

2.再来,在Java里边,你可以很简单的理解为: Java中只有call by value, 也就是说,所以所有传给function的parameter本身都不会被改变. (这是最简单直白的理解,当然也有另一种常从sun的人那边听到的说法:Java是call by value + call by reference by value)

3.那么现在的问题就是为什么第二个结果是2了. 首先说一下sun官方的解释: 对于reference type在作为parameter/argument的时候,也是call by value, 但是在你拥有足够权限时(比方说那个变量是public的, 不是final的等等各种符合的情况),可以修改这个object中fields的值(也就是属于这个object(严谨点讲是an instance of the object) 内部的变量, 在你的例子中, ko 里边的 a 就是一个field, 所以update(ko)会使ko.a变成2).

4.如果你是一个有过c/c++学习经验的人或者你以上的解释很难理解,以下这种说法或许更适合你 (当然了,这只是大多包括我在内有c经验的人的一种理解方式)

这里可以引入一个新的概念,pointer. 这是一种比较特殊的变量,它内部所储存的东西,其实只是另外一个变量的内存地址. 如果对内存没有概念,你可以把它简单理解为是风筝的线轴,虽然看它本身看不出什么端倪,但是顺着摸过去总会找到风筝,看到它是什么样子. 以pointer方式理解Java的人,通常会说: Type variable = new Type(); 这个过程中,最后生成的这个variable其实就是一个pointer,而不是instance本身.

在Java中, 有c/c++经验的人通常认为Java是call by value.同时,当一个变量用在储存reference type的时候,实际上储存的是它的pointer,这也一样可以解释为什么ko.a会有2这个结果,因为虽然pointer被传到function里边时,本身是call by value,无法被改变.但这并不影响function本身对这个pointer指向的object的内容做任何改变. 当然,再次声明,这只是一种帮助有c/c++经验的人理解的方法. Sun本身严正声明Java里边没有pointer这个东西的存在.

5. 再来解释一下为什么说楼上所说的(或者说楼上引用的)理解略有偏差.

引用"我们上面刚学习了JAVA的数据类型,则有:值类型就是按值传递的,而引用类型是按引用传递的" 这句话很明显的有两点错误. 第一点,如果我上面所说的,Java是没有call by reference的.

第二点,暂且假设Java里边是有call by reference的, 这句话依然不成立.

Java中的变量有两种类型: primitive types 和 reference type.

primitive type包括byte, short, int, long, char, boolean, float和double.

而这8种之外的所有的,都是reference type.

下面是一段对你的贴上来的code的一点延伸,希望可以帮助你更好的理解Java中的argument / parameter到底是如何运作的.

public class Test {

public static void main(String[] args) {

int a = 1;

Koo koo = new Koo();

Object o = new Integer(1);

Koo newKoo = new Koo();

update(a);

update(koo);

update(o);

update(newKoo);

newUpdate(newKoo);

System.out.println(a);

System.out.println(koo.a);

System.out.println(o);

System.out.println(newKoo.a);

}

static void update(int a) {

a++;

}

static void update(Koo koo) {

koo.a++;

}

static void update(Object o) {

o = (int) (Integer.parseInt(o.toString()) + 1);

}

static void newUpdate(Koo koo) {

koo = new Koo();

}

}

class Koo {

int a = 1;

}

/*

o = (int) (Integer.parseInt(o.toString()) + 1); 这一行中的(int)纯粹是多余的,是否有这个casting对code本身没有任何影响. 如果你高兴也可以用

o = new Integer(Integer.parseInt(o.toString()) + 1);

或者干脆

o = Integer.parseInt(o.toString()) + 1;

*/

以上这些code运行之后会得到1 2 1 2的结果. 后面两个结果可以很好的说明, 即使对objects (reference type variables) 来看, Java所应用的也并不是call by reference. 否则的话,以上code运行结果应该是1 2 2 1

希望你可以真正理解这个新的例子中,产生1212这个结果的原因,从而对Java中的arguments有一个系统全面的认识.

图片是相关资料的链接,知道里貌似不能加网址


新闻名称:跳表java代码解释 跳表 java
分享链接:http://azwzsj.com/article/hggodp.html