单向链表的增删改查,翻转,查找倒数第N个节点

package linkedlist;

import java.util.Stack;

/* 
 * 单向链表:
 * 现在明确要干什么:
 * 单向链表节点类:
 * 1.date域
 * 2.next指针
 * 3.这里给多一个int型的number类型
 * 
 * 单向链表类:
 * 1.一个头节点
 * 3.增加节点的方法,直接在后面增加
 */
public class SingleLinkedList
{
	public Node head=new Node("", 0);
	/*
	 * 普通地在后面增加节点方法
	 */
	public void add(Node node)
	{
		Node temp=this.head;
		while(temp.next!=null)
		{
			temp=temp.next;
		}
		temp.next=node;
	}
	/*
	 * 第二种方式添加节点时,根据number编号从小到大将节点插入到指定位置
	 * (如果有这个number值的时候,则添加失败,并给出提示)
	 * 这里是有一个flag标记是否能找到这样子的位置,
	 * 当存在有number号和node相等的时候flag=true,这时就不能添加
	 */
	public void add2(Node node)
	{
		Node temp=head;
		boolean flag=false;
		while(true)
		{
			//这里表示要么这个链表是空的,要么是到了链表的最后
			if(temp.next==null)
				break;
			if(temp.next.number>node.number)
				break;
			if(temp.next.number==node.number)
			{
				flag=true;
				break;
			}
			temp=temp.next;
		}
		if(flag)
		{
			System.out.println("这个编号已经存在");
		}
		else
		{
			node.next=temp.next;
			temp.next=node;
		}
	}
	/*
	 * 修改节点的信息,根据number来修改
	 */
	public void update(Node node)
	{
		Node temp=head;
		boolean flag=false;
		while(true)
		{
			//要么这个链表是空的,要么到了链表尾,都是找不到
			if(temp.next==null)
				break;
			if(temp.next.number==node.number)
			{
				flag=true;
				break;
			}
			temp=temp.next;
		}
		//如果找到了就干什么
		if(flag)
		{
			temp.next.date=node.date;
		}
		else
			System.out.println("不存在这个编号");
	}
	/*
	 * 删除节点,方法和前面的差不多
	 */
	public void delete(int number)
	{
		Node temp=head;
		boolean flag=false;
		while(true)
		{
			if(temp.next==null)
				break;
			if(temp.next.number==number)
			{
				flag=true;
				break;
			}
			temp=temp.next;
		}
		if(flag)
		{
			temp.next=temp.next.next;
		}
		else
		{
			System.out.println("不存在这样的节点");
		}
	}
	/*
	 * 遍历这个链表
	 */
	public void show()
	{
		if(head.next==null)
		{
			System.out.println("链表是空的");
			return;
		}
		Node temp=head.next;
		while(true)
		{
			if(temp==null)
			{
				break;
			}
			System.out.println(temp);
			temp=temp.next;
		}
	}
	
	/*
	 * 将单链表反转
	 * 就是将这个链表传进来,然后将这个链表的节点翻转过来
	 */
	public  void reverse1(SingleLinkedList list)
	{
		//如果这个链表是空链表或者是长度为1的链表,就不用翻转
		if(list.head.next==null||list.head.next.next==null)
		{
			return;
		}
		//确定是要翻转了,然后新建一个头节点,然后再遍历这个链表
		//每一次遍历的节点就加入到新的头节点的最前面
		//这里需要保存一下每一次遍历的节点的下一个节点,因为如果我们将
		//遍历的节点加入到新的头节点的链表后,就无法找到当前节点的下一个节点了
		Node head=new Node("", 0);
		Node temp1=list.head.next;
		Node tempnext;
		while(temp1!=null)
		{
			tempnext=temp1.next;
			
			temp1.next=head.next;
			head.next=temp1;
			
			temp1=tempnext;
		}
		list.head.next=head.next;
	}
	/*
	 * 说到翻转,最可能是想到栈的数据结构,它的先进后出的结构可以很轻松地实现
	 * 翻转地效果
	 */
	public void reverse2(SingleLinkedList list)
	{
		Stack<Node> stack=new Stack<Node>();
		Node temp=list.head.next;
		while(temp!=null)
		{
			stack.push(temp);
			temp=temp.next;
		}
		while(stack.size()>0)
		{
			System.out.println(stack.pop());
		}
	}
	/*
	 * 查找单链表中的倒数第k个结点
	 * 这里是这样子,先利用getlength的方法得到list的长度
	 * 然后利用长度length-index就是刚刚好是倒数index位置的节点
	 */
	public Node find(SingleLinkedList list,int index)
	{
		int length=this.getlength(list);
		//我觉得应该先处理一些不用返回的情况
		if(list.head.next==null||index<=0||index>length)
		{
			System.err.println("找不到");
			return null;
		}
		Node temp=list.head.next;
		for (int i = 0; i < length-index; i++)
		{
			temp=temp.next;
		}
		return temp;
	}
	/*
	 * 返回这个链表地长度
	 */
	public int getlength(SingleLinkedList list)
	{
		Node temp=list.head.next;
		int length=0;
		while(temp!=null)
		{
			length++;
			temp=temp.next;
		}
		return length;
	}
	public static void main(String[] args)
	{
		Node h1 = new Node("a", 1);
		Node h2 = new Node("b", 2);
		Node h3 = new Node("c", 3);
		Node h4 = new Node("d", 4);
		
		//创建要给链表
		SingleLinkedList singleLinkedList = new SingleLinkedList();
		
		//加入
		singleLinkedList.add2(h1);
		singleLinkedList.add2(h4);
		singleLinkedList.add2(h2);
		singleLinkedList.add2(h3);
		singleLinkedList.show();
		System.out.println();
		singleLinkedList.update(new Node("z", 3));
		singleLinkedList.show();
		System.out.println("翻转");
		singleLinkedList.reverse1(singleLinkedList);
		singleLinkedList.show();
		System.out.println();
		singleLinkedList.reverse2(singleLinkedList);
		System.out.println("删除");
		singleLinkedList.delete(3);
		singleLinkedList.show();
		System.out.println();
		System.out.println(singleLinkedList.find(singleLinkedList, 0));
	}
}
class Node
{
	public String date;
	public int number;
	public Node next;
	public Node(String date, int number)
	{
		this.date = date;
		this.number = number;
	}
	@Override
	public String toString()
	{
		return "Node [date=" + date + ", number=" + number + "]";
	}
	
}
发布了133 篇原创文章 · 获赞 37 · 访问量 4738

猜你喜欢

转载自blog.csdn.net/qq_43416157/article/details/104251365