import algorithd.LinkList.Node;
/**
*@author 风雨落
*@version 2017年12月16日下午6:21:29
*@title java写链表尝试
*/
class LinkList {
Node head;
//添加数据
public void add(int data){
Node newNode = new Node(data);
if(head==null){
head = newNode;
}else{
Node p = head;
while(p.next!=null){
p = p.next;
}
p.next = newNode;
}
}
//打印链表
public void print(){
Node p = head;
while(p!=null){
System.out.println(p.value);
p = p.next;
}
}
//找到链表中的倒数第k个节点
/**
* 这里需要声明两个指针:即两个结点型的变量first和second,
* 首先让first和second都指向第一个结点,
* 然后让second结点往后挪k-1个位置,
* 此时first和second就间隔了k-1个位置,
* 然后整体向后移动这两个节点,直到second节点走到最后一个结点的时候,
* 此时first节点所指向的位置就是倒数第k个节点的位置。时间复杂度为O(n)
* @param index
* @return
*/
public boolean findLastNode(int index){
Node p = head;
Node first = p;
Node second = p;
int k = index;
if(k==0){
System.out.println("数据不合理");
return false;
}
index--;
while(index>0&&second.next!=null){
second = second.next;
index--;
}
if(index!=0){
System.out.println("数据不合理");
return false;
}
while(second.next!=null){
first = first.next;
second = second.next;
}
System.out.print("倒数第"+k+"个节点"+first.value);
return true;
}
//两个有序列表合并 尤其要注意两个链表都为空、和其中一个为空的情况
public LinkList combineSorted(LinkList ls){
Node p = head;
Node q = ls.head;
LinkList newLs = new LinkList();
Node newNode;
if(p==null&&q==null){//两个链表均为空
return newLs;
}
if(p==null){//单链表为空
newLs = ls;
return newLs;
}
if(q==null){
newLs = this;
return newLs;
}
if(p.value<q.value){
newLs.head = p;
p = p.next;
}else{
newLs.head = q;
q = q.next;
}
newNode = newLs.head;
while(p!=null){
if(p.value<q.value){
newNode.next = p;
newNode = newNode.next;
p = p.next;
}else{
newNode.next = q;
newNode = newNode.next;
q = q.next;
}
}
//合并剩余节点
while(q!=null){
newNode.next = q;
q = q.next;
newNode = newNode.next;
}
return newLs;
}
//单链表的反转
public LinkList reverse(){
LinkList ls = this;
Node cur,pre,next;
cur = ls.head;
if(cur==null||cur.next==null){//空链表或者单元素
return ls;
}
//处理头节点
next = cur.next;
cur.next = null;
pre = cur;
cur = next;
while(cur!=null){
next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
ls.head = pre;
return ls;
}
//判断一个链表是否有环
public boolean hasCircle(){
Node p,q;
p = head;
q = head;
while(p!=null&&p.next!=null){
p = p.next.next;
q = q.next;
if(p==q){
return true;
}
}
return false;
}
//找链表环的起始节点
public void findCricleStart(){
//首先要有环
if(hasCircle()){
//确定在环中的点
Node p,q;
p = head;
q = head;
Node eNode = head;
while(p!=null&&p.next!=null){
p = p.next.next;
q = q.next;
if(p==q){
eNode = p;
break;
}
}
//确定环的长度
p = eNode;
int num = 0;
while(p!=null){
p=p.next;
num++;
if(p==eNode){
break;
}
}
p = head;
while((num--)!=0){
p = p.next;
}
System.out.print(p.value);
}
}
/**
* 使用内部类,可以和外部类进行私有操作的相互访问
* @author Administrator
*
* @param <Integer>
*/
class Node{
Integer value;
Node next;
public Node(Integer data){
value = data;
next = null;
}
}
}
public class Main1216 {
public static void main(String[] args) {
// TODO Auto-generated method stub
LinkList ls = new LinkList();
ls.print();
LinkList ls1 = new LinkList();
ls1.add(1);
ls1.add(3);
ls1.add(21);
Node p = ls1.head;
while(p.next!=null){
p = p.next;
}
p.next = ls1.head;
// LinkList ls2 = ls.combineSorted(ls1);
// LinkList ls3 = ls1.reverse();
// ls3.print();
if(ls1.hasCircle()){
System.out.println("有");
}else{
System.out.println("没有");
}
ls1.findCricleStart();
}
}
剑指offer关于链表的一些操作(java)
最新推荐文章于 2019-01-02 12:57:25 发布