0
点赞
收藏
分享

微信扫一扫

数据结构之链表

迎月兮 2022-03-12 阅读 79

单链表

小王子单链表

小王子有一天迷上了排队的游戏,桌子上有标号为 1-10 按顺序摆放的 10 个玩具,现在小王子想将它们按自己的喜好进行摆放。小王子每次从中挑选一个好看的玩具放到所有玩具的最前面。已知他总共挑选了 M 次,每次选取标号为 X 的玩具放到最前面,求摆放完成后的玩具标号。

给出一组输入,M=8 共计排了 8 次,这 8 次的序列为 9,3,2,5,6,8,9,8。 求最终玩具的编号序列。

过程:

1、创建初始链表

2、实现链表的删除操作

3、实现链表的插入操作

4、输出已排好序的链表

import java.util.Scanner;

public class 单链表 {
	
	static class Node{
		int data;
		Node next;
		
		Node(int data){
			this.data = data;
		}
	}//成员类,表节点
	
	static Node head = new Node(1);//头节点
	
	//初始化链表
	static void init() {
		Node x = head;
		for(int i = 1; i <= 10; i++) {
			x = (x.next = new Node(i));
//			x.next = new Node(i);
//			x = x.next;
			x.next = null;	
		}
	}
	
	//删除节点
	static void del(int x) {
		Node Befor = head;//存放一个节点前驱,方便删除元素
		for(Node T = head.next; T != null; T = T.next) {
			if(T.data == x) {//找到要删除的数
				Node temp = T;//临时节点保存节点
				Befor.next = T.next;//将节点从链表上删除
				return;//删除后结束函数
			}
			Befor = T;
		}
	}
	
	//插入元素(头插法)
	static void insert(int x) {
		Node temp = new Node(x);
		temp.next = head.next;
		head.next = temp;       
	}
	
	//显示链表
	static void show(int x) {
		//System.out.println("这是第"+x+"次操作");
		for(Node T = head.next; T != null; T = T.next) {
			System.out.print(T.data + " ");
		}
		System.out.println();
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int N;
		Scanner in = new Scanner(System.in);
		init();
		//show(0);
		N = in.nextInt();
		
		
		for(int i = 1; i <= N; i++) {
			int x = in.nextInt();
			del(x);
			insert(x);
			show(i);
		}

	}

}

循环链表

约瑟夫环问题

设有 n 个人围坐在圆桌周围,现从某个位置 k(1≤k≤n) 上的人开始报数,报数到 m 的人就站出来。下一个人,即原来的第 m+1 个位置上的人,又从 1 开始报数,再报数到 m 的人站出来。依次重复下去,直到全部的人都站出来为止。试设计一个程序求出这 n 个人的出列顺序。

  • 要求一:采用循环链表解决
  • 要求二:可以使用模拟法,模拟循环链表
  • 要求三:可以不使用循环链表类的定义使用方式

分析:和上一个创建链表几乎一样,只不过让末尾的节点指向头节点以形成循环链表。

即x.next = head。

import java.util.Scanner;


public class 循环链表 {
	static class Node{
		int val;
		Node next;
		Node(int val){
			this.val = val;
		}
	}
	
	public static void main(String[] args) {
		int N, M, K; //n个人从第k个位置报数,数到m出列
		Scanner in = new Scanner(System.in);
		N = in.nextInt();
		K = in.nextInt();
		M = in.nextInt();
		
		Node head = new Node(1);//头节点单列出来,方便形成循环链表
		Node x = head;
		
		//初始化循环链表
		for(int i = 2; i <= N; i++) {
			x = (x.next = new Node(i));
			x.next = head;//形成循环链表
		}//此时,x指向末尾节点
		
		
		//寻找报数起点
		for(int i = 1; i < K; i++) {
			x = x.next;//此时,x指向第k-1个节点
		}
		
		
		//报数,出环
		while(x != x.next) {//只剩下一个节点的时候停止
			for(int i = 1; i < M; i++) {
				x = x.next;
			}//此时,x指向要删除节点的前一个节点
			System.out.println(x.next.val + " ");
			x.next = x.next.next;//删除节点
		}
		//输出最后一个节点值
		System.out.println(x.val);

	}

}

 

双向链表

小王子双链表

与单链表题目相同,用双向链表实现。

重点在于节点有两个指针域:next和before。next指向节点的下一个节点,before指向节点的前一个节点。即x.next.befor = x,这样就可形成双向。在小王子问题中,这样做的时候,删除节点的时候就不必在new一个节点保存前驱节点,直接就能找到。

import java.util.Scanner;


public class 双向链表 {
	static class Node{
		int data;
		Node next;
		Node befor;
		Node(int data){
			this.data = data;
		}
	}

	static Node head = new Node(1);//头节点
	
	//初始化链表
	static void init() {
		Node x = head;
		for(int i = 1; i <= 10; i++) {
			x.next = new Node(i);//建立双向链表
			x.next.befor = x;
			x = x.next;
		}
		x.next = null;
	}
	
	//删除节点
	static void del(int x) {
		for(Node T = head.next; T != null; T = T.next) {
			if(T.data == x) {//找到删除的节点
				T.befor.next = T.next;//将节点x从链表上摘除
				T.next.befor = T.befor;//虽删除,但T的左右指针还指向之前指向的节点
				return;//删除节点后,结束函数
			}
		}
	}
	
	//插入节点(头插)
	static void insert(int x) {
		Node temp = new Node(x);
		temp.next = head.next;
		temp.next.befor = temp;
		head.next = temp;
		temp.befor = head;//头节点的next的before也指向头节点,在本题中,写不写均可
	}
	
	//显示链表
	static void show(int x) {
		//System.out.println("这是第" + x + "次操作");
		for(Node T = head.next; T != null; T = T.next) {
			System.out.print(T.data + " ");
		}
		System.out.println();
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int N;
		Scanner in = new Scanner(System.in);
		init();
		//show(0);
		N = in.nextInt();
		
		
		for(int i = 1; i <= N; i++) {
			int x = in.nextInt();
			del(x);
			insert(x);
			show(x);
		}

	}

}
举报

相关推荐

0 条评论