1、链表的概念:
链表时一种物理存储单位上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
2、链表的组成:
由一系列结点构成,每个结点分成两部分:一是存储数据元素的数据域,二是存储下一个结点地址的指针域。
3、链表与线性顺序结构的比较:
链表更方便插入和删除操作。
4、链表的分类:
单向链表:
组成:每个结点只有两部分:一个是存储数据元素的数据域和指向下一个结点的指针域组成。
代码如下:
public class LinkNode {
private Object obj;//节点内的数据对象
private LinkNode next;//对下一个节点的引用
public LinkNode(Object obj){
this.obj = obj;
}
public Object getobj(){
return obj;
}
public void setObj(Object obj){
this.obj = obj;
}
public LinkNode getNext(){
return next;
}
public void setNect(LinkNode next){
this.next = next;
}
}
双向链表:
组成:每个结点有三部分:一个是存储数据元素的数据域,另外两个是存储子结点地址的右链域和存储父结点地址的左链域。
代码如下:
public class LinkNode {
private LinkNode child;// 对下一个节点的应用
private LinkNode parent;// 对上一个节点的应用
private Object obj;// 节点内的数据对象
private LinkNode next;// 节点的下个元素
private String name;//节点名字
// 在创建节点对象的时候就传入节点中的数据对象
public LinkNode(Object obj) {
this.obj = obj;
}
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
public LinkNode getNext() {
return next;
}
public void setNext(LinkNode next) {
this.next = next;
}
public LinkNode getChild() {
return child;
}
public void setChild(LinkNode child) {
this.child = child;
}
public void setParent(LinkNode parent) {
this.parent = parent;
}
public LinkNode getParent() {
return parent;
}
public void setName(String name){
this.name= name;
}
public String getName(){
return name;
}
}
5、链表的实现:
实现链表的功能,基本上就是对数据的查找、插入、删除、合并、排序、统计等。
添加代码如下:
/**
* 添加节点的方法
*/
public void add(Object obj) {
LinkNode node = new LinkNode(obj);
if (null == front) {
front = node;
last = front;
} else {
last.setChild(node);
node.setParent(last);
last = node;
}
}
查找代码如下:
/**
* 根据索引取出节点
*/
public LinkNode getLinkNode(int index) {
if (this.getLength() < index || index < 0) {
throw new RuntimeException("下标越界:" + index + ",size:"
+ this.getLength());
} else {
int num = 0;
LinkNode node = front;
while (num != index) {
node = node.getChild();
num++;
}
return node;
}
}
插入代码如下:
/**
* 在指定索引下插入节点
*/
public void insertIndexObj(int index, Object obj) {
if (this.getLength() < index || index < 0) {
throw new RuntimeException("下标越界:" + index + ",size:"
+ this.getLength());
} else {
// 创建新的节点
LinkNode newNode = new LinkNode(obj);
// 得到当前索引位置的节点
LinkNode node = this.getLinkNode(index);
if (index == 0) {// 如果链表没有节点
front = newNode;
} else {
// 得到父节点
LinkNode fNode = node.getParent();
// 设置新的引用关系
fNode.setChild(newNode);
newNode.setParent(fNode);
}
// 设置新的引用关系
newNode.setChild(node);
node.setParent(newNode);
}
}
删除代码如下:
/**
* 根据索引位置删除节点
*/
public void deleteLinkNode(int index) {
if (this.getLength() < index || index < 0) {
throw new RuntimeException("下标越界:" + index + ",size:"
+ this.getLength());
} else {
// 得到当前索引位置的节点
LinkNode node = this.getLinkNode(index);
// 得到父节点
LinkNode fNode = node.getParent();
// 得到子节点
LinkNode cNode = node.getChild();
if (fNode == null) {
front = cNode;
} else if (cNode == null) {
fNode.setChild(null);
} else {
fNode.setChild(cNode);
cNode.setParent(fNode);
}
}
}
统计遍历输出代码如下:
/**
* 遍历链表的方法
*/
public void printLinKList(LinkNode root) {
if (null != root) {
Object data = root.getObj();
System.out.println(data);
LinkNode temp = root.getChild();
printLinKList(temp);
}
}