java实现单向链表_Java实现单向链表

Java实现链表的思想可以参考 LinkedList的源码

下面实现几点关于单向链表的一些操作:

1 public class LinkList{2 private Nodefirst;3 private Nodelast;4 private intsize;5

6 publicLinkList() {7 first = last = null;8 size = 0;9 }10

11

12 private static class Node{13 private Nodenext;14 privateE data;15 public Node(E data,Nodenext) {16 this.data =data;17 this.next =next;18 }19 }20

21 public voidadd(E e) {22 Node l =last;23 Node newNode = new Node(e, null);24 last =newNode;25 if(first == null) {26 first =newNode;27 } else{28 l.next =newNode;29 }30 size++;31 }32

33

34

35 public static voidmain(String[] args) {36 LinkList link = new LinkList();37 //1.添加

38 link.add(1);39 link.add(2);40 link.add(3);41 link.add(4);42

43 System.out.println("节点个数:" +link.size);44

45 //2.遍历

46 Node node1 =link.first;47 for(int i = 0;i

54 //3.查找单链表中的倒数第k个结点

55 int k = 2;56 //倒数第k个,就是正数第link.size-k+1,(因为是单向,只能正着数)

57 int index = link.size-k+1;58 Node node2 =link.first;59

60 if(link.size <= 0) {61 System.out.println("链表为空");62 return;63 }64 if(link.size <= k && link.size > 0) {65 System.out.println(node2.data);66 return;67 }68

69 for(int i = 1;i

73 System.out.println("这个链表中倒数第" + k + "个节点的值为:" +node2.data);74

75 //4.查找单链表中的中间节点(size + 1 / 2,然后遍历吧)76

77 //5.合并两个有序的单链表,合并之后,仍然有序;78 //这里自己的思路是,创建一个新的链表,将这两个有序的链表中的数据,按序放入到 新链表中

79 LinkList link2 = new LinkList();80 LinkList link3 = new LinkList();81 link2.add(0);82 link2.add(2);83 link2.add(3);84 link2.add(2);85 link2.add(7);86 link2.add(7);87

88 Node node3 =link.first;89 Node node4 =link2.first;90

91 //只有链表1和链表2中还有数据可以放入新链表

92 for(;node3 != null || node4 != null;) {93

94 //当链表1和链表2中都有数据可以去比较,

95 if(node3 != null && node4 != null) {96 if(node3.data node4.data) {101 link3.add(node4.data);102 node4 =node4.next;103 } else if(node3.data ==node4.data) {104 link3.add(node3.data);105 link3.add(node4.data);106 node3 =node3.next;107 node4 =node4.next;108 }109 }110

111

112 //若链表1的数据已经比较完了,链表2的还有数据存在,说明链表2这些剩下的数据都比链表1里面大,直接全部放到新链表后面

113 if(node3 == null && node4 != null) {114 link3.add(node4.data);115 node4 =node4.next;116 } else if(node3 != null && node4 == null) {117 link3.add(node3.data);118 node3 =node3.next;119 }120

121 }122 System.out.print("两个有序的单链表合并后:");123 for(int i = 0;i

130 //6.单链表的反转

131 Node node5 =link.first;132

133 Node pre = null;134 Node next = null;135

136 while(node5 != null) {137 next =node5.next;138 node5.next =pre;139 pre =node5;140 node5 =next;141

142 }143

144 while(pre != null) {145 System.out.print(pre.data + " ");146 pre =pre.next;147 }148 }149 }

注:上面的代码写得比较糟糕,也有很多可以封装的地方,等有时间再整理

提比较重要的几点:

1.关于链表中的泛型,用到泛型的地方,

a)创建这个LinkList的时候,

b)创建Node节点的时候,

c)往Node中添加的数据

2.关于单向链表的添加,

a)添加就是添加在链表的末尾,添加之前,肯定要创建一个 Node节点出来,这个Node节点的下一个节点为null

b)先保存原来的last节点,将这个newNode作为新的last节点

c)如果原先列表中不存在节点,则这个newNode就为 first节点

d)将原来的last节点的next指向这个newNode,就完成添加了 ,最后size++

3.关于合并两个有序的单链表,

a)这里自己的思路是,创建一个新的链表,将这两个有序的链表中的数据,按序放入到 新链表中,当然还有别的思路

4.关于单向链表的反转,

a)首先要有一个pre节点和 next 节点,用于保存当前节点的前一个节点和后一个节点

b)

用前面定义的next,保存当前节点的下一个节点

当前节点下一节点重新指向当前节点的前一节点(箭头反向) 1->2->3    1

让pre,当前节点,next,依次向后移动,这样就可以对下一个节点进行反转

c)还有一种递归的方式,递归和直接遍历的区别就是,直接遍历是从前往后按顺序一个一个反转

递归是从后往前,先反转最后一个节点,再回头反转前面

这边给出一个递归的示例:

1 public static voidmain(String[] args) {2 Node head = new Node(0);3 Node node1 = new Node(1);4 Node node2 = new Node(2);5 Node node3 = new Node(3);6 head.setNext(node1);7 node1.setNext(node2);8 node2.setNext(node3);9

10 //打印反转前的链表

11 Node h =head;12 while (null !=h) {13 System.out.print(h.getData() + " ");14 h =h.getNext();15 }16 //调用反转方法

17 head =Reverse1(head);18

19 System.out.println("\n**************************");20 //打印反转后的结果

21 while (null !=head) {22 System.out.print(head.getData() + " ");23 head =head.getNext();24 }25 }26

27 /**

28 * 递归,在反转当前节点之前先反转后续节点29 */

30 public staticNode Reverse1(Node head) {31 //head看作是前一结点,head.getNext()是当前结点,reHead是反转后新链表的头结点

32 if (head == null || head.getNext() == null) {33 return head;//若为空链或者当前结点在尾结点,则直接还回

34 }35 Node reHead = Reverse1(head.getNext());//先反转后续节点head.getNext()

36 head.getNext().setNext(head);//将当前结点的指针域指向前一结点

37 head.setNext(null);//前一结点的指针域令为null;

38 return reHead;//反转后新链表的头结点

39 }40 }41

42 classNode {43 private int Data;//数据域

44 private Node Next;//指针域

45

46 public Node(intData) {47 //super();

48 this.Data =Data;49 }50

51 public intgetData() {52 returnData;53 }54

55 public void setData(intData) {56 this.Data =Data;57 }58

59 publicNode getNext() {60 returnNext;61 }62

63 public voidsetNext(Node Next) {64 this.Next =Next;65 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值