数据结构之链表
序言:对于链表,首先要熟悉基本的操作,插入,删除,逆序,反转,旋转……指针的使用少不了
1. 插入
一个指针 P 即可
new node;
node.next = p.next;
p.next = node;
2. 删除
pre 和 p 指针实现 或者 用一个指针实现
pre.next = p.next
p移动后,p原来所指向的节点就被回收了
或者:
pre.next = pre.next.next
3. 逆序打印链表
链表逆序,想到栈
Stack<T> stack = new Stack<T>();
ListNode<T> p = head.next;
while(p!=null){
stack.push(p.value);
p = p.next;
}
遍历链表,压栈再依次出栈
用到栈,想到递归
void recursive(ListNode p){
if(p!=null){
recursive(p.next);
print(p);
}
}
非递归(三个指针,pre、p、next)
next = p.next
p.next = pre
pre = p;
p = next;
递归
ListNode recursive(ListNode p){
if(p.next==null){
return p;
}else{
ListNode next = p.next;
ListNode tail = recursive(next);
next.next = p;
return tail;
}
}
五个指针
反转需要3个:pre、p、next
另2个指向 begin 和 begin-1 的位置
6. 旋转链表
1-2-3-4-5 ——> 4-5- 1-2-3
第一种方法:模仿数组旋转。分部反转,再整体反转
第二种方法:链表可以直接调整指向
7. 回文链表
第一种方法:反转一半,然后双指针扫描(该表链表结构)
第二种方法:利用栈(牺牲空间,不改变链表本身结构)