最近在看尚硅谷韩老师的数据结构这门课,对于链表有了一定的认识,这里做一下学习记录。
首先,双向链表与单链表相比,需要考虑前一个结点的指向,所以在单链表的基础上去考虑双向链表相对来说比较容易一点。
首先还是需要先创建一个Node类,与单链表相比,多了个pre,用来表示前一个结点的指向。
//创建一个node类
class Node{
public int id;
public String name;
public Node pre; //指向前一个结点
public Node next; //指向后一个结点
public Node(int id, String name) {
this.id = id;
this.name = name;
}
}
然后创建双向链表类,类中包含各种方法
class DoubleLinkedList{
//初始化头结点
private Node head = new Node(0,"");
//头插法
public void addHead(Node node){
node.next = this.head.next;
node.pre = this.head;
this.head.next = node;
}
//尾插法
public void addTail(Node node){
Node temp = head;
boolean flag = false;
while(true){
if(temp.next == null){
flag = true;
break;
}
temp = temp.next;
}
if(flag){
temp.next = node;
node.pre = temp;
}
}
//顺序插入
public void addByOrder(Node node){
Node temp = head;
boolean flag = false;
while (true){
if (temp.next == null) {// 说明temp已经在链表的最后
break;
}
if(temp.next.id > node.id){
break;
}else if(temp.next.id==node.id){
flag = true;
break;
}
temp = temp.next;
}
if(flag){
System.out.println("该位置已有元素");
}else{
node.next = temp.next;
if(temp.next != null) {
temp.next.pre = node;
}
temp.next = node;
node.pre = temp;
}
}
//修改结点
public void update(Node node){
if(head.next==null){
System.out.println("该链表为空");
return;
}
Node temp = head.next;
boolean flag = false;
while (true){
if(temp.id == node.id){
flag=true;
break;
}
temp = temp.next;
}
if(flag){
temp.name = node.name;
}
}
//删除结点
public void delete(int id){
if(head.next==null){
System.out.println("该链表为空");
return;
}
Node temp = head.next;
boolean flag = false;
while (true){
if(temp.id == id){
flag = true;
break;
}
temp = temp.next;
}
if(flag){
temp.pre.next = temp.next;
if (temp.next != null) {
temp.next.pre = temp.pre;
}
}
}
//遍历结点
public void getAllNode(){
if(head.next==null){
System.out.println("该链表为空");
return;
}
Node temp = head.next;
while(true){
if(temp == null){
break;
}
System.out.println(temp);
temp = temp.next;
}
}
}
最后进行测试,完整代码如下:
package com.mzz.queue.DoubleLinkedList;
public class DoubleLinkedListDemo {
public static void main(String[] args) {
Node node1 = new Node(1,"aa");
Node node2 = new Node(2,"bb");
Node node3 = new Node(3,"cc");
Node node4 = new Node(4,"dd");
Node node5 = new Node(5,"ee");
DoubleLinkedList d = new DoubleLinkedList();
//头插法
// d.addHead(node1);
// d.addHead(node2);
// d.addHead(node3);
// d.addHead(node4);
// d.addHead(node5);
// d.getAllNode();
//尾插法
d.addTail(node1);
d.addTail(node2);
d.addTail(node3);
d.addTail(node4);
d.addTail(node5);
// d.getAllNode();
//顺序插入
// d.addByOrder(node2);
// d.addByOrder(node4);
// d.addByOrder(node3);
// d.addByOrder(node5);
// d.addByOrder(node1);
// d.getAllNode();
//修改结点
// d.update(new Node(3,"gg"));
// d.getAllNode();
//删除结点
// d.delete(3);
// d.getAllNode();
}
}
class DoubleLinkedList{
//初始化头结点
private Node head = new Node(0,"");
//头插法
public void addHead(Node node){
node.next = this.head.next;
node.pre = this.head;
this.head.next = node;
}
//尾插法
public void addTail(Node node){
Node temp = head;
boolean flag = false;
while(true){
if(temp.next == null){
flag = true;
break;
}
temp = temp.next;
}
if(flag){
temp.next = node;
node.pre = temp;
}
}
//顺序插入
public void addByOrder(Node node){
Node temp = head;
boolean flag = false;
while (true){
if (temp.next == null) {// 说明temp已经在链表的最后
break;
}
if(temp.next.id > node.id){
break;
}else if(temp.next.id==node.id){
flag = true;
break;
}
temp = temp.next;
}
if(flag){
System.out.println("该位置已有元素");
}else{
node.next = temp.next;
if(temp.next != null) {
temp.next.pre = node;
}
temp.next = node;
node.pre = temp;
}
}
//修改结点
public void update(Node node){
if(head.next==null){
System.out.println("该链表为空");
return;
}
Node temp = head.next;
boolean flag = false;
while (true){
if(temp.id == node.id){
flag=true;
break;
}
temp = temp.next;
}
if(flag){
temp.name = node.name;
}
}
//删除结点
public void delete(int id){
if(head.next==null){
System.out.println("该链表为空");
return;
}
Node temp = head.next;
boolean flag = false;
while (true){
if(temp.id == id){
flag = true;
break;
}
temp = temp.next;
}
if(flag){
temp.pre.next = temp.next;
if (temp.next != null) {
temp.next.pre = temp.pre;
}
}
}
//遍历结点
public void getAllNode(){
if(head.next==null){
System.out.println("该链表为空");
return;
}
Node temp = head.next;
while(true){
if(temp == null){
break;
}
System.out.println(temp);
temp = temp.next;
}
}
}
//创建一个node类
class Node{
public int id;
public String name;
public Node pre; //指向前一个结点
public Node next; //指向后一个结点
public Node(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "Node{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
测试结果
1.头插法:第一个插入id为1的,随后依次插入头部
2. 尾插法
3.顺序插入:可以看到addByOrder加入的顺序乱的,得出的结果是有顺序的
4.修改结点:id为3的dd改为gg,结果成功
5.删除结点:可以看到id为3的结点成功删除
对于链表,最好的理解办法就是画图,通过画图就很容易将代码写出来