算法通关村-第一关青铜挑战-链表

本文介绍了链表(包括单向和双向链表)的概念,存储方式,以及基本操作如查找、插入和删除的时间复杂度分析。通过示例展示了如何在Java中实现链表并进行相关操作。

1.什么是链表?

链表(linked list)是一种在物理上非连续、非顺序的数据结构,由若干节点(node)所组成。

单向链表的每一个节点又包含两部分,一部分是存放数据的变量data,另一部分是指向下一个节点的指针next。

1. private static class Node {
2. 		int data;
3. 		Node next;
4. }

链表的第1个节点被称为头节点,最后1个节点被称为尾节点,尾节点的next指针指向空(NULL)。

2.什么是双向链表?

双向链表的每一个节点除了拥有data和next指针,还拥有指向前置节点的prev指针。

3.链表的存储方式

4.链表的基本操作

1. 查找节点 o(n)

2.更新节点

如果不考虑查找节点的过程,链表的更新过程会像数组那样简单,直接把旧数据替换成新数据即可。

3.插入节点 o(1)
  • 尾部插入

把最后一个节点的next指针指向新插入的节点即可。

  • 头部插入

第1步,把新节点的next指针指向原先的头节点。

第2步,把新节点变为链表的头节点。

  • 中间插入

第1步,新节点的next指针,指向插入位置的节点。

第2步,插入位置前置节点的next指针,指向新节点。

只要内存空间允许,能够插入链表的元素是无穷无尽的,不需要像数组那样考虑扩容的问题。

4.删除节点 o(1)
  • 尾部删除

把倒数第2个节点的next指针指向空即可

  • 头部删除

把链表的头节点设为原先头节点的next指针即可

  • 中间删除

把要删除节点的前置节点的next指针,指向要删除元素的下一个节点即可

1. // 头节点指针
2. private Node head;
3. // 尾节点指针
4. private Node last;
5. // 链表实际长度
6. private int size;
7.
8. /**
9. * 链表插入元素
10. * @param data 插入元素
11. * @param index 插入位置
12. */
13. public void insert(int data, int index) throws Exception {
	14. if (index<0 || index>size) {
		15. throw new IndexOutOfBoundsException(" 超出链表节点范围!");
		16. }
	17. Node insertedNode = new Node(data);
	18. if(size == 0){
		19. //空链表
		20. head = insertedNode;
		21. last = insertedNode;
		22. } else if(index == 0){
		23. //插入头部
		24. insertedNode.next = head;
		25. head = insertedNode;
		26. }else if(size == index){
		27. //插入尾部
		28. last.next = insertedNode;
		29. last = insertedNode;
		30. }else {
		31. //插入中间
		32. Node prevNode = get(index-1);
		33. insertedNode.next = prevNode.next;
		34. prevNode.next = insertedNode;
		35. }
	36. size++;
	37. }
38.
39. /**
40. * 链表删除元素
41. * @param index 删除的位置
42. */
43. public Node remove(int index) throws Exception {
	44. if (index<0 || index>=size) {
		45. throw new IndexOutOfBoundsException(" 超出链表节点范围!");
		46. }
	47. Node removedNode = null;
	48. if(index == 0){
		49. //删除头节点
		50. removedNode = head;
		51. head = head.next;
		52. }else if(index == size-1){
		53. //删除尾节点
		54. Node prevNode = get(index-1);
		55. removedNode = prevNode.next;
		56. prevNode.next = null;
		57. last = prevNode;
		58. }else {
		59. //删除中间节点
		60. Node prevNode = get(index-1);
		61. Node nextNode = prevNode.next.next;
		62. removedNode = prevNode.next;
		63. prevNode.next = nextNode;
		64. }
	65. size--;
	66. return removedNode;
	67. }
68.
69. /**
70. * 链表查找元素
71. * @param index 查找的位置
72. */
73. public Node get(int index) throws Exception {
	74. if (index<0 || index>=size) {
		75. throw new IndexOutOfBoundsException(" 超出链表节点范围!");
		76. }
	77. Node temp = head;
	78. for(int i=0; i<index; i++){
		79. temp = temp.next;
		80. }
	81. return temp;
	82. }
83.
84. /**
85. * 输出链表
86. */
87. public void output(){
	88. Node temp = head;
	89. while (temp!=null) {
		90. System.out.println(temp.data);
		91. temp = temp.next;
		92. }
	93. }
94.
95. /**
96. * 链表节点
97. */
98. private static class Node {
	99. int data;
	100. Node next;
101. Node(int data) {
	102. this.data = data;
	103. }
104.}
105.
106.public static void main(String[] args) throws Exception {
	107. MyLinkedList myLinkedList = new MyLinkedList();
	108. myLinkedList.insert(3,0);
	109. myLinkedList.insert(7,1);
	110. myLinkedList.insert(9,2);
	111. myLinkedList.insert(5,3);
	112. myLinkedList.insert(6,1);
	113. myLinkedList.remove(0);
	114. myLinkedList.output();
	115.}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值