java 单向和双向链表的详解
2016-06-29 16:37
585 查看
Java 链表的使用
浅谈自己学习链表之后的理解:
链表是一种重要的数据结构,有单链表和双链表之分
单链表(单向链表):由两部分组成 数据域(Data)和结点域(Node),单链表就像是一条打了很多结的绳子,每一个绳结相当于一个结点,每个节结点间都有绳子连接,这样原理的实现是通过Node结点区的头指针head实现的,每个结点都有一个指针,每个节点指针的指向都是指向自身结点的下一个结点,最后一个结点的head指向为null,这样一来就连成了上述所说绳子一样的链,对单链表的操作只能从一端开始,如果需要查找链表中的某一个结点,则需要从头开始进行遍历。
单链表的操作:
添加:上图可以看出 单向链表只有一个指向,原来head为p,p指向s,添加结点只需要把p指向q,q指向s就可以了,即:p--->q ; q--->s ; 这样就实现了单向链表的添加;
删除:原理与添加相反,若此时链表为 p---> q --->s ; 若删除q节点只需要更改p的指向就可以了 p--->s,这样就删掉了;
查找:查找操作需要对整个但链表进行遍历,直到满足查找条件为止;
修改:此操作一般建立在查找之上进行,找到借点之后对值进行修改;
首先构建一个节点类,设置一个数据区和节点区
使用构造方法便于使用
双链表(双向链表):双链表和单链表相比,多了一个指向尾指针(tail),双链表的每个结点都有一个头指针head和尾指针tail,双链表相比单链表更容易操作,双链表结点的首结点的head指向为null,tail指向下一个节点的tail;尾结点的head指向前一个结点的head,tail 指向为null,是双向的关系;
双链表的操作:
package soft1;
public class LinkList {
Node head;
Node tail;
int count;
public LinkList(Node head,Node tail,int count){
this.head=null;
this.tail=null;
this.count=0;
}
public LinkList(){
}
//尾插法添加节点
public void addHeadNode(NodeData data){
Node node = new Node(data,null,null);
if(head==null&&tail==null){
head=node;
head.setFront(null);
tail=node;
tail.setNext(null);
}else{
head.setFront(node);
node.setNext(head);
head=node;
head.setFront(null);
}
count++;
}
//头插法添加节点
public void addTailNode(NodeData data){
Node node = new Node(data,null,null);
if(head==null&&tail==null){
head=node;
head.setFront(null);
tail=node;
tail.setNext(null);
}else{
tail.setNext(node);
node.setFront(tail);
tail=node;
tail.setNext(null);
}
count++;
}
//查找节点
public Node findNode(NodeData data){
Node temp=head;
if(head!=null){
while(temp!=null){
if(temp.data.compare(data)){
return temp;
}
temp=temp.getNext();
}
}
return null;
}
//删除节点
public void delNode(NodeData data){
Node temp=findNode(data);
if(temp!=null){
if(temp.getFront()==null){
head=temp.getNext();
head.setFront(null);
}else if(temp.getNext()==null){
tail=tail.getFront();
tail.setNext(null);
}else{
temp.getFront().setNext(temp.getNext());
temp.getNext().setFront(temp.getFront());
}
count--;
}
}
//修改更新
public void updNode(NodeData data){
Node temp=findNode(data);
if(temp!=null){
temp.setNodeData(data);
}
}
//打印链表
public void printNode(){
Node temp = head;
while(temp!=null){
temp.print();
temp=temp.getNext();
}
}
}
需要把自己写过的代码总结之后都放在网上,不过就是有点慢,急不得啊 哈哈
浅谈自己学习链表之后的理解:
链表是一种重要的数据结构,有单链表和双链表之分
单链表(单向链表):由两部分组成 数据域(Data)和结点域(Node),单链表就像是一条打了很多结的绳子,每一个绳结相当于一个结点,每个节结点间都有绳子连接,这样原理的实现是通过Node结点区的头指针head实现的,每个结点都有一个指针,每个节点指针的指向都是指向自身结点的下一个结点,最后一个结点的head指向为null,这样一来就连成了上述所说绳子一样的链,对单链表的操作只能从一端开始,如果需要查找链表中的某一个结点,则需要从头开始进行遍历。
单链表的操作:
添加:上图可以看出 单向链表只有一个指向,原来head为p,p指向s,添加结点只需要把p指向q,q指向s就可以了,即:p--->q ; q--->s ; 这样就实现了单向链表的添加;
删除:原理与添加相反,若此时链表为 p---> q --->s ; 若删除q节点只需要更改p的指向就可以了 p--->s,这样就删掉了;
查找:查找操作需要对整个但链表进行遍历,直到满足查找条件为止;
修改:此操作一般建立在查找之上进行,找到借点之后对值进行修改;
首先构建一个节点类,设置一个数据区和节点区
使用构造方法便于使用
public class Node{ public Node data; //数据区 public Node next; //指针区 public Node (Node data,Node next){ this.data = data ; this.next = next; } public Node(){ } public void setData(Node data){ this.data = data; } public Node getData(){ return data; } public void setNext(Node next){ this.next=next; } public Node getNext(){ return next; } } public class LinkList{ public Node head; //头节点 public int count; //记录节点的长度 public LinkList(){ //构造函数用来初始化 head = null; count = 0; } //节点的添加 public void addNode(Node data){ Node node = new Node(data,null); Node temp = null; If(head!= null){ temp = head; while(temp.getNext()!=null){ Temp = temp.getNext(); } temp.setNext(node); }else{ head = node; temp = node; } count++; } //节点的删除 public void delNode(Node data){ Node front = null; //定义一个空节点,用于接收和判断被删除节点的前面还有没有节点 while(head!= null){ If(head.equals(data)){ break; } front=head; head = head.getNext(); } If(head!=null){ If(front==null){ head = head.getNext(); }else{ front.setNext(head.getNext()); } count--; }else{ Count--; } } //给定下标删除节点 public void delNode_count(int index){ if(index<0||index>count-1){ System.out.println("链表索引越界"); } Node temp = head; //作用同上 //找到要删除节点的前一个节点 for(int i=0;i<index-1;i++){ temp=temp.getNext(); } //找到之后 此节点的前节点和此节点的后节点进行连接 //让要删除节点的前一个节点,指向被删除节点的后一个节点,也就是指向要删除节点的后后一个节点 temp.setNext(temp.getNext().getNext()); //把要删除的节点隔过去进行连接,也就是实现了删除节点的操作 //删除之后链表的长度变短了1位 count--; } //以给出的index 查找节点 public Node findNode(int index){ if(index<0||index>count-1){ System.out.println("链表索引越界"); } Node temp = head; for(int i=0;i<index-1;i++){ temp=temp.getNext(); //找到之后获取index在链表中的位置,表示链表中第index个节点的值是temp.getData; } return temp; //根据需要可返回找到的数据对象,也可不返回,此处建议返回,这样可以把链表封装起来 } //以对象查找节点 public Node findNode(NodeData data){ Node temp = head; while(temp!=null){ if(temp.equals(data)){ return temp; } temp.setNext(temp.getNext()); } return null; } //修改 public void updateNode(NodeData data){ Node temp = findNode(data); if(temp!=null){ temp.setData(data); } } //打印 public void print(){ Node temp=head; while(temp!=null){ temp.print(); //temp.print(temp.getData().toString()); temp=temp.getNext(); } } }
双链表(双向链表):双链表和单链表相比,多了一个指向尾指针(tail),双链表的每个结点都有一个头指针head和尾指针tail,双链表相比单链表更容易操作,双链表结点的首结点的head指向为null,tail指向下一个节点的tail;尾结点的head指向前一个结点的head,tail 指向为null,是双向的关系;
双链表的操作:
package soft1;
public class LinkList {
Node head;
Node tail;
int count;
public LinkList(Node head,Node tail,int count){
this.head=null;
this.tail=null;
this.count=0;
}
public LinkList(){
}
//尾插法添加节点
public void addHeadNode(NodeData data){
Node node = new Node(data,null,null);
if(head==null&&tail==null){
head=node;
head.setFront(null);
tail=node;
tail.setNext(null);
}else{
head.setFront(node);
node.setNext(head);
head=node;
head.setFront(null);
}
count++;
}
//头插法添加节点
public void addTailNode(NodeData data){
Node node = new Node(data,null,null);
if(head==null&&tail==null){
head=node;
head.setFront(null);
tail=node;
tail.setNext(null);
}else{
tail.setNext(node);
node.setFront(tail);
tail=node;
tail.setNext(null);
}
count++;
}
//查找节点
public Node findNode(NodeData data){
Node temp=head;
if(head!=null){
while(temp!=null){
if(temp.data.compare(data)){
return temp;
}
temp=temp.getNext();
}
}
return null;
}
//删除节点
public void delNode(NodeData data){
Node temp=findNode(data);
if(temp!=null){
if(temp.getFront()==null){
head=temp.getNext();
head.setFront(null);
}else if(temp.getNext()==null){
tail=tail.getFront();
tail.setNext(null);
}else{
temp.getFront().setNext(temp.getNext());
temp.getNext().setFront(temp.getFront());
}
count--;
}
}
//修改更新
public void updNode(NodeData data){
Node temp=findNode(data);
if(temp!=null){
temp.setNodeData(data);
}
}
//打印链表
public void printNode(){
Node temp = head;
while(temp!=null){
temp.print();
temp=temp.getNext();
}
}
}
需要把自己写过的代码总结之后都放在网上,不过就是有点慢,急不得啊 哈哈
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- [C/C++]反转链表
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序