单链表介绍和内存布局
链表(Linked List)是有序的列表,但他在内存中的存储如下图:
结论:
- 链表是以节点的方式来存储,是链式存储;
- 每个节点包含data域,next域(来指向下一个节点);
- 根据图发现,链表的各个节点不一定是连续存放;
- 链表分带头节点的链表和没带头的链表;
单链表(带头节点)逻辑结构示意图:
单链表创建和遍历的分析实现
单链表的应用实例
使用带head头的单项链表实现-水浒传英雄排行榜的管理,要求:
- 完成对英雄任务的CRUD操作;
- 第一种方法在添加英雄时,直接添加到链表尾部;
- 第二种方式在添加英雄时,根据排名将英雄插入到指定位置(如果该排名存在,则添加失败并提示);
单链表代码实现分析
添加(创建):
- 先创建一个head头节点,作用就是表示单链表的头;
- 后面我们每添加一个节点,就直接加入到链表的最后遍历;
- 通过一个辅助变量,帮助遍历整个链表;
代码实现
第一种方法实现代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
| package com.jokerdig.linkedlist;
public class SIngleLinkedListDemo { public static void main(String[] args) { HeroNode hero1 = new HeroNode(1,"宋江","及时雨"); HeroNode hero2 = new HeroNode(2,"卢俊义","玉麒麟"); HeroNode hero3 = new HeroNode(3,"吴用","智多星"); HeroNode hero4 = new HeroNode(4,"武松","行者"); HeroNode hero5 = new HeroNode(5,"林冲","豹子头"); SingleLinkedList singleLinkedList = new SingleLinkedList(); singleLinkedList.add(hero1); singleLinkedList.add(hero2); singleLinkedList.add(hero3); singleLinkedList.add(hero4); singleLinkedList.add(hero5); singleLinkedList.list(); } }
class SingleLinkedList{ private HeroNode head = new HeroNode(0,"","");
public void add(HeroNode heroNode){ HeroNode temp = head; while(true){ if(temp.next==null){ break; } temp = temp.next; } temp.next = heroNode; }
public void list(){ if(head.next == null){ System.out.println("链表为空"); return; } HeroNode temp = head.next; while(true){ if(temp == null){ break; } System.out.println(temp); temp = temp.next; } } }
class HeroNode{ public int no; public String name; public String nickname; public HeroNode next;
public HeroNode(int no,String name,String hickname){ this.no = no; this.name = name; this.nickname = hickname; }
@Override public String toString() { return "HeroNode{" + "no=" + no + ", name='" + name + '\'' + ", nickname='" + nickname + '}'; } }
|
运行结果
1 2 3 4 5 6 7
| HeroNode{no=1, name='宋江', nickname='及时雨} HeroNode{no=2, name='卢俊义', nickname='玉麒麟} HeroNode{no=3, name='吴用', nickname='智多星} HeroNode{no=4, name='武松', nickname='行者} HeroNode{no=5, name='林冲', nickname='豹子头}
Process finished with exit code 0
|
单链表按顺序插入节点
思路分析
需要按照编号的顺序添加:
- 首先找到新添加的节点位置,通过辅助变量(指针),使用遍历来定位;
- 新的节点next = temp.next
- 将temp.next = 新节点
代码实现
第二种方法实现代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
| package com.jokerdig.linkedlist;
public class SIngleLinkedListDemo { public static void main(String[] args) { HeroNode hero1 = new HeroNode(1,"宋江","及时雨"); HeroNode hero2 = new HeroNode(2,"卢俊义","玉麒麟"); HeroNode hero3 = new HeroNode(3,"吴用","智多星"); HeroNode hero4 = new HeroNode(4,"武松","行者"); HeroNode hero5 = new HeroNode(5,"林冲","豹子头"); SingleLinkedList singleLinkedList = new SingleLinkedList(); singleLinkedList.addByOrder(hero1); singleLinkedList.addByOrder(hero5); singleLinkedList.addByOrder(hero2); singleLinkedList.addByOrder(hero4); singleLinkedList.addByOrder(hero3); singleLinkedList.addByOrder(hero3); singleLinkedList.list();
} }
class SingleLinkedList{ private HeroNode head = new HeroNode(0,"","");
public void add(HeroNode heroNode){ HeroNode temp = head; while(true){ if(temp.next==null){ break; } temp = temp.next; } temp.next = heroNode; }
public void addByOrder(HeroNode heroNode){ HeroNode temp = head; boolean flag = false; while(true){ if(temp.next == null){ break; } if(temp.next.no>heroNode.no){ break; }else if(temp.next.no == heroNode.no){ flag = true; break; } temp = temp.next; } if(flag){ System.out.println("该英雄编号"+heroNode.no+"已经存在"); }else{ heroNode.next = temp.next; temp.next = heroNode;
}
}
public void list(){ if(head.next == null){ System.out.println("链表为空"); return; } HeroNode temp = head.next; while(true){ if(temp == null){ break; } System.out.println(temp); temp = temp.next; } } }
class HeroNode{ public int no; public String name; public String nickname; public HeroNode next;
public HeroNode(int no,String name,String hickname){ this.no = no; this.name = name; this.nickname = hickname; }
@Override public String toString() { return "HeroNode{" + "no=" + no + ", name='" + name + '\'' + ", nickname='" + nickname + '}'; } }
|
运行结果
1 2 3 4 5 6 7 8
| 该英雄编号3已经存在 HeroNode{no=1, name='宋江', nickname='及时雨} HeroNode{no=2, name='卢俊义', nickname='玉麒麟} HeroNode{no=3, name='吴用', nickname='智多星} HeroNode{no=4, name='武松', nickname='行者} HeroNode{no=5, name='林冲', nickname='豹子头}
Process finished with exit code 0
|
单链表节点的修改
修改代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
| package com.jokerdig.linkedlist;
public class SIngleLinkedListDemo { public static void main(String[] args) { HeroNode hero1 = new HeroNode(1,"宋江","及时雨"); HeroNode hero2 = new HeroNode(2,"卢俊义","玉麒麟"); HeroNode hero3 = new HeroNode(3,"吴用","智多星"); HeroNode hero4 = new HeroNode(4,"武松","行者"); HeroNode hero5 = new HeroNode(5,"林冲","豹子头"); SingleLinkedList singleLinkedList = new SingleLinkedList(); singleLinkedList.addByOrder(hero1); singleLinkedList.addByOrder(hero5); singleLinkedList.addByOrder(hero2); singleLinkedList.addByOrder(hero4); singleLinkedList.addByOrder(hero3); singleLinkedList.addByOrder(hero3); singleLinkedList.list(); singleLinkedList.update(new HeroNode(1,"不是松江","不是及时雨")); singleLinkedList.update(new HeroNode(7,"巴拉巴拉","巴拉巴拉")); System.out.println("============修改后的链表============="); singleLinkedList.list(); } }
class SingleLinkedList{ private HeroNode head = new HeroNode(0,"","");
public void add(HeroNode heroNode){ HeroNode temp = head; while(true){ if(temp.next==null){ break; } temp = temp.next; } temp.next = heroNode; }
public void addByOrder(HeroNode heroNode){ HeroNode temp = head; boolean flag = false; while(true){ if(temp.next == null){ break; } if(temp.next.no>heroNode.no){ break; }else if(temp.next.no == heroNode.no){ flag = true; break; } temp = temp.next; } if(flag){ System.out.println("该英雄编号"+heroNode.no+"已经存在"); }else{ heroNode.next = temp.next; temp.next = heroNode; } }
public void update(HeroNode newHeroNode){ if(head.next == null){ System.out.println("链表为空"); return; } HeroNode temp = head.next; boolean flag = false; while(true){ if(temp == null){ break; } if(temp.no == newHeroNode.no){ flag = true; break; } temp = temp.next; } if(flag){ temp.name = newHeroNode.name; temp.nickname = newHeroNode.nickname; }else{ System.out.println("编号为:"+newHeroNode.no+"的英雄未在链表中找到"); } }
public void list(){ if(head.next == null){ System.out.println("链表为空"); return; } HeroNode temp = head.next; while(true){ if(temp == null){ break; } System.out.println(temp); temp = temp.next; } } }
class HeroNode{ public int no; public String name; public String nickname; public HeroNode next;
public HeroNode(int no,String name,String hickname){ this.no = no; this.name = name; this.nickname = hickname; }
@Override public String toString() { return "HeroNode{" + "no=" + no + ", name='" + name + '\'' + ", nickname='" + nickname + '}'; } }
|
运行结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 该英雄编号3已经存在 HeroNode{no=1, name='宋江', nickname='及时雨} HeroNode{no=2, name='卢俊义', nickname='玉麒麟} HeroNode{no=3, name='吴用', nickname='智多星} HeroNode{no=4, name='武松', nickname='行者} HeroNode{no=5, name='林冲', nickname='豹子头} 编号为:7的英雄未在链表中找到 ============修改后的链表============= HeroNode{no=1, name='不是松江', nickname='不是及时雨} HeroNode{no=2, name='卢俊义', nickname='玉麒麟} HeroNode{no=3, name='吴用', nickname='智多星} HeroNode{no=4, name='武松', nickname='行者} HeroNode{no=5, name='林冲', nickname='豹子头}
Process finished with exit code 0
|
单链表节点的删除
思路分析
从单链表删除一个节点:
- 创建辅助变量temp,先找到需要删除节点的前一个节点;
- temp.next = temp.next.next;
- 而要删除的那个节点(没有引用指向),就会被Java的GC垃圾回收机制回收掉;
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
| package com.jokerdig.linkedlist;
public class SIngleLinkedListDemo { public static void main(String[] args) { HeroNode hero1 = new HeroNode(1,"宋江","及时雨"); HeroNode hero2 = new HeroNode(2,"卢俊义","玉麒麟"); HeroNode hero3 = new HeroNode(3,"吴用","智多星"); HeroNode hero4 = new HeroNode(4,"武松","行者"); HeroNode hero5 = new HeroNode(5,"林冲","豹子头"); SingleLinkedList singleLinkedList = new SingleLinkedList(); singleLinkedList.addByOrder(hero1); singleLinkedList.addByOrder(hero5); singleLinkedList.addByOrder(hero2); singleLinkedList.addByOrder(hero4); singleLinkedList.addByOrder(hero3); singleLinkedList.addByOrder(hero3); singleLinkedList.list(); singleLinkedList.update(new HeroNode(1,"不是松江","不是及时雨")); singleLinkedList.update(new HeroNode(7,"巴拉巴拉","巴拉巴拉")); System.out.println("============修改后的链表============="); singleLinkedList.list();
singleLinkedList.delete(5); singleLinkedList.delete(6); System.out.println("============删除后的链表============="); singleLinkedList.list(); } }
class SingleLinkedList{ private HeroNode head = new HeroNode(0,"","");
public void add(HeroNode heroNode){ HeroNode temp = head; while(true){ if(temp.next==null){ break; } temp = temp.next; } temp.next = heroNode; }
public void addByOrder(HeroNode heroNode){ HeroNode temp = head; boolean flag = false; while(true){ if(temp.next == null){ break; } if(temp.next.no>heroNode.no){ break; }else if(temp.next.no == heroNode.no){ flag = true; break; } temp = temp.next; } if(flag){ System.out.println("该英雄编号"+heroNode.no+"已经存在"); }else{ heroNode.next = temp.next; temp.next = heroNode; } }
public void update(HeroNode newHeroNode){ if(head.next == null){ System.out.println("链表为空"); return; } HeroNode temp = head.next; boolean flag = false; while(true){ if(temp == null){ break; } if(temp.no == newHeroNode.no){ flag = true; break; } temp = temp.next; } if(flag){ temp.name = newHeroNode.name; temp.nickname = newHeroNode.nickname; }else{ System.out.println("编号为:"+newHeroNode.no+"的英雄未在链表中找到"); } }
public void delete(int deleteNo){ HeroNode temp = head; boolean flag = false; while(true){ if(temp.next == null){ break; } if(temp.next.no == deleteNo){ flag = true; break; } temp = temp.next; } if(flag){ temp.next = temp.next.next; }else{ System.out.println("要删除的节点"+deleteNo+"不存在"); } }
public void list(){ if(head.next == null){ System.out.println("链表为空"); return; } HeroNode temp = head.next; while(true){ if(temp == null){ break; } System.out.println(temp); temp = temp.next; } } }
class HeroNode{ public int no; public String name; public String nickname; public HeroNode next;
public HeroNode(int no,String name,String hickname){ this.no = no; this.name = name; this.nickname = hickname; }
@Override public String toString() { return "HeroNode{" + "no=" + no + ", name='" + name + '\'' + ", nickname='" + nickname + '}'; } }
|
运行结果
1 2 3 4 5 6 7 8 9 10 11 12 13
| HeroNode{no=1, name='不是松江', nickname='不是及时雨} HeroNode{no=2, name='卢俊义', nickname='玉麒麟} HeroNode{no=3, name='吴用', nickname='智多星} HeroNode{no=4, name='武松', nickname='行者} HeroNode{no=5, name='林冲', nickname='豹子头} 要删除的节点6不存在 ============删除后的链表============= HeroNode{no=1, name='不是松江', nickname='不是及时雨} HeroNode{no=2, name='卢俊义', nickname='玉麒麟} HeroNode{no=3, name='吴用', nickname='智多星} HeroNode{no=4, name='武松', nickname='行者}
Process finished with exit code 0
|
单链表面试题
单链表常见面试题:
- 求单链表中有效节点的个数;
- 查找单链表中的倒数第k个节点;
- 单链表的反转;
- 从尾到头打印单链表(方式1:反向遍历,方式2:Stack栈);
第一题
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
| package com.jokerdig.linkedlist;
public class SingleLinkedListTest1 { public static void main(String[] args) { HeroNode1 hero1 = new HeroNode1(1,"宋江","及时雨"); HeroNode1 hero2 = new HeroNode1(2,"卢俊义","玉麒麟"); HeroNode1 hero3 = new HeroNode1(3,"吴用","智多星"); HeroNode1 hero4 = new HeroNode1(4,"武松","行者"); HeroNode1 hero5 = new HeroNode1(5,"林冲","豹子头"); SingleLinkedList1 singleLinkedList = new SingleLinkedList1(); singleLinkedList.addByOrder(hero1); singleLinkedList.addByOrder(hero5); singleLinkedList.addByOrder(hero2); singleLinkedList.addByOrder(hero4); singleLinkedList.addByOrder(hero3); singleLinkedList.list(); System.out.println("有"+getLength(singleLinkedList.getHead())+"个有效节点"); }
public static int getLength(HeroNode1 head){ if(head.next == null){ return 0; } int length = 0; HeroNode1 cur = head.next; while(cur!=null){ length++; cur = cur.next; } return length; }
}
class SingleLinkedList1{ private HeroNode1 head = new HeroNode1(0,"",""); public HeroNode1 getHead() { return head; }
public void addByOrder(HeroNode1 heroNode){ HeroNode1 temp = head; boolean flag = false; while(true){ if(temp.next == null){ break; } if(temp.next.no>heroNode.no){ break; }else if(temp.next.no == heroNode.no){ flag = true; break; } temp = temp.next; } if(flag){ System.out.println("该英雄编号"+heroNode.no+"已经存在"); }else{ heroNode.next = temp.next; temp.next = heroNode; } }
public void list(){ if(head.next == null){ System.out.println("链表为空"); return; } HeroNode1 temp = head.next; while(true){ if(temp == null){ break; } System.out.println(temp); temp = temp.next; } } }
class HeroNode1{ public int no; public String name; public String nickname; public HeroNode1 next;
public HeroNode1(int no,String name,String hickname){ this.no = no; this.name = name; this.nickname = hickname; }
@Override public String toString() { return "HeroNode1{" + "no=" + no + ", name='" + name + '\'' + ", nickname='" + nickname + '}'; } }
|
运行结果
1 2 3 4 5 6 7 8
| HeroNode1{no=1, name='宋江', nickname='及时雨} HeroNode1{no=2, name='卢俊义', nickname='玉麒麟} HeroNode1{no=3, name='吴用', nickname='智多星} HeroNode1{no=4, name='武松', nickname='行者} HeroNode1{no=5, name='林冲', nickname='豹子头} 有5个有效节点
Process finished with exit code 0
|
第二题
思路分析:
- 编写一个方法,接收head节点,同时接收一个index(表示倒数第index个节点);
- 先把链表从头到尾遍历,得到链表的总长度getLength;
- 得到size,从链表第一个开始遍历到(seiz-index)个;
- 如果找到就返回该节点,否则返回null;
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
| package com.jokerdig.linkedlist;
public class SingleLinkedListTest1 { public static void main(String[] args) { HeroNode1 hero1 = new HeroNode1(1,"宋江","及时雨"); HeroNode1 hero2 = new HeroNode1(2,"卢俊义","玉麒麟"); HeroNode1 hero3 = new HeroNode1(3,"吴用","智多星"); HeroNode1 hero4 = new HeroNode1(4,"武松","行者"); HeroNode1 hero5 = new HeroNode1(5,"林冲","豹子头"); SingleLinkedList1 singleLinkedList = new SingleLinkedList1(); singleLinkedList.addByOrder(hero1); singleLinkedList.addByOrder(hero5); singleLinkedList.addByOrder(hero2); singleLinkedList.addByOrder(hero4); singleLinkedList.addByOrder(hero3); singleLinkedList.list(); HeroNode1 res = findLastIndexNode(singleLinkedList.getHead(),1); System.out.println("res="+res);
}
public static int getLength(HeroNode1 head){ if(head.next == null){ return 0; } int length = 0; HeroNode1 cur = head.next; while(cur!=null){ length++; cur = cur.next; } return length; }
public static HeroNode1 findLastIndexNode(HeroNode1 head,int index){ if(head.next == null){ return null; } int size = getLength(head); if(index <= 0|| index>size){ return null; } HeroNode1 cur = head.next; for (int i = 0; i < size - index; i++) { cur = cur.next; } return cur; }
}
class SingleLinkedList1{ private HeroNode1 head = new HeroNode1(0,"",""); public HeroNode1 getHead() { return head; }
public void addByOrder(HeroNode1 heroNode){ HeroNode1 temp = head; boolean flag = false; while(true){ if(temp.next == null){ break; } if(temp.next.no>heroNode.no){ break; }else if(temp.next.no == heroNode.no){ flag = true; break; } temp = temp.next; } if(flag){ System.out.println("该英雄编号"+heroNode.no+"已经存在"); }else{ heroNode.next = temp.next; temp.next = heroNode; } }
public void list(){ if(head.next == null){ System.out.println("链表为空"); return; } HeroNode1 temp = head.next; while(true){ if(temp == null){ break; } System.out.println(temp); temp = temp.next; } } }
class HeroNode1{ public int no; public String name; public String nickname; public HeroNode1 next;
public HeroNode1(int no,String name,String hickname){ this.no = no; this.name = name; this.nickname = hickname; }
@Override public String toString() { return "HeroNode1{" + "no=" + no + ", name='" + name + '\'' + ", nickname='" + nickname + '}'; } }
|
运行结果
1 2 3 4 5 6 7 8 9
| HeroNode1{no=1, name='宋江', nickname='及时雨} HeroNode1{no=2, name='卢俊义', nickname='玉麒麟} HeroNode1{no=3, name='吴用', nickname='智多星} HeroNode1{no=4, name='武松', nickname='行者} HeroNode1{no=5, name='林冲', nickname='豹子头} res=HeroNode1{no=5, name='林冲', nickname='豹子头}
Process finished with exit code 0
|
第三题
思路分析:
将链表的顺序反转,并非只把值替换了;
- 先去定义一个节点reverseHead = new HeroNode1();
- 从头到尾遍历原来的链表,每遍历一个节点,就将其取出,并放在新的链表的最前端;
- 把原链表的head.next=reverseHead.next;
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
| package com.jokerdig.linkedlist;
public class SingleLinkedListTest1 { public static void main(String[] args) { HeroNode1 hero1 = new HeroNode1(1,"宋江","及时雨"); HeroNode1 hero2 = new HeroNode1(2,"卢俊义","玉麒麟"); HeroNode1 hero3 = new HeroNode1(3,"吴用","智多星"); HeroNode1 hero4 = new HeroNode1(4,"武松","行者"); HeroNode1 hero5 = new HeroNode1(5,"林冲","豹子头"); SingleLinkedList1 singleLinkedList = new SingleLinkedList1(); singleLinkedList.addByOrder(hero1); singleLinkedList.addByOrder(hero5); singleLinkedList.addByOrder(hero2); singleLinkedList.addByOrder(hero4); singleLinkedList.addByOrder(hero3); singleLinkedList.list(); reverseList(singleLinkedList.getHead()); System.out.println("===========反转后的链表信息========="); singleLinkedList.list();
}
public static int getLength(HeroNode1 head){ if(head.next == null){ return 0; } int length = 0; HeroNode1 cur = head.next; while(cur!=null){ length++; cur = cur.next; } return length; }
public static HeroNode1 findLastIndexNode(HeroNode1 head,int index){ if(head.next == null){ return null; } int size = getLength(head); if(index <= 0|| index>size){ return null; } HeroNode1 cur = head.next; for (int i = 0; i < size - index; i++) { cur = cur.next; } return cur; }
public static void reverseList(HeroNode1 head){ if(head.next == null || head.next.next == null){ return ; } HeroNode1 cur = head.next; HeroNode1 next = null; HeroNode1 reverseHead = new HeroNode1(0,"",""); while(cur!=null){ next = cur.next; cur.next = reverseHead.next; reverseHead.next = cur; cur = next; } head.next = reverseHead.next; }
}
class SingleLinkedList1{ private HeroNode1 head = new HeroNode1(0,"",""); public HeroNode1 getHead() { return head; }
public void addByOrder(HeroNode1 heroNode){ HeroNode1 temp = head; boolean flag = false; while(true){ if(temp.next == null){ break; } if(temp.next.no>heroNode.no){ break; }else if(temp.next.no == heroNode.no){ flag = true; break; } temp = temp.next; } if(flag){ System.out.println("该英雄编号"+heroNode.no+"已经存在"); }else{ heroNode.next = temp.next; temp.next = heroNode; } }
public void list(){ if(head.next == null){ System.out.println("链表为空"); return; } HeroNode1 temp = head.next; while(true){ if(temp == null){ break; } System.out.println(temp); temp = temp.next; } } }
class HeroNode1{ public int no; public String name; public String nickname; public HeroNode1 next;
public HeroNode1(int no,String name,String hickname){ this.no = no; this.name = name; this.nickname = hickname; }
@Override public String toString() { return "HeroNode1{" + "no=" + no + ", name='" + name + '\'' + ", nickname='" + nickname + '}'; } }
|
运行结果
1 2 3 4 5 6 7 8 9 10 11 12 13
| HeroNode1{no=1, name='宋江', nickname='及时雨} HeroNode1{no=2, name='卢俊义', nickname='玉麒麟} HeroNode1{no=3, name='吴用', nickname='智多星} HeroNode1{no=4, name='武松', nickname='行者} HeroNode1{no=5, name='林冲', nickname='豹子头} ===========反转后的链表信息========= HeroNode1{no=5, name='林冲', nickname='豹子头} HeroNode1{no=4, name='武松', nickname='行者} HeroNode1{no=3, name='吴用', nickname='智多星} HeroNode1{no=2, name='卢俊义', nickname='玉麒麟} HeroNode1{no=1, name='宋江', nickname='及时雨}
Process finished with exit code 0
|
第四题
思路分析:
- 题目要求就是逆序打印单链表
- 方式1:先将单链表进行反转,然后在遍历(但这样做破坏了原来单链表结构);
- 方式2:利用Stack栈数据结构,将各个节点压入到栈中,利用栈的先进后出特点,就可以实现逆序打印;
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
| package com.jokerdig.linkedlist;
import java.util.Stack;
public class SingleLinkedListTest1 { public static void main(String[] args) { HeroNode1 hero1 = new HeroNode1(1,"宋江","及时雨"); HeroNode1 hero2 = new HeroNode1(2,"卢俊义","玉麒麟"); HeroNode1 hero3 = new HeroNode1(3,"吴用","智多星"); HeroNode1 hero4 = new HeroNode1(4,"武松","行者"); HeroNode1 hero5 = new HeroNode1(5,"林冲","豹子头"); SingleLinkedList1 singleLinkedList = new SingleLinkedList1(); singleLinkedList.addByOrder(hero1); singleLinkedList.addByOrder(hero5); singleLinkedList.addByOrder(hero2); singleLinkedList.addByOrder(hero4); singleLinkedList.addByOrder(hero3); singleLinkedList.list(); System.out.println("===========使用栈实现逆序打印单链表========="); reversePrint(singleLinkedList.getHead());
}
public static int getLength(HeroNode1 head){ if(head.next == null){ return 0; } int length = 0; HeroNode1 cur = head.next; while(cur!=null){ length++; cur = cur.next; } return length; }
public static HeroNode1 findLastIndexNode(HeroNode1 head,int index){ if(head.next == null){ return null; } int size = getLength(head); if(index <= 0|| index>size){ return null; } HeroNode1 cur = head.next; for (int i = 0; i < size - index; i++) { cur = cur.next; } return cur; }
public static void reverseList(HeroNode1 head){ if(head.next == null || head.next.next == null){ return ; } HeroNode1 cur = head.next; HeroNode1 next = null; HeroNode1 reverseHead = new HeroNode1(0,"",""); while(cur!=null){ next = cur.next; cur.next = reverseHead.next; reverseHead.next = cur; cur = next; } head.next = reverseHead.next; }
public static void reversePrint(HeroNode1 head){ if(head.next == null){ return ; } Stack<HeroNode1> stack = new Stack<HeroNode1>(); HeroNode1 cur = head.next; while(cur!=null){ stack.push(cur); cur = cur.next; } while(stack.size()>0){ System.out.println(stack.pop()); } }
}
class SingleLinkedList1{ private HeroNode1 head = new HeroNode1(0,"",""); public HeroNode1 getHead() { return head; }
public void addByOrder(HeroNode1 heroNode){ HeroNode1 temp = head; boolean flag = false; while(true){ if(temp.next == null){ break; } if(temp.next.no>heroNode.no){ break; }else if(temp.next.no == heroNode.no){ flag = true; break; } temp = temp.next; } if(flag){ System.out.println("该英雄编号"+heroNode.no+"已经存在"); }else{ heroNode.next = temp.next; temp.next = heroNode; } }
public void list(){ if(head.next == null){ System.out.println("链表为空"); return; } HeroNode1 temp = head.next; while(true){ if(temp == null){ break; } System.out.println(temp); temp = temp.next; } } }
class HeroNode1{ public int no; public String name; public String nickname; public HeroNode1 next;
public HeroNode1(int no,String name,String hickname){ this.no = no; this.name = name; this.nickname = hickname; }
@Override public String toString() { return "HeroNode1{" + "no=" + no + ", name='" + name + '\'' + ", nickname='" + nickname + '}'; } }
|
运行结果
1 2 3 4 5 6 7 8 9 10 11 12 13
| HeroNode1{no=1, name='宋江', nickname='及时雨} HeroNode1{no=2, name='卢俊义', nickname='玉麒麟} HeroNode1{no=3, name='吴用', nickname='智多星} HeroNode1{no=4, name='武松', nickname='行者} HeroNode1{no=5, name='林冲', nickname='豹子头} ===========使用栈实现逆序打印单链表========= HeroNode1{no=5, name='林冲', nickname='豹子头} HeroNode1{no=4, name='武松', nickname='行者} HeroNode1{no=3, name='吴用', nickname='智多星} HeroNode1{no=2, name='卢俊义', nickname='玉麒麟} HeroNode1{no=1, name='宋江', nickname='及时雨}
Process finished with exit code 0
|