链表小结
链表
链表是一种重要的数据结构,在程序设计中占有很重要的地位。 C 语言和 C ++ 语言中是用指针来实现链表结构的,由于 java 语言不提供指针,所以有人认为在 java 语言中不能实现链表,其实不是这样, java 语言比 C 语言和 C ++ 语言更容易实现链表结构。 Java 语言中的对象引用实际上就相当于指针的作用。链表与数组和队列这种数据结构在存储上的不同体现在:其物理存储为非连续,非顺序的,数据元素的逻辑顺序是通过链表中对象的引用(指针)来实现的。链表有一系列结点(链表中的每个元素称为结点)组成,节点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个节点地址的指针域。相比于线性表顺序结构,链表比较容易插入和删除。
一、 单向链表
单向链表 的每一个结点只有一个指针域和数据域组成
/**
* 单向链表的节点类
*
*/
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 setNext(LinkNode next){
this . next = next;
}
}
/**
* 单向链表类
* *
*/
public class LinkList {
public static void main(String args[]) {
LinkList list = new LinkList();
// 创建链表
LinkNode root = list.createLink();
// 遍历
list.printLinkList(root);
}
// 创建链表
public LinkNode createLink() {
String s = " 根节点 " ;
LinkNode root = new LinkNode(s);
LinkNode n1 = new LinkNode( " 一节点 " );
LinkNode n2 = new LinkNode( " 二节点 " );
LinkNode n3 = new LinkNode( " 三节点 " );
root.setNext(n1);
n1.setNext(n2);
n2.setNext(n3);
return root;
}
public void printLinkList(LinkNode root) {
if ( null != root) {
Object data = root.getObj();
System. out .println(data);
// 继续向下打印
printLinkList(root.getNext());
}
}
}
二、 双向链表
单向链表的缺点是如果你相对链表中的某个结点进行操作,如果是单向非循环链表,只能从表头开始查找、这是有单链表的结构所导致的,因为单向链表每个结点只有一个存储子节点的地址的链域。而双向链表则是对单向链表的一种改进,在双向链表中结点由数据域和一个存储直接子结点地址的右链域,一个存储直接父结点地址的左链域。这样无论从链表中的任何位置都可以得到整个链表中的元素。
/**
* 双向链表结点类
*
*/
public class LinkNode {
// 定义双向链表的三个属性
private Object obj ;
private LinkNode child ;
private LinkNode parent ;
// 重载构造方法,并传入参数
public LinkNode(Object obj){
this . obj = obj;
}
// 取得链表中的元素
public Object getObj() {
return obj ;
}
// 设置链表中的元素
public void setObj(Object obj) {
this . obj = obj;
}
public LinkNode getChild() {
return child ;
}
public void setChild(LinkNode child) {
this . child = child;
}
public LinkNode getParent() {
return parent ;
}
public void setParent(LinkNode parent) {
this . parent = parent;
}
}
链表实现自定义队列
实现数据 的查找,删除,添加,插入,长度,等操作
/**
* 双向链表类
*
*/
public class LinkList {
// 定义一个头结点
public static LinkNode head = null;
// 定义一个尾结点
public LinkNode foot = head;
// 程序入口
public static void main(String args[]){
LinkList list = new LinkList();
for(int i=0;i<10;i++){
list.add(" 练习 "+i);
}
list.add(6, " 新加入的 ");
System.out.println(" 删除前遍历》》》》》》》》》》》》》》》 ");
list.printList(head);
list.size();
LinkNode c = list.getNode(4);
System.out.println(">>>>>>>>>>>>>>>>>>");
System.out.println(c.getObj());
list.remove(3);
System.out.println(" 元素的个数: "+list.size());
System.out.println(" 删除后遍历《《《《《《《《《《《《《《《《《《《 ");
list.printList(head);
System.out.println(" 更改某位置上的元素! ");
list.update(2, " 人不犯我我不犯人! ");
list.printList(head);
}
/**
* 添加一個元素的方法
* @param obj
*/
public void add(Object obj){
LinkNode node = new LinkNode(obj);
if(head==null){
head = node;
foot = head;
}
else{
node.setParent(foot);
foot.setChild(node);
foot = node;
}
}
/**
* 插入一個元素的方法
* @param index 所要插入元素的索引位置
* @param obj 所要插入的元素
*/
public void add(int index,Object obj){
if(index>size()||index<0){
throw new RuntimeException(" 越界: "+index+",size:"+size());
}else{
LinkNode newnode = new LinkNode(obj);
// 得到所要插入位置的索引
LinkNode node = this.getNode(index);
if(index==0){
// head.setChild(newnode);
// newnode.setParent(head);
head = newnode;
}else{
// 得到父节点对象
LinkNode fnode = node.getParent();
fnode.setChild(newnode);
newnode.setParent(fnode);
}
newnode.setChild(node);
node.setParent(newnode);
}
}
/**
* 删除指定索引位置上的元素
* @param index 要删除元素的索引位置
*/
public void remove(int index){
if(index>size()||index<0){
throw new RuntimeException(" 越界: "+index+",size:"+size());
}else{
// 获得要删除元素的索引值
LinkNode node = this.getNode(index);
LinkNode fnode = node.getParent();
LinkNode cnode = node.getChild();
if(index==0){
head = cnode;
}else if(cnode == null){
cnode = null;
}
else{
cnode.setParent(fnode);
fnode.setChild(cnode);
}
}
}
public void update(int index,Object obj){
if(index>size()||index<0){
throw new RuntimeException(" 越界: "+index+",size:"+size());
}
else{
LinkNode node = this.getNode(index);
node.setObj(obj);
}
}
/**
* 获取链表的长度
* @return
*/
public int size(){
int count = 0;
if(head==null){
return 0;
}
// 创建一个节点对象
LinkNode node = head.getChild();
while(node!=null){
count++;
node = node.getChild();
}
return count+1;
}
/**
* 得到指定位置上的元素
* @param index
* @return
*/
public LinkNode getNode(int index){
if(index>size()||index<0){
throw new RuntimeException(" 越界: "+index+",size:"+size());
}
else {
int i = 0;
LinkNode node = head;
// 如果没有找到就继续向下找
while(i!=index){
node = node.getChild();
i++;
}
return node;
}
}
/**
* 打印链表中的元素
* @param head
*/
public void printList(LinkNode head){
if(head!=null){
Object obj = head.getObj();
System.out.println(obj);
printList(head.getChild());
}
}
}