节点类
class ListNode {
public int data;
public ListNode next;
public ListNode(int data) {
this.data = data;
this.next = null;
}
}
头插法
public void addFirst(int data) {
ListNode node=new ListNode(data);
if(this.head ==null){
this.head=node;
}
else {
node.next=this.head;
this.head=node;
}
}
尾插法
public void addLast(int data) {
ListNode node=new ListNode(data);
ListNode cur=this.head;
if(this.head==null){
this.head=node;
}else {
while (cur.next!=null){
cur=cur.next;
}
cur.next=node;
}
}
打印
public void display() {
ListNode cur = this.head;
while (cur!=null){
System.out.print(cur.data+" ");
cur=cur.next;
}
System.out.println();
}
是否包含key
public boolean contains(int key) {
ListNode cur = this.head;
while (cur!=null){
if(cur.data==key){
return true;
}
cur=cur.next;
}
return false;
}
获得单链表的长度
public int getLength() {
int count=0;
ListNode cur=this.head;
while(cur!=null){
count++;
cur=cur.next;
}
return count;
}
找第index的节点
private ListNode searchIndex(int index) {
ListNode cur = this.head;
//cur -> index-1
int count=0;
while (count<index-1){
count++;
cur=cur.next;
}
return cur;
}
任意位置插入
public boolean addIndex(int index, int data) {
if(index<0||index>getLength()){
System.out.println("index位置不合法");
return false;
}
if(index==0){
addFirst(data);
return true;
}
ListNode node=new ListNode(data);
ListNode cur=searchIndex(index);
node.next=cur.next;
cur.next=node;
return true;
}
查找关键字
private ListNode searchPre(int key) {
ListNode pre=this.head;
while (pre.next!=null){
if(pre.next.data==key){
return pre;
}
pre=pre.next;
}
return null;
}
删除第一次出现关键字为key的节点
public void remove(int key){
if(this.head==null){
System.out.println("单链表为空");
return;
}
//0、删除的节点是否是头结点
if (this.head.data==key){
this.head=this.head.next;
return;
}
//1、找到key的前驱 如果返回空
ListNode pre=searchPre(key);
if (pre==null){
System.out.println("没有你要删除的节点");
return;
}
//2、删除节点
ListNode del=pre.next;
pre.next=del.next;
}
删除所有值为key的节点
public void removeAllKey(int key){
ListNode pre=this.head;
ListNode cur=this.head.next;
while(cur.next!=null){
if (pre.next.data==key){
pre.next=cur.next;
cur=cur.next;
}
if(pre.next.data!=key){
pre=cur;
cur=cur.next;
}
}
if (this.head.data==key){
this.head=this.head.next;
}
}
反转单链表
public ListNode reverseList(){
ListNode pre=null;
ListNode newHead=null;
ListNode cur=this.head;
while (cur!=null){
ListNode curNext=cur.next;
if(curNext==null){
newHead=cur;
}
cur.next=pre;
pre=cur;
cur=cur.next;
}
return newHead;
}
单链表的中间节点
public ListNode middleNode(){
ListNode fast=this.head;
ListNode slow=this.head;
while(fast!=null&&fast.next!=null){
fast=fast.next.next;
slow=slow.next;
}
return slow;
}
打印2
public void display2(ListNode newHead) {
ListNode cur = newHead;
while (cur != null) {
System.out.print(cur.data+" ");
cur = cur.next;
}
System.out.println();
}
输入一个链表,输出该链表中倒数第k个结点
public ListNode findKthToTail(int k){
//k>getLength
if(k<=0){
System.out.println("没有这个节点");
return null;
}
ListNode fast=this.head;
ListNode slow=this.head;
while (k-1>0){
if(fast.next!=null) {
fast = fast.next;
k--;
}
else {
System.out.println("没有你要找的节点");
return null;
}
}
while (fast.next!=null){
fast=fast.next;
slow=slow.next;
}
return slow;
}
以x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前
public ListNode partition(int x) {
ListNode cur = this.head;
ListNode beforeStart = null;
ListNode beforeEnd = null;
ListNode afterStart = null;
ListNode afterEnd = null;
while (cur != null) {
//cur.data < x
if(cur.data < x) {
//第一次插入
if(beforeStart==null) {
beforeStart=cur;
beforeEnd=cur;
}else {
beforeEnd.next=cur;
beforeEnd=beforeEnd.next;
}
cur=cur.next;
}
else {
//第一次插入
if(afterStart == null) {
afterStart=cur;
afterEnd=cur;
}else {
afterEnd.next=cur;
afterEnd=afterEnd.next;
}
}
cur=cur.next;
}
if(beforeStart==null){
return afterStart;
}
beforeEnd.next =afterStart;
if (afterStart!=null){
afterEnd.next=null;
}
return beforeStart;
}
删除重复的节点
public ListNode deleteDuplication() {
ListNode node = new ListNode(-1);
ListNode cur = this.head;
ListNode tmp = node;
while (cur != null) {
if(cur.next != null &&
cur.data == cur.next.data) {
//1、循环
while (cur.next != null &&cur.data == cur.next.data){
cur=cur.next;
}
cur=cur.next;
//2、退出循环 cur要多走一步
//
}else {
//当前节点 不等于下一个节点的时候
tmp.next = cur;
cur = cur.next;
tmp = tmp.next;
}
}
tmp.next=cur;
return node.next;
}
回文
public boolean chkPalindrome() {
ListNode fast = this.head;
ListNode slow = this.head;
while (fast != null && fast.next!=null) {
fast = fast.next.next;
slow = slow.next;
}
//反转
ListNode p = slow.next;
while (p != null) {
ListNode pNext = p.next;
//反转
p.next = slow;
slow = p;
p = pNext;
}
while (slow!=head){
if(slow.data!=head.data){
return false;
}//偶数
if (this.head.next==slow){
return true;
}
slow=slow.next; //slow往前 head 往后
head=head.next;
}
return true;//直到相遇
}
是否有环
public boolean hasCycle(){
ListNode fast=this.head;
ListNode slow=this.head;
while (fast!=null&&fast .next!=null){
slow=slow.next;
fast=fast.next.next;
if(slow==fast){
return true;
}
}
return false;
}
返回链表开始入环的第一个节点如果链表无环,则返回null
public ListNode detectCycle(){
ListNode fast=this.head;
ListNode slow=this.head;
while (fast!=null&&fast .next!=null){
slow=slow.next;
fast=fast.next.next;
if(slow==fast) {
break;
}
if(fast.next!=null||fast!=null)
return null;
}
fast = this.head;
while (fast!=slow){
fast=fast.next;
slow=slow.next;
}
return fast;
}
环的长度
public int Listlen(){
ListNode fast=this.head;
ListNode slow=this.head;
while (fast!=null&&fast .next!=null){
slow=slow.next;
fast=fast.next.next;
if(slow==fast) {
break;
}
if(fast.next!=null||fast!=null)
return -1;
}
//slow=fast
slow=slow.next;
int count=1;
while (fast!=slow){
slow=slow.next;
count++;
}
return count;
}
}
找共同节点返回
public static ListNode getIntersectionNode
(ListNode headA,ListNode headB){
if(headA == null || headB == null) {
return null;
}
//永远指向最长的单链表
ListNode pL = headA;
//永远指向最短的单链表
ListNode pS = headB;
int lenA = 0;
int lenB = 0;
//分别求长度
while(pL!=null){
lenA++;
pL=pL.next;
}
while(pS!=null){
lenA++;
pS=pS.next;
}
pL = headA;
pS = headB;
//求长度的差值
int len = lenA-lenB;
//如果是负数-》pL = headB; pS = headA
if(len<0){
pL = headB;
pS = headA;
len=lenB-lenA;
}
//只需要让pL走len步就好了
while (len>0){
pL=pL.next;
len--;
}
//走完len步之后 两个同时开始走
while (pL!= pS&&pL!=null){
pL= pL.next;
pS=pS.next;
}
if(pL==pS&&pS!=null){
return pL;
}
return null;
//一直走 走到next值相同时 就是交点
}
将两个有序链表合并为一个新的有序链表并返回
public static ListNode mergeTwoLists(
ListNode headA,ListNode headB) {
ListNode node=new ListNode(-1);
ListNode tmp=null;
while (headA!=null&&headB!=null){
if(headA.data<headB.data){
tmp.next=headA;
headA=headA.next;
tmp=tmp.next;
}
else {
tmp.next=headB;
headB=headB.next;
tmp=tmp.next;
}
}
if(headA!=null){
tmp.next=headA;
}
if (headB!=null){
tmp.next=headB;
}
return node.next;
}