单向链表是我们常用的数据结构,今天我们分享一下其实现和原理:
1、创建链表:节点元素
public static class ListNode {
public int val;
public ListNode next;
}
1.1、笨方式创建
ListNode node = new ListNode();
/**
* 最笨的方法创建链表
*/
node.val = 1;
node.next = new ListNode();
node.next.val = 2;
node.next.next = new ListNode();
node.next.next.val = 3;
node.next.next.next = new ListNode();
node.next.next.next.val = 4;
node.next.next.next.next = new ListNode();
node.next.next.next.next.val = 5;
1.2、循环创建
/**
* 批量创建N个节点的链表,
* @return
*/
private static ListNode addMore() {
ListNode head = new ListNode();
head.val = 0;
/**
* 创建链表的首个节点
*/
ListNode curNode = head;
for(int i = 1;i < 9;i++){
ListNode cur = new ListNode();
cur.val = i;
/**
* 比如首个节点的下一个节点赋值,此时这里有两个对象,1,2
*/
curNode.next = cur;
/**
* 比如 这里给第二个对象节点赋值(此时仅包含第二个对象);循环操作依次按此规则赋值
*/
curNode = curNode.next;
}
return head;
}
2、删除
2.1、删除最后一个节点:
/**
* 删除最后一个节点
* @param node
* @return
*/
private static ListNode removeEnd(ListNode node) {
ListNode head = node;
ListNode cur = node;
if(node != null){
while (cur.next != null){
head = cur;
cur = head.next;
}
head.next = null;
}
return node;
}
2.2、删除第n个节点:
/**
* 删除第三个节点元素
* @param node
* @return
*/
private static ListNode removeEnd3(ListNode node) {
ListNode head = node;
ListNode cur = node;
if(node != null){
for (int j = 0;j < 2;j++){
head = cur;
cur = head.next;
}
head.next = cur.next;
cur.next = null;
}
return node;
}
/**
* 删除第三个节点元素1
* @param node
* @return
*/
private static ListNode removeEnd1(ListNode node) {
ListNode head = node;
ListNode cur = node;
int j =0;
if(node != null){
while (j < 2){
head = cur;
cur = head.next;
j++;
}
head.next = cur.next;
cur.next = null;
}
return node;
}
2.3、删第一个:
/**
* 删除第一个
* @param node
* @return
*/
private static ListNode removeFirst(ListNode node) {
node = node.next;
return node;
}
/**
* 删除第一个1
* @param node
* @return
*/
private static ListNode removeFirst1(ListNode node) {
ListNode head = node;
node = head.next;
head.next = null;
return node;
}
2.4、删倒数第n个:
/**
* 删除倒数第二个
* @param node
* @return
*/
private static ListNode removeEnd2(ListNode node) {
ListNode temp = node;
ListNode head = node;
ListNode cur = node;
int i = 0;
while (temp != null){
temp = temp.next;
i++;
}
int k = i - 2;
System.out.println("链表的长度"+i);
int j = 0;
if(node != null){
while (j < k){
head = cur;
cur = head.next;
j++;
}
head.next = cur.next;
cur.next = null;
}
return node;
}
/**
* 删除倒数第二个
* @param node
* @return
*/
private static ListNode removeEnd22(ListNode node) {
ListNode temp = node;
ListNode head = node;
ListNode cur = node;
int i = 0;
while (temp != null){
temp = temp.next;
i++;
}
int k = i - 2;
System.out.println("链表的长度"+i);
if(node != null){
for(int j = 0;j < k;j++){
head = cur;
cur = head.next;
}
head.next = cur.next;
cur.next = null;
}
return node;
}
private static ListNode removeNthFromEnd1(ListNode head, int i) {
ListNode curNode = head;
ListNode preNode = null;
while (curNode !=null){
i--;
if(i == -1){
preNode = head;
}
if(i < -1){
preNode = preNode.next;
}
curNode = curNode.next;
}
if(i > 0){
return head;
}
if(preNode == null){
return head.next;
}
preNode.next = preNode.next.next;
return head;
}
4、修改
/**
* 更新第三个节点元素
* @param node
* @return
*/
private static ListNode update3(ListNode node) {
ListNode head = node;
if(node != null){
for (int j = 0;j < 2;j++){
head = head.next;
}
head.val = 33;
}
return node;
}
5、新增
5.1、尾节点后添加:
/**
* 未节点后面添加新的元素
* @param node
* @return
*/
private static ListNode addEnd(ListNode node) {
ListNode one = new ListNode();
one.val = 6;
ListNode head = node;
/**
* head 和 node 包含5个元素,引用传递。
*/
while (head.next != null){
head = head.next;
}
/**
* 此时烦人head 是第五个对象,在其后添加一个元素为第六个,因此返回时不能 return head 而应该返回 node
* 单链表的增删改查均遵守次规律
*/
head.next = one;
return node;
}
5.2、首节点前添加:
/**
* 首节点前面添加元素
* @param node
* @return
*/
private static ListNode addFirst(ListNode node) {
ListNode one = new ListNode();
one.val = 0;
one.next = node;
return one;
}
/**
* 首节点前面添加元素1
* @param node
* @return
*/
private static ListNode addFirst2(ListNode node) {
ListNode one = new ListNode();
one.val = 0;
one.next = node;
node = one;
return node;
}
/**
* 首节点前面添加元素2
* @param node
* @return
*/
private static ListNode addFirst1(ListNode node) {
ListNode head = node;
ListNode one = new ListNode();
one.val = 0;
one.next = head;
return one;
}
6、查询:
/**
* 查询第三个节点元素
* @param node
* @return
*/
private static ListNode get3(ListNode node) {
ListNode head = node;
if(node != null){
for (int j = 0;j < 2;j++){
head = head.next;
}
System.out.println("查询的结果"+head.val);
}
return node;
}
到此分享完毕,下篇分享双向链表,敬请期待!