<code class="language-text">private class Node<t> {
public Node<t> next;
public T data;
public Node(T d,Node<t> n) {data = d; next = n;}
}
</t></t></t></code>
java的引用就不说了,python里所有的变量其实都是对象的引用(连基本类型都是如此),而这个引用,说白了就是个指向实例的指针。
所以并不是没有指针,而是全都是指针只不过你看不出来而已。
做链表当然可以,对于python而言就一个类里两个属性,next仍旧是next,指向下个节点的实例就可以了。
Python和Java的“引用”就是不能运算的指针。
其实我更喜欢go语言的理念,没有任何“引用”,所以就避免了混淆的“传引用”概念。所有的值传递都是传值,指针就是指针,但是不能运算。
其实Java, python完全可以看成在语言层用语法糖隐藏了指针。
Java中,假设class A有 属性 int a, B(class B) b,那A实例化(b在A实例化新开辟而不是通过外部赋值),内存开辟一段包含一个int a和 一个b 的reference地址,b实例化和A一样,然后把地址抛给A中b的reference。其实这个和C/C++中的A中有个B* b差不多。所以链表、图等数据结构在C/C++中的实现转义到Java中也就是改改语法糖的表示。
Python中,链表、树等数据结构大致对应Python自带list、tuple、dict。Python这种动态语言用C实现,拿Python的list来讲,用一个struct PyListObject 实现,看看源码指针随处都是。
C/C++这样的语言比较接近早期抽象计算机数据的思维方式,指针其实就是我们抽象数据并且这个数据是聚合但是实际内存离散的胶合层产物。后来出的语言通过其他的方式来抽象数据表示,将指针这个概念隐藏了,显得友好了,但是其实他还在那。
基本上没有指针会有更灵活的方式进行,回收机制直接丢弃可以自动释放内存,写起来也简单,一码胜千言,贴张python的简单链表实现:
<code class="language-python"><span class="c"># -*- coding: utf-8 -*-</span>
<span class="k">class</span> <span class="nc">Node</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">datum</span><span class="p">,</span> <span class="nb">next</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">__datum</span> <span class="o">=</span> <span class="n">datum</span>
<span class="bp">self</span><span class="o">.</span><span class="n">__next</span> <span class="o">=</span> <span class="nb">next</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">datum</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">__datum</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">next</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">__next</span>
<span class="nd">@next.setter</span>
<span class="k">def</span> <span class="nf">next</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">next</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">__next</span> <span class="o">=</span> <span class="nb">next</span>
<span class="k">class</span> <span class="nc">LinkedList</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">__head</span> <span class="o">=</span> <span class="bp">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">__tail</span> <span class="o">=</span> <span class="bp">None</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">head</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">__head</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">tail</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">__tail</span>
<span class="k">def</span> <span class="nf">purge</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">__head</span> <span class="o">=</span> <span class="bp">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">__tail</span> <span class="o">=</span> <span class="bp">None</span>
<span class="k">def</span> <span class="nf">is_empty</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">__head</span> <span class="ow">is</span> <span class="bp">None</span>
<span class="k">def</span> <span class="nf">append</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">item</span><span class="p">):</span>
<span class="c">#Generates the node.</span>
<span class="n">datum</span> <span class="o">=</span> <span class="n">Node</span><span class="p">(</span><span class="n">item</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span>
<span class="c">#For the first node in a linked list, it will change the head.</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">__head</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">__head</span> <span class="o">=</span> <span class="n">datum</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">__tail</span><span class="o">.</span><span class="n">next</span> <span class="o">=</span> <span class="n">datum</span>
<span class="bp">self</span><span class="o">.</span><span class="n">__tail</span> <span class="o">=</span> <span class="n">datum</span>
<span class="k">def</span> <span class="nf">remove</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">item</span><span class="p">):</span>
<span class="n">pointer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">__head</span>
<span class="n">prepointer</span> <span class="o">=</span> <span class="bp">None</span>
<span class="c">#Finds the item</span>
<span class="k">while</span> <span class="n">pointer</span> <span class="ow">and</span> <span class="n">pointer</span><span class="o">.</span><span class="n">datum</span> <span class="o">!=</span> <span class="n">item</span><span class="p">:</span>
<span class="n">prepointer</span> <span class="o">=</span> <span class="n">pointer</span>
<span class="n">pointer</span> <span class="o">=</span> <span class="n">pointer</span><span class="o">.</span><span class="n">next</span>
<span class="c">#Raise the error when not finding the item.</span>
<span class="k">if</span> <span class="n">pointer</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span> <span class="k">raise</span> <span class="ne">KeyError</span>
<span class="c">#When the linked list has one node, it will sets the head.</span>
<span class="k">if</span> <span class="n">pointer</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">__head</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">__head</span> <span class="o">=</span> <span class="n">pointer</span><span class="o">.</span><span class="n">next</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">prepointer</span><span class="o">.</span><span class="n">next</span> <span class="o">=</span> <span class="n">pointer</span><span class="o">.</span><span class="n">next</span>
<span class="k">if</span> <span class="n">pointer</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">__tail</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">__tail</span> <span class="o">=</span> <span class="n">prepointer</span>
</code>
其实完全不用指针也可以实现这种结构。
参见:cons