单链表的实现
用一组地址任意的存储单元存放线性表中的数据元素。以元素(数据元素的映象) + 指针(指示后继元素存储位置) = 结点。
以“结点的序列”表示线性表,称作线性链表(单链表)。单链表是一种顺序存取的结构,为找第 i 个数据元素,必须先找到第 i-1 个数据元素。
链表的结点结构:
┌──┬──┐
│data│next│
└──┴──┘
data域:存放结点值的数据域
next域:存放结点的直接后继的地址(位置)的指针域(链域)。
注意:①链表通过每个结点的链域将线性表的n个结点按其逻辑顺序链接在一起的。
②每个结点只有一个链域的链表称为单链表(Single Linked List)。
所谓的链表就好像火车车厢一样,从火车头开始,每一节车厢之后都连着后一节车厢。
例如:创建一节车厢的节点类,其代码如下:
class Node {
private String data; //保存该节点内容
private Node next; //保存下一个节点
public Node() {}
public Node(String data) {
this.data = data;
}
public void setData(String data) {
this.data = data;
}
public String getData() {
return this.data;
}
public void setNext(Node next) {
this.next = next;
}
public Node getNext() {
return this.next;
}
}
实现一个单链表节点操作包括增加数据、查找数据、删除数据。删除节点,则是直接修改上一个节点的引用即可。
例如:实现链表操作,代码如下:
class Link
class Node
private T info ; //保存节点内容
private Node
public Node(T info) {
this.info = info;
}
public T getInfo() {return this.info;}
public Node
public void setNext(Node
public void setNext(T info) {this.add(info);}
public void add(Node
if(this.next == null) {
this.next = newNode;
} else {
this.next.add(newNode); //运用递归方法来完成下一个节点处的增加
}
}
public void add(T info) {
Node
this.add(newNode);
}
public boolean search(T info) {
if(info.equals(this.info)) {
return true;
} else { //判断下一个节点
if(this.next != null) { //下一个节点存在,则继续查找
return this.next.search(info);
} else {
return false;
}
}
}
public void delete(Node
if(info.equals(this.info)) {
preNode.next = this.next; //修改上一个节点的引用
} else {
if(this.next != null) {
this.next.delete(this,info);
}
}
}
public void print() {
System.out.print(this.info.toString()+"/t");
if(this.next != null) {
this.next.print();
}
}
}
private Node
public void addNode(T info) { //新增
Node
if(this.root == null) {
this.root = newNode;
} else {
this.root.add(newNode);
}
}
public boolean contaits(T info) { //查询
return this.root.search(info);
}
public void deleteNode(T info) { //删除
if(this.contaits(info)) {
if(this.root.info.equals(info)) { //包含该内部类的外部类中,可以通过该内部类的实例来访问内部类的私有属性和方法
this.root = this.root.next;
} else {
this.root.next.delete(this.root,info);
}
}
}
public void printNode() { //打印
if(this.root != null) {
this.root.print();
}
}
}
此处的Node类是一个Inner Class(内部类),Link类此处属于Outer Class(外部类) ,内部类和外部类之间都可以通过其对应的实例来访问其私有的属性和方法。
一个内部类除了通过外部类访问外,也可直接在其他类中进行调用,调用的格式为:
外部类 外部类对象 = new 外部类();
外部类.内部类 内部类对象 = 外部类对象.new 内部类();
调用该链表的主要部分:
Link
myLink.addNode("A");
myLink.addNode("B");
myLink.addNode("C");
myLink.addNode("D");
myLink.printNode();
myLink.deleteNode("C");
System.out.println();
myLink.printNode();
System.out.println();
//内部类对象
Link
inns.print();
单链表的反转(倒置)reverseNode
反转(倒置):则必须在泛类 Link
class Link
.......(与上面的Link类中代码相同)
private Node
public void reverseNode() {
if (this != null && this.root != null) {
this.temp = this.root;
this.cur = this.root;
this.root = null;
while (this.temp.next != null) {
while (this.cur.next != null) {
this.cur = this.cur.next;
}
this.addNode(this.cur.info);
this.temp.delete(this.temp, this.cur.info);
this.cur = this.temp;
}
if(this.temp.next == null && this.temp.info != null) {
this.addNode(this.temp.info);
}
}
}
}
调用实现链表反转的主要代码:
Link
myLink.addNode("A");
myLink.addNode("B");
myLink.addNode("C");
myLink.addNode("D");
myLink.printNode();
System.out.println();
myLink.reverseNode();
// 反转后
myLink.printNode();