苦行僧DH

博客园 首页 新随笔 联系 订阅 管理

数据结构:双向链表

目录:

1、简介

2、简单使用

  1、创建节点

  2、创建链表对象

  3、判断是否为空的方法

  4、判断该节点是否已经存在的方法

  5、将节点添加到链表尾部

  6、将节点添加到链表中,保持从小到大的顺序

    7、修改节点

  8、删除节点

  9、全部源码

 

 

 

1、简介

在说双向链表之前,肯定要先说一下单向链表,因为双向链表是在单向链表的基础上进行修改。【单链表】

那么我们这里简单的画一个单链表的图:

 

 

单链表每个节点都有一个next属性,都指向了下一个节点,这就形成了一个链表的结构,那么这次记录的双向链表,表如其名,我们的单链表只是每个节点只有一个next属性指向其他节点,而我们的双向链表不仅仅有next属性,还有pre属性。

 

 

 

这个图应该还是挺清晰的哈,双向链表在原单向链表的基础上增加了一个pre属性,指向了当前节点的前一个结点。

 

 

2、简单使用

 

 

1)创建节点

 

 1 /*节点*/
 2 /*英雄类-水浒传*/
 3 class HeroNode2 {
 4 
 5     public int no;
 6     public String name;
 7     public String nickName;
 8 
 9     public HeroNode2 next;
10     public HeroNode2 pre;
11 
12     public HeroNode2() {
13     }
14 
15     public HeroNode2(int no, String name, String nickName) {
16         this.no = no;
17         this.name = name;
18         this.nickName = nickName;
19     }
20 
21     @Override
22     public String toString() {
23         return "HeroNode2{" +
24                 "no=" + no +
25                 ", name='" + name + '\'' +
26                 ", nickName='" + nickName + '\'' +
27                 '}';
28     }
29 }
英雄节点

 节点中no、name、nickName为基础字段,为该节点存储的数据,pre和next分别指向前一个节点和后一个节点

2、创建链表对象

 

1 /*双向链表*/
2 class DoubleLinkedList {
3 
4     /*头节点*/
5     private HeroNode2 head = new HeroNode2();
6 }
链表对象

 

创建一个链表对象来存放操作双向链表的方法

 

3、判断是否为空的方法

 如果头节点的next为空,那么就说明该链表中没有数据

/*判断链表是否为空*/
    public boolean isEmpty() {
        return head.next == null;
    }
判断链表是否为空(存放到DoubleLinkedList中)

 

4、判断该节点是否已经存在的方法

 1  /*判断该节点是否已经存在与链表中*/
 2     public boolean isExits(HeroNode2 heroNode) {
 3         if (isEmpty()) {
 4             return false;
 5         }
 6         HeroNode2 tmp = head.next;
 7         while (true) {
 8             if (tmp == heroNode) {
 9                 return true;
10             }
11             if (tmp == null) {
12                 return false;
13             }
14             tmp = tmp.next;
15         }
16     }
判断该节点是否已经存在(存放在DoubleLinkedList中)

 首先判断是否为空,如果为空,那肯定不存在,如果不为空,那么就遍历链表进行判断

 

5、将节点添加到链表的底部

 

 1 /*将节点添加到链表的底部*/
 2     public boolean addHeroNode(HeroNode2 heroNode) {
 3         /*如果为空,那么直接添加到链表的底部*/
 4         if (isEmpty()) {
 5             head.next = heroNode;
 6             heroNode.pre = head;
 7             return true;
 8         }
 9         /*判断是否已经存在于链表中*/
10         if (isExits(heroNode)) {
11             System.err.println(heroNode + "已经存在于链表中不能添加");
12             return false;
13         }
14         HeroNode2 tmp = head.next;
15         while (true) {
16             if (tmp.next == null) {
17                 tmp.next = heroNode;
18                 heroNode.pre = tmp;
19                 return true;
20             } else {
21                 tmp = tmp.next;
22             }
23         }
24     }
将节点添加到链表的底部(存放在DoubleLinkedList中)

先判断是否为空,如果为空那么就直接放置到头结点的next中,然后把头结点放置到节点的pre中。

如果不为空,那么就遍历,只要遍历到尾部,例如尾部节点为end,我们需要加进去的节点为node,那么只需要将node赋值给end.next,然后将end赋值给node.pre,那么end的next往后的一条线和node.pre往前的一条线就连成了。

 

 6、将节点添加到链表,保持从小到大的顺序

 1 /*将节点添加到链表中,保持从小到大的顺序*/
 2     public boolean addHeroNodeOrder(HeroNode2 heroNode) {
 3         /*如果为空,那么直接添加到尾部*/
 4         if (isEmpty()) {
 5             head.next = heroNode;
 6             heroNode.pre = head;
 7             return true;
 8         }
 9         /*判断该节点是否存在于链表中,如果存在,则不要进行添加*/
10         /*判断是否已经存在于链表中*/
11         if (isExits(heroNode)) {
12             System.err.println(heroNode + "已经存在于链表中不能添加");
13             return false;
14         }
15         /*从第一个元素开始遍历*/
16         HeroNode2 tmp = head.next;
17         while (true) {
18             if (tmp.no > heroNode.no) {
19                 /*如果当前节点的no大于需要添加的节点的no,那么就将需要加入的节点放置到当前节点的前一个*/
20                 tmp.pre.next = heroNode;
21                 heroNode.pre = tmp.pre;
22                 tmp.pre = heroNode;
23                 heroNode.next = tmp;
24                 return true;
25             } else if (tmp.next == null) {
26                 /*tmp的下一个为空,说明已经完了,直接加到末尾*/
27                 tmp.next = heroNode;
28                 heroNode.pre = tmp;
29                 return true;
30             } else {
31                 tmp = tmp.next;
32             }
33         }
34     }
将节点添加到链表的同时保持顺序(DoubleLinkedList)

 

首先是判断是否为空,如果为空,那么就直接添加到head后。

然后再判断该节点是否已经存在,如果已经存在,那么则不能添加。

然后遍历链表,如果当前当前遍历到的节点为current,然后需要添加的节点为node

如果current的no大于node的no的话,那么我们就需要将node存到current的前面去。

首先让current的pre的next指向node,然后node.pre就等于current.pre,然后至此,current的前一个节点就会指向current,然后我们需要做的就是将current的pre指向我们的node,最后我们需要将node.next指向我们的current。

 

7、修改节点

 1   /*修改节点数据,通过no*/
 2     public boolean update(HeroNode2 heroNode2) {
 3         if (isEmpty()) {
 4             System.err.println("链表为空!");
 5             return false;
 6         }
 7         HeroNode2 tmp = head.next;
 8         while (tmp != null) {
 9             if (tmp.no == heroNode2.no) {
10                 tmp.name = heroNode2.name;
11                 tmp.nickName = heroNode2.nickName;
12                 return true;
13             } else {
14                 tmp = tmp.next;
15             }
16         }
17         return false;
18     }
修改节点(存放在DoubleLinkedList中)

 

这个没啥逻辑,就是遍历,找到了就修改name和nickName 

 

 

 8、删除节点

 

 1     /*删除节点*/
 2     public boolean delByNo(Integer no) {
 3         if (isEmpty()) {
 4             System.err.println("当前链表为空,无法删除");
 5             return false;
 6         }
 7         HeroNode2 tmp = head.next;
 8         /*可能有多个相同no的节点,所以当成立删除时并不停止。*/
 9         boolean flag = false;
10         while (tmp != null) {
11             if (tmp.no == no) {
12                 /**/
13                 tmp.pre.next = tmp.next;
14                 tmp.next.pre = tmp.pre;
15                 flag = true;
16             }
17             tmp = tmp.next;
18         }
19         return flag;
20     }
删除节点(存放在DoubleLinkedList)

 

 

遍历,如果当前节点的no就是我们需要删除的no,假设我们当前节点为current,然后需要删除的no为3

那么就是如果current.no==3的话,那么我们current的pre的next就等于node.next,然后node.next.pre就等于我们current的pre。

 

9、全部源码

 

  1 package t4;
  2 
  3 
  4 import t2.Test;
  5 
  6 import java.util.Random;
  7 
  8 /**
  9  * @author 自在仙
 10  * @create 2020年04月19  12:20
 11  */
 12 public class DoubleLinkedListDemo {
 13 
 14     public static void main(String[] args) {
 15         DoubleLinkedList doubleLinkedList = new DoubleLinkedList();
 16         HeroNode2 heroNode = new HeroNode2(1, "林冲", "林大哥");
 17         HeroNode2 heroNode2 = new HeroNode2(2, "林冲2", "林大哥");
 18         HeroNode2 heroNode3 = new HeroNode2(3, "林冲3", "林大哥");
 19         HeroNode2 heroNode5 = new HeroNode2(3, "林冲3", "林大哥");
 20         HeroNode2 heroNode4 = new HeroNode2(4, "林冲4", "林大哥");
 21         doubleLinkedList.addHeroNodeOrder(heroNode4);
 22         doubleLinkedList.addHeroNodeOrder(heroNode3);
 23         doubleLinkedList.addHeroNodeOrder(heroNode5);
 24         doubleLinkedList.addHeroNodeOrder(heroNode);
 25         doubleLinkedList.addHeroNodeOrder(heroNode2);
 26 /*
 27         doubleLinkedList.display();
 28 
 29         doubleLinkedList.delByNo(3);
 30 
 31         System.out.println("-------------");*/
 32 
 33         doubleLinkedList.display();
 34 
 35     }
 36 }
 37 
 38 /*双向链表*/
 39 class DoubleLinkedList {
 40 
 41     /*头节点*/
 42     private HeroNode2 head = new HeroNode2();
 43 
 44     /*判断链表是否为空*/
 45     public boolean isEmpty() {
 46         return head.next == null;
 47     }
 48 
 49     /*将节点添加到链表的底部*/
 50     public boolean addHeroNode(HeroNode2 heroNode) {
 51         /*如果为空,那么直接添加到链表的底部*/
 52         if (isEmpty()) {
 53             head.next = heroNode;
 54             heroNode.pre = head;
 55             return true;
 56         }
 57         /*判断是否已经存在于链表中*/
 58         if (isExits(heroNode)) {
 59             System.err.println(heroNode + "已经存在于链表中不能添加");
 60             return false;
 61         }
 62         HeroNode2 tmp = head.next;
 63         while (true) {
 64             if (tmp.next == null) {
 65                 tmp.next = heroNode;
 66                 heroNode.pre = tmp;
 67                 return true;
 68             } else {
 69                 tmp = tmp.next;
 70             }
 71         }
 72     }
 73 
 74     /*将节点添加到链表中,保持从小到大的顺序*/
 75     public boolean addHeroNodeOrder(HeroNode2 heroNode) {
 76         /*如果为空,那么直接添加到尾部*/
 77         if (isEmpty()) {
 78             head.next = heroNode;
 79             heroNode.pre = head;
 80             return true;
 81         }
 82         /*判断该节点是否存在于链表中,如果存在,则不要进行添加*/
 83         /*判断是否已经存在于链表中*/
 84         if (isExits(heroNode)) {
 85             System.err.println(heroNode + "已经存在于链表中不能添加");
 86             return false;
 87         }
 88         /*从第一个元素开始遍历*/
 89         HeroNode2 tmp = head.next;
 90         while (true) {
 91             if (tmp.no > heroNode.no) {
 92                 /*如果当前节点的no大于需要添加的节点的no,那么就将需要加入的节点放置到当前节点的前一个*/
 93                 tmp.pre.next = heroNode;
 94                 heroNode.pre = tmp.pre;
 95                 tmp.pre = heroNode;
 96                 heroNode.next = tmp;
 97                 return true;
 98             } else if (tmp.next == null) {
 99                 /*tmp的下一个为空,说明已经完了,直接加到末尾*/
100                 tmp.next = heroNode;
101                 heroNode.pre = tmp;
102                 return true;
103             } else {
104                 tmp = tmp.next;
105             }
106         }
107     }
108 
109     /*删除节点*/
110     public boolean delByNo(Integer no) {
111         if (isEmpty()) {
112             System.err.println("当前链表为空,无法删除");
113             return false;
114         }
115         HeroNode2 tmp = head.next;
116         /*可能有多个相同no的节点,所以当成立删除时并不停止。*/
117         boolean flag = false;
118         while (tmp != null) {
119             if (tmp.no == no) {
120                 /**/
121                 tmp.pre.next = tmp.next;
122                 tmp.next.pre = tmp.pre;
123                 flag = true;
124             }
125             tmp = tmp.next;
126         }
127         return flag;
128     }
129 
130     /*修改节点数据,通过no*/
131     public boolean update(HeroNode2 heroNode2) {
132         if (isEmpty()) {
133             System.err.println("链表为空!");
134             return false;
135         }
136         HeroNode2 tmp = head.next;
137         while (tmp != null) {
138             if (tmp.no == heroNode2.no) {
139                 tmp.name = heroNode2.name;
140                 tmp.nickName = heroNode2.nickName;
141                 return true;
142             } else {
143                 tmp = tmp.next;
144             }
145         }
146         return false;
147     }
148 
149     /*判断该节点是否已经存在与链表中*/
150     public boolean isExits(HeroNode2 heroNode) {
151         if (isEmpty()) {
152             return false;
153         }
154         HeroNode2 tmp = head.next;
155         while (true) {
156             if (tmp == heroNode) {
157                 return true;
158             }
159             if (tmp == null) {
160                 return false;
161             }
162             tmp = tmp.next;
163         }
164     }
165 
166     /*遍历该链表*/
167     public void display() {
168         if (isEmpty()) {
169             System.out.println("当前链表为空");
170         }
171         HeroNode2 temp = head.next;
172         while (temp != null) {
173             System.out.println(temp);
174             temp = temp.next;
175         }
176     }
177 
178 }
179 
180 /*节点*/
181 /*英雄类-水浒传*/
182 class HeroNode2 {
183 
184     public int no;
185     public String name;
186     public String nickName;
187 
188     public HeroNode2 next;
189     public HeroNode2 pre;
190 
191     public HeroNode2() {
192     }
193 
194     public HeroNode2(int no, String name, String nickName) {
195         this.no = no;
196         this.name = name;
197         this.nickName = nickName;
198     }
199 
200     @Override
201     public String toString() {
202         return "HeroNode2{" +
203                 "no=" + no +
204                 ", name='" + name + '\'' +
205                 ", nickName='" + nickName + '\'' +
206                 '}';
207     }
208 }
所有源码,

 

 

如果有说错了的地方,请您联系我,QQ:2366567504,万分抱歉。

 

posted on 2020-04-21 15:40  苦行僧DH  阅读(385)  评论(0编辑  收藏  举报