﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-JAVA-文章分类-算法/数据结构</title><link>http://www.blogjava.net/zzzlyr/category/55177.html</link><description /><language>zh-cn</language><lastBuildDate>Sat, 06 Jan 2018 16:56:56 GMT</lastBuildDate><pubDate>Sat, 06 Jan 2018 16:56:56 GMT</pubDate><ttl>60</ttl><item><title>JAVA 实现链表队列</title><link>http://www.blogjava.net/zzzlyr/articles/432415.html</link><dc:creator>张钊钊</dc:creator><author>张钊钊</author><pubDate>Tue, 28 Mar 2017 07:48:00 GMT</pubDate><guid>http://www.blogjava.net/zzzlyr/articles/432415.html</guid><wfw:comment>http://www.blogjava.net/zzzlyr/comments/432415.html</wfw:comment><comments>http://www.blogjava.net/zzzlyr/articles/432415.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zzzlyr/comments/commentRss/432415.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zzzlyr/services/trackbacks/432415.html</trackback:ping><description><![CDATA[<pre style="font-family: Consolas; font-size: 14.3pt; background-color: #ffffff;"><span style="color:#000080;font-weight:bold;">package </span>stacktest;<br /><br /><span style="color:#808080;font-style:italic;">/**<br /></span><span style="color:#808080;font-style:italic;"> * </span><span style="color:#808080;font-weight:bold;font-style:italic;">@Author: </span><span style="color:#808080;font-style:italic;">zzz<br /></span><span style="color:#808080;font-style:italic;"> * </span><span style="color:#808080;font-weight:bold;font-style:italic;">@CreateTime: </span><span style="color:#808080;font-style:italic;">2017/3/28 10:52<br /></span><span style="color:#808080;font-style:italic;"> * </span><span style="color:#808080;font-weight:bold;font-style:italic;">@Description: </span><span style="color:#808080;font-style:italic;font-family:'宋体';">队列特点（先进先出），链表实现的队列 在队头删除元素，在队尾插入元素。<br /></span> <span style="color:#808080;font-style:italic;">* </span><span style="color:#808080;font-style:italic;font-family:'宋体';">这样才能满足队列的特性。<br /></span> <span style="color:#808080;font-style:italic;">*/<br /></span><span style="color:#000080;font-weight:bold;">public class </span>MyQueue&lt;<span style="color:#20999d;">T</span>&gt; {<br />    <span style="color:#000080;font-weight:bold;">private </span>Node&lt;<span style="color:#20999d;">T</span>&gt; <span style="color:#660e7a;font-weight:bold;">front</span>; <span style="color:#808080;font-style:italic;">//</span><span style="color:#808080;font-style:italic;font-family:'宋体';">队列头，只能删除元素<br /></span><span style="color:#808080;font-style:italic;font-family:'宋体';"><br /></span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#000080;font-weight:bold;">private </span>Node&lt;<span style="color:#20999d;">T</span>&gt; <span style="color:#660e7a;font-weight:bold;">rear</span>; <span style="color:#808080;font-style:italic;">//</span><span style="color:#808080;font-style:italic;font-family:'宋体';">队列尾，只能用来插入入元素<br /></span><span style="color:#808080;font-style:italic;font-family:'宋体';"><br /></span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#000080;font-weight:bold;">private int </span><span style="color:#660e7a;font-weight:bold;">size</span>;<span style="color:#808080;font-style:italic;">//</span><span style="color:#808080;font-style:italic;font-family:'宋体';">队列的长度<br /></span><span style="color:#808080;font-style:italic;font-family:'宋体';"><br /></span> <span style="color:#808080;font-style:italic;">/**<br /></span><span style="color:#808080;font-style:italic;">     * </span><span style="color:#808080;font-style:italic;font-family:'宋体';">初始化队列<br /></span> <span style="color:#808080;font-style:italic;">*/<br /></span> <span style="color:#000080;font-weight:bold;">public </span>MyQueue() {<br />        <span style="color:#660e7a;font-weight:bold;">front </span>= <span style="color:#000080;font-weight:bold;">new </span>Node&lt;<span style="color:#20999d;">T</span>&gt;();<br />        <span style="color:#660e7a;font-weight:bold;">rear </span>= <span style="color:#660e7a;font-weight:bold;">front</span>;<br />    }<br /><br />    <span style="color:#808080;font-style:italic;">/**<br /></span><span style="color:#808080;font-style:italic;">     * </span><span style="color:#808080;font-style:italic;font-family:'宋体';">链表的数据结构<br /></span> <span style="color:#808080;font-style:italic;">*/<br /></span> <span style="color:#000080;font-weight:bold;">private class </span>Node&lt;<span style="color:#20999d;">T</span>&gt; {<br />        <span style="color:#000080;font-weight:bold;">public </span><span style="color:#20999d;">T </span><span style="color:#660e7a;font-weight:bold;">data</span>;<br />        <span style="color:#000080;font-weight:bold;">public </span>Node&lt;<span style="color:#20999d;">T</span>&gt; <span style="color:#660e7a;font-weight:bold;">next</span>;<br /><br />        <span style="color:#000080;font-weight:bold;">public </span>Node(<span style="color:#20999d;">T </span>data, Node next) {<br />            <span style="color:#000080;font-weight:bold;">this</span>.<span style="color:#660e7a;font-weight:bold;">data </span>= data;<br />            <span style="color:#000080;font-weight:bold;">this</span>.<span style="color:#660e7a;font-weight:bold;">next </span>= next;<br />        }<br /><br />        <span style="color:#000080;font-weight:bold;">public </span>Node(<span style="color:#20999d;">T </span>data) {<br />            <span style="color:#000080;font-weight:bold;">this</span>.<span style="color:#660e7a;font-weight:bold;">data </span>= data;<br />        }<br /><br />        <span style="color:#000080;font-weight:bold;">public </span>Node() {<br />        }<br />    }<br /><br />    <span style="color:#000080;font-weight:bold;">public void </span>add(<span style="color:#20999d;">T </span>data) {<br />        <span style="color:#808080;font-style:italic;">//</span><span style="color:#808080;font-style:italic;font-family:'宋体';">新插入的节点永远是尾节点，它的</span><span style="color:#808080;font-style:italic;">next </span><span style="color:#808080;font-style:italic;font-family:'宋体';">指向</span><span style="color:#808080;font-style:italic;">null(</span><span style="color:#808080;font-style:italic;font-family:'宋体';">即没有后继节点</span><span style="color:#808080;font-style:italic;">)<br /></span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Node newNode = <span style="color:#000080;font-weight:bold;">new </span>Node(data, <span style="color:#000080;font-weight:bold;">null</span>);<br />        <span style="color:#808080;font-style:italic;">//</span><span style="color:#808080;font-style:italic;font-family:'宋体';">让尾节点</span><span style="color:#808080;font-style:italic;">next</span><span style="color:#808080;font-style:italic;font-family:'宋体';">指向新节点<br /></span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#660e7a;font-weight:bold;">rear</span>.<span style="color:#660e7a;font-weight:bold;">next </span>= newNode;<br />        <span style="color:#660e7a;font-weight:bold;">rear </span>= newNode;<br />        <span style="color:#660e7a;font-weight:bold;">size</span>++;<br />    }<br /><br />    <span style="color:#000080;font-weight:bold;">public </span><span style="color:#20999d;">T </span>pop() <span style="color:#000080;font-weight:bold;">throws </span>Exception {<br />        <span style="color:#000080;font-weight:bold;">if </span>(<span style="color:#660e7a;font-weight:bold;">size </span>&lt; <span style="color:#0000ff;">1</span>) {<br />            <span style="color:#000080;font-weight:bold;">throw new </span>Exception(<span style="color:#008000;font-weight:bold;">"</span><span style="color:#008000;font-weight:bold;font-family:'宋体';">错误，队列为空。</span><span style="color:#008000;font-weight:bold;">"</span>);<br />        }<br />        Node&lt;<span style="color:#20999d;">T</span>&gt; nextNode = <span style="color:#660e7a;font-weight:bold;">front</span>.<span style="color:#660e7a;font-weight:bold;">next</span>;<br /><br />        <span style="color:#660e7a;font-weight:bold;">front</span>.<span style="color:#660e7a;font-weight:bold;">next </span>= nextNode.<span style="color:#660e7a;font-weight:bold;">next</span>;<br />        <span style="color:#660e7a;font-weight:bold;">size</span>--;<br />        <span style="color:#000080;font-weight:bold;">if </span>(<span style="color:#660e7a;font-weight:bold;">size </span>&lt; <span style="color:#0000ff;">1</span>) {<br />            <span style="color:#660e7a;font-weight:bold;">rear </span>= <span style="color:#660e7a;font-weight:bold;">front</span>;<br />            <span style="color:#660e7a;font-weight:bold;">size </span>= <span style="color:#0000ff;">0</span>;<br />        }<br />        <span style="color:#000080;font-weight:bold;">return </span>nextNode.<span style="color:#660e7a;font-weight:bold;">data</span>;<br /><br />    }<br /><br />    <span style="color:#808080;font-style:italic;">//</span><span style="color:#808080;font-style:italic;font-family:'宋体';">取队首元素<br /></span><span style="color:#808080;font-style:italic;font-family:'宋体';"><br /></span> <span style="color:#000080;font-weight:bold;">public </span><span style="color:#20999d;">T </span>peek() <span style="color:#000080;font-weight:bold;">throws </span>Exception {<br />        <span style="color:#000080;font-weight:bold;">if </span>(<span style="color:#660e7a;font-weight:bold;">size </span>&lt; <span style="color:#0000ff;">1</span>){<br />            <span style="color:#000080;font-weight:bold;">throw new </span>Exception(<span style="color:#008000;font-weight:bold;">"</span><span style="color:#008000;font-weight:bold;font-family:'宋体';">错误，队列为空。</span><span style="color:#008000;font-weight:bold;">"</span>);<br />        };<br />        <span style="color:#000080;font-weight:bold;">return </span><span style="color:#660e7a;font-weight:bold;">front</span>.<span style="color:#660e7a;font-weight:bold;">next</span>.<span style="color:#660e7a;font-weight:bold;">data</span>;<br /><br />    }<br />    <span style="color:#808080;font-style:italic;">//</span><span style="color:#808080;font-style:italic;font-family:'宋体';">返回队列的大小<br /></span> <span style="color:#000080;font-weight:bold;">public int </span>getSize() {<br />        <span style="color:#000080;font-weight:bold;">return </span><span style="color:#660e7a;font-weight:bold;">size</span>;<br />    }<br /><br />    <span style="color:#808080;font-style:italic;">//</span><span style="color:#808080;font-style:italic;font-family:'宋体';">判断队列是否为空<br /></span> <span style="color:#000080;font-weight:bold;">public boolean </span>isEmpty() {<br />        <span style="color:#000080;font-weight:bold;">return </span><span style="color:#660e7a;font-weight:bold;">size </span>== <span style="color:#0000ff;">0</span>;<br />    }<br /><br />    <span style="color:#808080;font-style:italic;">/**<br /></span><span style="color:#808080;font-style:italic;">     * </span><span style="color:#808080;font-style:italic;font-family:'宋体';">遍历算法，移动</span><span style="color:#808080;font-style:italic;">front</span><span style="color:#808080;font-style:italic;font-family:'宋体';">指针，直到</span><span style="color:#808080;font-style:italic;">front</span><span style="color:#808080;font-style:italic;font-family:'宋体';">指针追上</span><span style="color:#808080;font-style:italic;">rear</span><span style="color:#808080;font-style:italic;font-family:'宋体';">指针<br /></span> <span style="color:#808080;font-style:italic;">*/<br /></span> <span style="color:#000080;font-weight:bold;">public void   </span>traverse(){<br />        <span style="color:#000080;font-weight:bold;">for</span>(Node currentNode=<span style="color:#660e7a;font-weight:bold;">front</span>.<span style="color:#660e7a;font-weight:bold;">next</span>; currentNode!=<span style="color:#000080;font-weight:bold;">null</span>; currentNode=currentNode.<span style="color:#660e7a;font-weight:bold;">next  </span>){<br />            System.<span style="color:#660e7a;font-weight:bold;font-style:italic;">out</span>.println(currentNode.<span style="color:#660e7a;font-weight:bold;">data</span>);<br />        }<br />    }<br /><br />    <span style="color:#000080;font-weight:bold;">public static void </span>main(String[] args)<span style="color:#000080;font-weight:bold;">throws </span>Exception{<br />        MyQueue&lt;String&gt; queue=<span style="color:#000080;font-weight:bold;">new </span>MyQueue&lt;&gt;();<br />        <span style="color:#000080;font-weight:bold;">for</span>(<span style="color:#000080;font-weight:bold;">int </span>i=<span style="color:#0000ff;">0</span>;i&lt;<span style="color:#0000ff;">10</span>;i++){<br />            queue.add(<span style="color:#008000;font-weight:bold;">"88888-"</span>+i);<br />        }<br /><br />       <span style="color:#808080;font-style:italic;">/* for(int i=0;i&lt;10;i++){<br /></span><span style="color:#808080;font-style:italic;">            String s=queue.pop();<br /></span><span style="color:#808080;font-style:italic;">            System.out.print(s+";");<br /></span><span style="color:#808080;font-style:italic;">        }*/<br /></span> queue.traverse();<br /><br />    }<br />}<br /></pre><img src ="http://www.blogjava.net/zzzlyr/aggbug/432415.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zzzlyr/" target="_blank">张钊钊</a> 2017-03-28 15:48 <a href="http://www.blogjava.net/zzzlyr/articles/432415.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA 栈(链表和数组实现的栈操作) pop push </title><link>http://www.blogjava.net/zzzlyr/articles/432414.html</link><dc:creator>张钊钊</dc:creator><author>张钊钊</author><pubDate>Mon, 27 Mar 2017 07:43:00 GMT</pubDate><guid>http://www.blogjava.net/zzzlyr/articles/432414.html</guid><wfw:comment>http://www.blogjava.net/zzzlyr/comments/432414.html</wfw:comment><comments>http://www.blogjava.net/zzzlyr/articles/432414.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zzzlyr/comments/commentRss/432414.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zzzlyr/services/trackbacks/432414.html</trackback:ping><description><![CDATA[<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--></div><pre style="font-family: Consolas; font-size: 14.3pt; background-color: #ffffff;"><span style="color: #808080; font-style: italic;">栈的特点：后进先出，所以一个线性链表实现的栈也只能在一端操作才能满足这种特性；<br /><br /><br />/**<br /></span><span style="color:#808080;font-style:italic;"> * </span><span style="color:#808080;font-weight:bold;font-style:italic;">@Author: </span><span style="color:#808080;font-style:italic;">zzz<br /></span><span style="color:#808080;font-style:italic;"> * </span><span style="color:#808080;font-weight:bold;font-style:italic;">@CreateTime: </span><span style="color:#808080;font-style:italic;">2017/3/27 14:51<br /></span><span style="color:#808080;font-style:italic;"> * </span><span style="color:#808080;font-weight:bold;font-style:italic;">@Description:<br /></span> <span style="color:#808080;font-style:italic;">*/<br /></span><span style="color:#000080;font-weight:bold;">public class </span>MyStack&lt;<span style="color:#20999d;">T</span>&gt; {<br /><br />    <span style="color:#000080;font-weight:bold;">private </span>Node <span style="color:#660e7a;font-weight:bold;">top</span>;<span style="color:#808080;font-style:italic;">//</span><span style="color:#808080;font-style:italic;font-family:'宋体';">永远指向栈顶元素<br /></span> <span style="color:#808080;font-style:italic;">//</span><span style="color:#808080;font-style:italic;font-family:'宋体';">元素个数<br /></span> <span style="color:#000080;font-weight:bold;">private int </span><span style="color:#660e7a;font-weight:bold;">size</span>;<br /><br /><br />    <span style="color:#808080;font-style:italic;">/**<br /></span><span style="color:#808080;font-style:italic;">     * </span><span style="color:#808080;font-style:italic;font-family:'宋体';">内部类，定义节点<br /></span> <span style="color:#808080;font-style:italic;">*/<br /></span> <span style="color:#000080;font-weight:bold;">private class </span>Node {<br />        <span style="color:#000080;font-weight:bold;">public </span><span style="color:#20999d;">T </span><span style="color:#660e7a;font-weight:bold;">data</span>;<br /><br />        <span style="color:#000080;font-weight:bold;">public </span>Node <span style="color:#660e7a;font-weight:bold;">next</span>;<br /><br />        <span style="color:#000080;font-weight:bold;">public </span>Node(<span style="color:#20999d;">T </span>data, Node next) {<br />            <span style="color:#000080;font-weight:bold;">this</span>.<span style="color:#660e7a;font-weight:bold;">data </span>= data;<br />            <span style="color:#000080;font-weight:bold;">this</span>.<span style="color:#660e7a;font-weight:bold;">next </span>= next;<br />        }<br /><br />    }<br /><br />    <span style="color:#000080;font-weight:bold;">public void </span>push(<span style="color:#20999d;">T </span>data) {<br />        <span style="color:#808080;font-style:italic;">//next </span><span style="color:#808080;font-style:italic;font-family:'宋体';">指向当前元素</span><span style="color:#808080;font-style:italic;">top,</span><span style="color:#808080;font-style:italic;font-family:'宋体';">如果是第一个元素</span><span style="color:#808080;font-style:italic;">next </span><span style="color:#808080;font-style:italic;font-family:'宋体';">指向</span><span style="color:#808080;font-style:italic;">null;<br /></span> Node node = <span style="color:#000080;font-weight:bold;">new </span>Node(data, <span style="color:#660e7a;font-weight:bold;">top</span>);<br />        <span style="color:#808080;font-style:italic;">//</span><span style="color:#808080;font-style:italic;font-family:'宋体';">把当前元素指向</span><span style="color:#808080;font-style:italic;">top<br /></span> <span style="color:#660e7a;font-weight:bold;">top </span>= node;<br />        <span style="color:#660e7a;font-weight:bold;">size</span>++;<br />    }<br /><br /><br />    <span style="color:#000080;font-weight:bold;">public </span><span style="color:#20999d;">T </span>pop() {<br />        Node oldNode = <span style="color:#660e7a;font-weight:bold;">top</span>;<br />        <span style="color:#660e7a;font-weight:bold;">top </span>= <span style="color:#660e7a;font-weight:bold;">top</span>.<span style="color:#660e7a;font-weight:bold;">next</span>;<br />        oldNode.<span style="color:#660e7a;font-weight:bold;">next </span>= <span style="color:#000080;font-weight:bold;">null</span>;<br />        <span style="color:#808080;font-style:italic;">//</span><span style="color:#808080;font-style:italic;font-family:'宋体';">释放引用<br /></span> <span style="color:#000080;font-weight:bold;">return </span>oldNode.<span style="color:#660e7a;font-weight:bold;">data</span>;<br />    }<br /><br />    <span style="color:#808080;font-style:italic;">//</span><span style="color:#808080;font-style:italic;font-family:'宋体';">返回栈顶的元素，但不出栈<br /></span> <span style="color:#000080;font-weight:bold;">public </span><span style="color:#20999d;">T </span>peek() {<br />        <span style="color:#000080;font-weight:bold;">return </span><span style="color:#660e7a;font-weight:bold;">top</span>.<span style="color:#660e7a;font-weight:bold;">data</span>;<br /><br />    }<br /><br />    <span style="color:#808080;font-style:italic;">// </span><span style="color:#808080;font-style:italic;font-family:'宋体';">判断链栈是否为空栈<br /></span> <span style="color:#000080;font-weight:bold;">public boolean </span>empty() {<br />        <span style="color:#000080;font-weight:bold;">return </span><span style="color:#660e7a;font-weight:bold;">size </span>== <span style="color:#0000ff;">0</span>;<br />    }<br /><br />    <span style="color:#000080;font-weight:bold;">public </span>String toString() {<br />        <span style="color:#808080;font-style:italic;">// </span><span style="color:#808080;font-style:italic;font-family:'宋体';">链栈为空链栈时<br /></span> <span style="color:#000080;font-weight:bold;">if </span>(empty())<br />            <span style="color:#000080;font-weight:bold;">return </span><span style="color:#008000;font-weight:bold;">"[]"</span>;<br />        <span style="color:#000080;font-weight:bold;">else </span>{<br />            StringBuilder sb = <span style="color:#000080;font-weight:bold;">new </span>StringBuilder(<span style="color:#008000;font-weight:bold;">"["</span>);<br />            <span style="color:#000080;font-weight:bold;">for </span>(Node current = <span style="color:#660e7a;font-weight:bold;">top</span>; current != <span style="color:#000080;font-weight:bold;">null</span>; current = current.<span style="color:#660e7a;font-weight:bold;">next</span>) {<br />                sb.append(current.<span style="color:#660e7a;font-weight:bold;">data</span>.toString() + <span style="color:#008000;font-weight:bold;">", "</span>);<br />            }<br />            <span style="color:#000080;font-weight:bold;">int </span>len = sb.length();<br />            <span style="color:#000080;font-weight:bold;">return </span>sb.delete(len - <span style="color:#0000ff;">2</span>, len).append(<span style="color:#008000;font-weight:bold;">"]"</span>).toString();<br /><br />        }<br />    }<br /><br />    <span style="color:#000080;font-weight:bold;">public static void </span>main(String[] args) <span style="color:#000080;font-weight:bold;">throws </span>Exception {<br />        MyStack stack = <span style="color:#000080;font-weight:bold;">new </span>MyStack&lt;String&gt;();<br />        <span style="color:#000080;font-weight:bold;">for </span>(<span style="color:#000080;font-weight:bold;">int </span>i = <span style="color:#0000ff;">0</span>; i &lt;= <span style="color:#0000ff;">10</span>; i++) {<br />            stack.push(<span style="color:#008000;font-weight:bold;">"111111-" </span>+ i);<br />        }<br />        System.<span style="color:#660e7a;font-weight:bold;font-style:italic;">out</span>.println(stack);<br />        System.<span style="color:#660e7a;font-weight:bold;font-style:italic;">out</span>.println(<span style="color:#008000;font-weight:bold;">"frist pop="</span>+stack.pop());<br />        System.<span style="color:#660e7a;font-weight:bold;font-style:italic;">out</span>.println(<span style="color:#008000;font-weight:bold;">"second pop="</span>+stack.pop());<br />        System.<span style="color:#660e7a;font-weight:bold;font-style:italic;">out</span>.println(<span style="color:#008000;font-weight:bold;">"thrid pop="</span>+stack.pop());<br />        System.<span style="color:#660e7a;font-weight:bold;font-style:italic;">out</span>.println(<span style="color:#008000;font-weight:bold;">"pop </span><span style="color:#008000;font-weight:bold;font-family:'宋体';">之后的</span><span style="color:#008000;font-weight:bold;">"</span>+stack);<br />    }<br /><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000; ">/**</span><span style="color: #008000; "><br />&nbsp;*&nbsp;Created&nbsp;by&nbsp;zz.zhang&nbsp;on&nbsp;2018/1/4.<br />&nbsp;</span><span style="color: #008000; ">*/</span><br /><span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;MyStack&lt;T&gt;&nbsp;{<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;DEFAULT_SIZE&nbsp;=&nbsp;8;<span style="color: #008000; ">//</span><span style="color: #008000; ">定义栈的初始默认长度</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;capacity;<span style="color: #008000; ">//</span><span style="color: #008000; ">保存顺序栈的长度</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;size;<span style="color: #008000; ">//</span><span style="color: #008000; ">保存顺序栈中元素的个数</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;Object[]&nbsp;elementData;<span style="color: #008000; ">//</span><span style="color: #008000; ">定义一个数组用于保存顺序栈中的元素</span><span style="color: #008000; "><br /></span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;MyStack()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;capacity&nbsp;=&nbsp;DEFAULT_SIZE;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;elementData&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;Object[capacity];<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;MyStack(<span style="color: #0000FF; ">int</span>&nbsp;initSize)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;capacity&nbsp;=&nbsp;1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;(capacity&nbsp;&lt;&nbsp;initSize)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;capacity&nbsp;&lt;&lt;=&nbsp;1;<span style="color: #008000; ">//</span><span style="color: #008000; ">将capacity设置成大于initSize的最小2次方</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;elementData&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;Object[capacity];<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;push(T&nbsp;element)&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;Exception&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;elementData[size++]&nbsp;=&nbsp;element;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;T&nbsp;pop()&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;Exception&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(empty())&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">throw</span>&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;IndexOutOfBoundsException("栈空，不能出栈");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;oldValue&nbsp;=&nbsp;(T)&nbsp;elementData[size&nbsp;-&nbsp;1];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;elementData[--size]&nbsp;=&nbsp;<span style="color: #0000FF; ">null</span>;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;设置成null&nbsp;让JVM垃圾回收</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;oldValue;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;empty()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;size&nbsp;==&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">返回当前顺序栈中元素的个数</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;length()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;size;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">获取栈顶元素，不会将栈顶元素删除</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;T&nbsp;peek()&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;Exception&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(size&nbsp;==&nbsp;0)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">throw</span>&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;ArrayIndexOutOfBoundsException("栈为空");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;(T)&nbsp;elementData[size&nbsp;-&nbsp;1];<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;clear()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;size;&nbsp;i++)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;elementData[i]&nbsp;=&nbsp;<span style="color: #0000FF; ">null</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;main(String[]&nbsp;args)<span style="color: #0000FF; ">throws</span>&nbsp;Exception{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyStack&lt;String&gt;&nbsp;stack=<span style="color: #0000FF; ">new</span>&nbsp;MyStack&lt;String&gt;(30);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(<span style="color: #0000FF; ">int</span>&nbsp;i=0&nbsp;;i&lt;30;i++){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stack.push(String.valueOf(i));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(stack.pop());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(stack.peek());<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}</div><br /><br /><br /></pre><img src ="http://www.blogjava.net/zzzlyr/aggbug/432414.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zzzlyr/" target="_blank">张钊钊</a> 2017-03-27 15:43 <a href="http://www.blogjava.net/zzzlyr/articles/432414.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hash算法 (hashmap 实现原理)</title><link>http://www.blogjava.net/zzzlyr/articles/413349.html</link><dc:creator>张钊钊</dc:creator><author>张钊钊</author><pubDate>Wed, 07 May 2014 00:37:00 GMT</pubDate><guid>http://www.blogjava.net/zzzlyr/articles/413349.html</guid><wfw:comment>http://www.blogjava.net/zzzlyr/comments/413349.html</wfw:comment><comments>http://www.blogjava.net/zzzlyr/articles/413349.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zzzlyr/comments/commentRss/413349.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zzzlyr/services/trackbacks/413349.html</trackback:ping><description><![CDATA[<div style="margin-bottom: 15px; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 12px; line-height: 18px;"><h3><a href="http://zha-zi.iteye.com/blog/1124484" style="color: #108ac6;">hash算法 (hashmap 实现原理)</a><em></em></h3><div style="clear: both; margin: 10px 0px 5px; line-height: 20px;">&nbsp;<span style="line-height: 1.8em; font-size: 14px;">&nbsp; &nbsp; Hash&nbsp;，一般翻译做&#8220;&nbsp;散列&#8221;&nbsp;，也有直接音译为&#8220;&nbsp;哈希&#8221;&nbsp;的，就是把任意长度的输入（又叫做预映射，&nbsp;pre-image），通过散列算法，变换成固定长度的输出，该输出就是散列值。这种转换是一种压缩映射，也就是，散列值的空间通常远小于输入的空间，不 同的输入可能会散列成相同的输出，而不可能从散列值来唯一的确定输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。</span></div></div><div id="blog_content" style="line-height: 1.8em; font-family: Helvetica, Tahoma, Arial, sans-serif;"><p style="margin: 0px; padding: 0px; text-indent: 24pt;">HASH&nbsp;主要用于信息安全领域中加密算法，它把一些不同长度的信息转化成杂乱的128&nbsp;位的编码,&nbsp;这些编码值叫做HASH&nbsp;值.&nbsp;也可以说，hash&nbsp;就是找到一种数据内容和数据存放地址之间的映射关系</p><p style="margin: 0px; padding: 0px;">例如字符串&nbsp;hello&nbsp;的哈希算法</p><p style="margin: 0px; padding: 0px;">char* value = "hello"; int key = (((((((27* (int)'h'+27)* (int)'e') + 27)&nbsp;　* (int)'l') + 27) * (int)'l' +27) * 27 ) + (int)'o' ;。</p><p style="margin: 0px; padding: 0px; text-indent: 24pt;">&nbsp;</p><p style="margin: 0px; padding: 0px; text-indent: 24pt;">&nbsp;&nbsp;数组的特点是：寻址容易，插入和删除困难；而链表的特点是：寻址困难，插入和删除容易。那么我们能不能综合两者的特性，做出一种寻址容易，插入删除也容易 的数据结构？答案是肯定的，这就是我们要提起的哈希表，哈希表有多种不同的实现方法，我接下来解释的是最常用的一种方法&#8212;&#8212;&nbsp;拉链法，我们可以理解为&#8220;&nbsp;链表 的数组&#8221;&nbsp;，如图：</p><p style="margin: 0px; padding: 0px; text-indent: 24pt;"><br /><img alt="" src="http://dl.iteye.com/upload/attachment/517190/b197e4de-8b25-39a0-aa03-ac933a12ff08.png" style="border: 0px;" /></p><p style="margin: 0px; padding: 0px; text-indent: 24pt;">&nbsp;</p><p style="margin: 0px; padding: 0px; text-indent: 24pt;">&nbsp;</p><p style="margin: 0px; padding: 0px; text-indent: 24pt;">&nbsp;</p><p style="margin: 0px; padding: 0px;">HashMap其实也是一个线性的数组实现的,所以可以理解为其存储数据的容器就是一个线性数组。这可能让我们很不解，一个线性的数组怎么实现按键值对来存取数据呢？这里HashMap有做一些处理。</p><table width="157" border="0" style="height: 24px;"><tbody><tr><td style="font-size: 1em;"></td></tr></tbody></table><p style="margin: 0px; padding: 0px;">&nbsp;&nbsp;&nbsp; 1.首先HashMap里面实现一个静态内部类Entry 其重要的属性有 key , value, next,从属性key,value我们就能很明显的看出来Entry就是HashMap键值对实现的一个基础bean,我们上面说到HashMap的基 础就是一个线性数组,这个数组就是Entry[]，Map里面的内容都保存在Entry[]里面。</p><p style="margin: 0px; padding: 0px;">&nbsp;&nbsp;&nbsp;&nbsp; 2.既然是线性数组，为什么能随机存取？这里HashMap用了一个小算法，大致是这样实现：</p><p style="margin: 0px; padding: 0px;">&nbsp;</p><div id="" style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', Consolas, 'Courier New', monospace; width: 679px; margin-left: 9px; padding-right: 1px; padding-bottom: 1px; padding-left: 1px; word-break: break-all; word-wrap: break-word;"><div><div style="padding-right: 3px; padding-bottom: 3px; padding-left: 3px; margin: 0px; font-weight: bold;">Java代码&nbsp;&nbsp;<a title="收藏这段代码" style="color: #108ac6; text-decoration: underline;"><img src="http://zha-zi.iteye.com/images/icon_star.png" alt="收藏代码" style="border: 0px;" /></a></div></div><ol start="1" style="font-size: 1em; line-height: 1.4em; margin-left: 0px; padding-top: 2px; padding-bottom: 2px; border: 1px solid #d1d7dc; color: #2b91af;"><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">存储时:&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: #7f0055;">int</span>&nbsp;hash&nbsp;=&nbsp;key.hashCode();--&gt;&nbsp;这个hashCode方法这里不详述,只要理解每个key的hash是一个固定的<span style="color: #7f0055;">int</span>值&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: #7f0055;">int</span>&nbsp;index&nbsp;=&nbsp;hash&nbsp;%&nbsp;Entry[].length;&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">Entry[index]&nbsp;=&nbsp;value;&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">取值时:&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: #7f0055;">int</span>&nbsp;hash&nbsp;=&nbsp;key.hashCode();&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: #7f0055;">int</span>&nbsp;index&nbsp;=&nbsp;hash&nbsp;%&nbsp;Entry[].length;&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;">&nbsp;&nbsp;</li><li style="font-size: 1em; margin-left: 38px; padding-right: 0px; border-left-width: 1px; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: #7f0055;">return</span>&nbsp;Entry[index]&nbsp;&nbsp;</li></ol></div>&nbsp;<p style="margin: 0px; padding: 0px;">到这里我们轻松的理解了HashMap通过键值对实现存取的基本原理</p><p style="margin: 0px; padding: 0px;">&nbsp;&nbsp;&nbsp; 3.疑问：如果两个key通过hash % Entry[].length得到的index相同，会不会有覆盖的危险？</p><p style="margin: 0px; padding: 0px;">这里HashMap里面用到链式数据结构的一个概念.上面我们提到过Entry类里面有一个next属性,作用是指向下一个Entry。打个比方, 第一个键值对A进来,通过计算其key的hash得到的index=0，记做:Entry[0] = A.一会后又进来一个键值对B,通过计算其index也等于0,现在怎么办？HashMap会这样做:B.next = A,Entry[0] = B,如果又进来C,index也等于0,那么C.next = B,Entry[0] = C；这样我们发现index=0的地方其实存取了A,B,C三个键值对,他们通过next这个属性链接在一起。所以疑问不用担心。</p><p style="margin: 0px; padding: 0px;">到这里为止，HashMap的大致实现，我们应该已经清楚了。</p><p style="margin: 0px; padding: 0px;">当然HashMap里面也包含一些优化方面的实现，这里也啰嗦一下。</p><p style="margin: 0px; padding: 0px;">比如：Entry[]的长度一定后，随着map里面数据的越来越长，这样同一个index的链就会很长，会不会影响性能？</p><p style="margin: 0px; padding: 0px;">HashMap里面设置一个因素（也称为因子），随着map的size越来越大，Entry[]会以一定的规则加长长度。</p><p style="margin: 0px; padding: 0px;">&nbsp;</p><p style="margin: 0px; padding: 0px;">&nbsp;</p><p style="margin: 0px; padding: 0px;">解决hash冲突的办法</p><p style="margin: 0px; padding: 0px;">1）开放定址法（线性探测再散列，二次探测再散列，伪随机探测再散列）</p><p style="margin: 0px; padding: 0px;">2）再哈希法</p><p style="margin: 0px; padding: 0px;">3）链地址法</p><p style="margin: 0px; padding: 0px;">4）建立一 公共溢出区</p><p style="margin: 0px; padding: 0px;">&nbsp;</p><p style="margin: 0px; padding: 0px;">java 中hashmap的解决办法就是采用的链地址法<br />转载文章<br /><br /></p></div><img src ="http://www.blogjava.net/zzzlyr/aggbug/413349.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zzzlyr/" target="_blank">张钊钊</a> 2014-05-07 08:37 <a href="http://www.blogjava.net/zzzlyr/articles/413349.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>