使用java实现链表

本文详细介绍了链表数据结构的基础操作,包括单向链表的创建、插入、遍历和删除,链表反转,合并两个有序链表,以及双向链表的构建和删除节点。此外,还展示了如何使用环形链表解决约瑟夫问题,提供了完整的代码实现。
摘要由CSDN通过智能技术生成

一、单向链表

创建节点对象

class Node {
	int no;
	Node next; //指向下一个节点
	public Node(int no) {
		this.no = no;
	}
}

实现链表的建立、插入、遍历以及删除

//建立链表
class BuildNode {
	
	private Node head = new Node(0);
	
	//将每个节点添加到链表的最后一个节点
	public void buildByLast(Node node) {
		Node temp = head;
		while(temp.next!=null) {
			temp = temp.next;
		}
		temp.next = node;
	}
	
	//将每个节点按顺序插入到链表中
	public void buildByOrder(Node node) {
		Node temp = head;
		boolean flag = true;
		while(temp.next!=null) {
			if (temp.next.no>=node.no) { //找到位置,插入节点
				flag = false;
				break;
			}
			temp = temp.next;
		}
		if (flag) {
			temp.next = node;
		} else {
			node.next = temp.next;
			temp.next = node;
		}
	}
	
	//删除节点
	public void deleteNode(int n) {
		if (head.next==null) {
			System.out.println("列表为空");
			return;
		}
		boolean flag = true;
		Node temp = head;
		while(temp.next != null) {
			if (temp.next.no == n) {
				flag = false;
				break;
			}
			temp = temp.next;
		}
		if (flag) {
			System.out.println("没有找到该节点");
			return;
		}
		temp.next = temp.next.next;
	}
	
	//遍历每个节点
	public void getAll() {
		Node temp = head.next;
		while(temp!=null) {
			System.out.print(temp.no + " ");
			temp = temp.next;
		}
		System.out.print("\n");
	}
}

二、单向链表的其他操作

链表反转

//单链表的反转
public void reverseNode() {
	if (head.next==null || head.next.next==null) {
		return;
	}
	Node n1 = head.next; //当前节点
	Node n2 = null; //用于记录当前节点的下一个节点
	Node n3 = new Node(0); //使用该节点标记最开始的位置,每个节点的next都指向n3的next
	while(n1!=null) {
		n2 = n1.next;  
		n1.next = n3.next;
		n3.next = n1;
		n1 = n2;
	}
	head.next = n3.next;
}

合并两个有序的链表

//合并两个有序的链表,头节点为空
public Node conbine(Node head, Node head2) {
	Node temp1 = head.next;
	Node temp2 = head2.next;
	//前置节点
	Node pre1 = head;
	//记录temp2的下一个节点
	Node record = null;
	while(temp1!=null&&temp2!=null) {
		if (temp1.no>=temp2.no) {
			//预先记录temp2的下一个节点
			record = temp2.next;
			//前置节点指向当前要插入的节点
			pre1.next = temp2;
			//插入的节点指向temp1
			temp2.next = temp1;
			//将前置节点后移一位
			pre1 = pre1.next;
			temp2 = record;
		} else {
			temp1 = temp1.next;
			pre1 = pre1.next;
		}
	}
	if (temp1==null) {
		pre1.next = temp2;
	}
	return head;
}
//第二种写法
public Node conbine(Node l1, Node l2) {
	ListNode pre = new ListNode(-1);
	ListNode t = pre;
	while(l1!=null&&l2!=null) {
	    if(l1.val>=l2.val) {
	        pre.next = l2;
	        l2 = l2.next;
	    } else {
	        pre.next = l1;
	        l1 = l1.next;
	    }
	    pre = pre.next;
	}
	if(l2!=null) {
	    pre.next = l2;
	}
	if(l1!=null) {
	    pre.next = l1;
	}
	return t.next;
}

三、双向链表

private Node1 head = new Node1(0);
//将每个节点添加到链表的最后一个节点
public void buildByLast(Node1 node) {
	Node1 temp = head;
	while(temp.next!=null) {
		temp = temp.next;
	}
	//当前节点的pre指向前面的链表
	node.pre = temp;
	//最后一个节点的next指向node
	temp.next = node;
}

//删除节点
public void deleteNode(int n) {
	if (head.next==null) {
		System.out.println("列表为空");
		return;
	}
	boolean flag = true;
	Node1 temp = head.next;
	while(temp != null) {
		if (temp.no == n) {
			flag = false;
			break;
		}
		temp = temp.next;
	}
	if (flag) {
		System.out.println("没有找到该节点");
		return;
	}
	temp.pre.next = temp.next;
	if (temp.next!=null) {
		temp.next.pre = temp.pre;
	}
}
 
//遍历每个节点
public void getAll() {
	Node1 temp = head.next;
	while(temp!=null) {
		System.out.print(temp.no + " ");
		temp = temp.next;
	}
	System.out.print("\n");
}

四、环形链表解决约瑟夫问题

//创建环形链表解决约瑟夫问题
class BuildLink3 {
	
	private CircleLink first = null; //设置为环形链表的第一个节点
	
	//创建环形链表
	public void build(int nums) {
		//定义当前节点
		CircleLink cur = null;
		for(int i=1; i<=nums; i++) {
			CircleLink circleLink = new CircleLink(i);
			if (i==1) { //只有一个节点时,next指向自己
				first = circleLink;
				circleLink.next = first;
			} else {
				cur.next = circleLink;
				circleLink.next = first;
			}
			cur = circleLink;
		}
	}
	
	//约瑟夫问题删除节点
	public void deleteNode(int k) {
		//定义初始位置
		int i = 1;
		CircleLink cur = first;
		CircleLink data = first;
		while (data.next!=first) {
			data = data.next;
		}

		while(true) {
			if (data == cur) {
				break;
			}
			if (i==k) {
				System.out.println(cur.no);
				data.next = cur.next;
				cur = cur.next;
				i=1;
				continue;
			}
			i++;
			cur = cur.next;
			data = data.next;
		}
	}
	
	//遍历环形链表
	public void getAll() {
		CircleLink data = first;
		while (data.next!=first) {
			System.out.println(data.no);
			data = data.next;
		}
		System.out.println(data.no);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值