package com.tulun.src07;
/**
- @author Richard
- @date 2019/9/14 0014-14:50
- 头增
- 尾增
- 头删
- 尾删
- 删值
- 两个链表相交,输出相交节点
- 输出单链表的倒数第k个节点
- 单链表的逆置
- 判断一个单链表是否有环,输出相遇节点
- 输出环的入口节点:当前链表的入口节点
*/
class Entry<T extends Comparable>{
private T value;
private Entry next;
public Entry(T value){
this.value=value;
}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
public Entry getNext() {
return next;
}
public void setNext(Entry next) {
this.next = next;
}
}
public class Link<T extends Comparable> {
private Entry headEntry;
private Entry tailEntry;
public Link() {
headEntry = null;
tailEntry = null;
}
public Entry<T> getEntry(T value) {
for (Entry p = headEntry; p != null; p = p.getNext()) {
if (p.getValue().compareTo(value) == 0) {
return p;
}
}
return null;
}
public void addHead(T value) {
Entry<T> newEntry = new Entry<>(value);
//当原链表为空链表时
if (headEntry == null) {
headEntry = newEntry;
tailEntry = newEntry;
return;
} else {//当原链表有一个及以上节点时
headEntry = newEntry.getNext();//newEntry.setNext(headEntry);
headEntry=newEntry;
}
}
public void addTail(T value){
Entry<T> newEntry=new Entry<>(value);
//当原链表为空链表时
if (headEntry==null){
headEntry=newEntry;
tailEntry=newEntry;
return;
}else{//当原链表不为空链表时
tailEntry.setNext(newEntry);
tailEntry=newEntry;
//Entry p=null;
//for (p=headEntry;p.getNext()!=null;p=p.getNext());
//p.setNext(newEntry);
}
}
public void removeHead(){
//当原链表为空链表
if (headEntry==null){//该处可以使用异常,后续实现
System.out.println("该链表为空链表,无法删除");
return;
}else if (headEntry.getNext()==null){//当链表只有一个节点时
headEntry=null;
tailEntry=null;
return;
}else{//当链表有大于1个节点时
headEntry.setValue(null);//防止内存泄漏
headEntry=headEntry.getNext();
}
}
public void removeTail(){
//当原链表为空链表时
if (headEntry==null){
System.out.println("原链表为空链表,无法删除!");
return;
}else if (headEntry.getNext()==null){//当原链表只有一个节点时
headEntry=null;
tailEntry=null;
return;
}else{//当原链表含有大一1个节点
tailEntry.setValue(null);//防止内存泄漏
Entry<T> priorTailEntry=null;
for (priorTailEntry=headEntry;priorTailEntry.getNext().getNext()!=null;priorTailEntry=priorTailEntry.getNext());
priorTailEntry.setNext(null);
tailEntry=priorTailEntry;
}
}
public void removeValue(T value){
if (headEntry==null){//当原链表为空链表时
System.out.println("该链表为空链表,无法删除");
return;
}else if (headEntry.getValue().compareTo(value)==0){//若头节点为所要删除的节点
headEntry.setValue(null);
//headEntry.setNext(null);此处为错误代码,需谨记
headEntry=headEntry.getNext();
if (tailEntry==headEntry){
tailEntry=null;
}
return;
}else{
for(Entry<T> entry=headEntry;entry.getNext()!=null;entry=entry.getNext()){
if (entry.getNext().getValue().compareTo(value)==0){
entry.getNext().setValue(null);
entry.setNext(entry.getNext().getNext());
}
}
}
}
private int getLength(){
int count=0;
for (Entry<T> entry=headEntry;entry!=null;entry=entry.getNext()){
count++;
}
return count;
}
//两个链表相交,输出相交节点的value值
public static<T extends Comparable<T>> T getMeetEntryValue(Link<T> link1,Link<T> link2){
//1,统计出链表的长度
int length1=link1.getLength();
int length2=link2.getLength();
int different=Math.abs(length1-length2);//两个链表的长度差
//2,长链表先走差值步
Entry<T> longLinkEntry=length1>length2?link1.headEntry:link2.headEntry;
Entry<T> shortLinkEntry=length1<length2?link1.headEntry:link2.headEntry;
for (;--different>=0;longLinkEntry=longLinkEntry.getNext());
//3,长短链表同时向后走,直到long==short
for (;longLinkEntry!=null;longLinkEntry=longLinkEntry.getNext(),shortLinkEntry=shortLinkEntry.getNext()){
if (longLinkEntry==shortLinkEntry){
return longLinkEntry.getValue();
}
}
return null;
}
//输出倒数第K个节点
public static<T extends Comparable<T>> T showDK(Link<T> link,int k){
if (k<0 || k>link.getLength()){
return null;
}
Entry<T> p=link.headEntry;
Entry<T> q=link.headEntry;
for (;--k>=0;p=p.getNext());//p先走k步
for (;p!=null;p=p.getNext(),q=q.getNext());//p和q同时走,当p==null时,q的位置就为倒数第k个节点
return q.getValue();
}
//单链表逆置
public static<T extends Comparable<T>> void reverse(Link<T> link){
if (link.getLength()==1){
return;
}
Entry<T> p=link.headEntry;
Entry<T> q=p.getNext();
Entry<T> s=q.getNext();
while (q!=null){
q.setNext(p);
p=q;
q=s;
if (s!=null){
s.getNext();
}
}
link.tailEntry=link.headEntry;
link.headEntry=p;
link.tailEntry.setNext(null);
}
//判断一个单链表是否有环,输出相遇节点
public Entry<T> isCircle(){
Entry<T> fast=headEntry;
Entry<T> slow=headEntry;
do {
if (fast==null || fast.getNext()==null){
return null;
}
fast=fast.getNext().getNext();
slow=slow.getNext();
}while (fast!=slow);
return slow;
}
//输出环的入口节点:当前链表的入口节点
public Entry<T> getCircleMeetEntry(){
Entry<T> meet=isCircle();
if (meet==null){
return null;
}
Entry<T> p=headEntry;
Entry<T> q=meet;
while (p!=q){
p=p.getNext();
q=q.getNext();
}
return p;
}
//两个有序单链表合并成一个有序单链表
public Entry<T> mergeLink(Link<T> link){
if (link==null || link.headEntry==null){
return this.headEntry;
}
Entry<T> p1=this.headEntry;
Entry<T> p2=link.headEntry;
//新链表头&&新链表尾巴
Entry<T> newHeadEntry=p1.getValue().compareTo(p2.getValue())>0?p2:p1;
Entry<T> newTailEntry=newHeadEntry;
if (newHeadEntry==p1){
p1=p1.getNext();
}else{
p2=p2.getNext();
}
//比较p1和p2的值,值小的连接在链表尾部
while (p1!=null && p2!=null){
if (p1.getValue().compareTo(p2.getValue())<0){
tailEntry.setNext(p1);
newTailEntry=p1;//p1节点作为新链表的尾巴
p1=p1.getNext();
}else{
tailEntry.setNext(p2);
newTailEntry=p2;
p2=p2.getNext();
}
}
//p1走完,p1==null
if (p1==null){
tailEntry.setNext(p2);
}
//p2走完,p2==null
if (p2==null){
tailEntry.setNext(p1);
}
return newHeadEntry;
}
public void show(){
for(Entry<T> entry=headEntry;entry!=null;entry=entry.getNext()){
System.out.print(entry.getValue()+" ");
}
System.out.println();
}
}