Java链表的代码

Java链表的代码

  1. 单链表的使用
  2. 双线链表的使用
  3. 约瑟夫问题
  4. 栈的使用

单链表的使用

功能:

  1. 链表节点的添加
  2. 链表节点的删除
  3. 链表节点的修改
  4. 遍历链表的节点
  5. 获取单链表的节点个数
  6. 查询单链表中倒数第 k 个节点
  7. 单链表的反转
class Data{
	private int no;
	private Data next;  //指向下一个节点	
	public Data(int no) {
		this.no = no;
	}
	public int getNo() {
		return no;
	}
	public void setNo(int no) {
		this.no = no;
	}
	public Data getNext() {
		return next;
	}
	public void setNext(Data next) {
		this.next = next;
	}
	@Override
	public String toString() {
		return "Data [no=" + no + "]";
	}
}
/**
 * 链表的增删改查
 * @author dell
 *
 */
class UserLinkedList{
	Data head = new Data(-1);  //设置头指针,设为 -1
	/*
	 * 链表节点的添加
	 */
	public void add(Data data) {
		//插入方法一:按照顺序插入节点
//		Data temp = head;  //头节点head不能动,设置辅助节点
//		//找到最后一个节点
//		while(true) {
//			if(temp.getNext() == null) {  //下一个节点为空,则找到最后一个节点
//				break;
//			}
//			temp = temp.getNext();  //指向下一个节点
//		}
//		temp.setNext(data);  //添加节点到末尾

		//插入方法二:按照从小到大的顺序插入节点
		Data temp = head;  //头节点head不能动,设置辅助节点
		//找到适合插入的节点的位置
		while(true) {
			if(temp.getNext() == null) {  //下一个节点为空,则找到最后一个节点
				break;
			}
			if(temp.getNo() < data.getNo() && data.getNo() <= temp.getNext().getNo()) {  //插入的值大于这个节点且小于等于下一个节点
				break;
			}
			temp = temp.getNext();  //指向下一个节点
		}
		data.setNext(temp.getNext());
		temp.setNext(data);
	}
	/*
	 * 链表节点的删除
	 */
	public void delete(Data data) {
		if(head.getNext() == null) {  //链表为空
			System.out.println("链表为空");
			return ;
		}
		Data temp = head;  //头节点head不能动,设置辅助节点
		while(true) {
			if(temp.getNext() == null) {  //遍历完链表
				System.out.println("未找到相应信息");
				return ;
			}
			if(temp.getNext().getNo() == data.getNo()) {  //找到与data的no值相同的节点
				temp.setNext(temp.getNext().getNext());
				return ;
			}
			temp = temp.getNext();  //指向下一个节点
		}
	}
	/*
	 * 链表节点的修改
	 * 根据 Data 来修改 no 的值
	 */
	public void upData(Data data, int x) {
		if(head.getNext() == null) {  //链表为空
			System.out.println("链表为空");
			return ;
		}
		Data temp = head.getNext();  //头节点head不能动,设置辅助节点
		while(true) {
			if(temp == null) {  //遍历完链表
				System.out.println("未找到相应信息");
				return ;
			}
			if(temp.getNo() == data.getNo()) {  //找到与data的no值相同的节点
				temp.setNo(x);
				return ;
			}
			temp = temp.getNext();
		}
	}
	/*
	 * 遍历链表的节点
	 */
	public void list() {
		if(head.getNext() == null) {  //链表为空
			System.out.println("链表为空");
			return ;
		}
		Data temp = head.getNext();  //设置辅助节点
		//遍历链表输出
		while(true) {
			if(temp == null) {  //指针到链表最后
				break;
			}
			System.out.println(temp.toString());
			temp = temp.getNext();
		}
	}
	/*
	 * 获取单链表的节点个数
	 */
	public int countNode() {
		Data temp = head.getNext();  //设置辅助节点
		int count = 0;
		while(temp != null) {  //指针到链表最后
			count++;
			temp = temp.getNext();
		}
		return count;
	}
	/*
	 * 查询单链表中倒数第 k 个节点
	 */
	public void reNode(int k) {
		Data temp = head.getNext();  //设置辅助节点
		int i = countNode() - k;  //定义变量为temp向后移动 i 个节点
		if(i < 0) {
			System.out.println("输入数值大于了链表节点数量");
			return ;
		}
		while(i-- > 0) {  //temp向后移动 i 个节点
			temp = temp.getNext();
		}
		System.out.println("倒数第" + k + "个节点是:" + "Data [no = " + temp.getNo() + "]");
	}
	/*
	 * 单链表的反转
	 */
	public void reverseNode() {
		if(head.getNext() == null || head.getNext().getNext() == null) {  //当只有0或1个节点时,不需要反转
			return ;
		}
		Data temp = head.getNext();  //设置辅助节点
		Data first = new Data(-1);  //设置反转的头节点
		Data next = null;  //记录temp的下一个节点
		while(temp != null) {  //指针到链表最后
			next = temp.getNext();  //记录temp的下一个节点,后面有用,若不设置这个,后面temp将获取不到head链表后面的值
			//将temp插入到first链表的第一个节点
			temp.setNext(first.getNext());  
			first.setNext(temp);
			temp = next;  //获取head链表中temp的下一个节点
		}
		head.setNext(first.getNext());
	}
}

public class CaoGao {
	public static void main(String[] args) {
		Data data1 = new Data(1);
		Data data2 = new Data(22);
		Data data3 = new Data(3);
		Data data4 = new Data(4);
		UserLinkedList userLinkedList = new UserLinkedList();
		userLinkedList.add(data1);  //添加节点
		userLinkedList.add(data2);  //添加节点
		userLinkedList.add(data3);  //添加节点
		userLinkedList.add(data4);  //添加节点
		System.out.println("添加后的节点:");
		userLinkedList.list();  //遍历节点
		userLinkedList.upData(data1, 100);  //修改 data1 节点信息
		System.out.println("修改后的节点:");
		userLinkedList.list();  //遍历节点
		userLinkedList.delete(data1);  //删除 data1 节点
		System.out.println("删除后的节点:");
		userLinkedList.list();  //遍历节点
		System.out.println("节点个数:" + userLinkedList.countNode());  //节点个数
		userLinkedList.reNode(2);
		userLinkedList.reverseNode();  //链表反转
		System.out.println("反转后的节点:");
		userLinkedList.list();
	}
}

程序运行结果:

  • 添加后的节点:
    Data [no=1] Data [no=3] Data [no=4] Data [no=22]
  • 修改后的节点:
    Data [no=100] Data [no=3] Data [no=4] Data [no=22]
  • 删除后的节点:
    Data [no=3] Data [no=4] Data [no=22]
  • 节点个数:3
  • 倒数第2个节点是:
    Data [no = 4]
  • 反转后的节点:
    Data [no=22] Data [no=4] Data [no=3]






双向链表的使用

功能:

  1. 双线链表节点的添加
  2. 双线链表节点的删除
  3. 双线链表节点的修改
  4. 遍历双线链表的节点
class Data{
	private int no;
	private Data next;  //指向下一个节点	
	private Data pre;  //指向前一个节点
	public Data(int no) {
		this.no = no;
	}
	public int getNo() {
		return no;
	}
	public void setNo(int no) {
		this.no = no;
	}
	public Data getNext() {
		return next;
	}
	public void setNext(Data next) {
		this.next = next;
	}
	public Data getPre() {
		return pre;
	}
	public void setPre(Data pre) {
		this.pre = pre;
	}
	@Override
	public String toString() {
		return "Data [no=" + no + "]";
	}
}

/*
 * 功能实现类
 */
class DoubleLinked{
	Data head = new Data(-1);  //设置头指针
	/**
	 * 添加数据
	 * @param data 添加的对象
	 */
	public void add(Data data) {
		//按照顺序插入节点
//		Data temp = head;  //设置辅助节点
//		//找到最后一个节点,并将他插入到最后
//		while(true) { 
//			if(temp.getNext() == null) {  //下一个节点为空,找到最后一个节点
//				break;
//			}
//			temp = temp.getNext();
//		}
//		//形成双向链表
//		temp.setNext(data);
//		data.setPre(temp);
		
		//按照大小插入节点
		Data temp = head;  //设置辅助节点
		//找到合适的位置,并将其插入到相应位置
		while(true) {
			if(temp.getNext() == null) {  //下一个节点为空,找到最后一个节点,没有找到合适的位置
				temp.setNext(data);
				data.setPre(temp);
				return ;
			}
			//插入的值大于这个节点且小于等于下一个节点
			if(temp.getNo() < data.getNo() && data.getNo() <= temp.getNext().getNo()) {  
				break;
			}
			temp = temp.getNext();
		}
		data.setNext(temp.getNext());
		temp.getNext().setPre(data);
		temp.setNext(data);
		data.setPre(temp);
	}
	
	/**
	 * 链表节点的修改
	 * @param id  需要修改的 no
	 * @param x  修改后的 no
	 */
	public void upData(int id, int x) {
		if(head.getNext() == null) {  //链表为空
			System.out.println("链表为空");
			return ;
		}
		Data temp = head.getNext();  //头节点head不能动,设置辅助节点
		while(true) {
			if(temp == null) {  //遍历完链表
				System.out.println("未找到相应信息");
				return ;
			}
			if(temp.getNo() == id) {  //找到与data的no值相同的节点
				temp.setNo(x);
				return ;
			}
			temp = temp.getNext();
			
		}
	}
	
	/**
	 * 链表的删除
	 * @param id 需要修改的 no
	 */
	public void delete(int id) {
		if(head.getNext() == null) {  //链表为空
			System.out.println("链表为空");
			return ;
		}
		Data temp = head.getNext();  //设置辅助节点
		while(true) {
			if(temp == null) {  //遍历到最后了
				System.out.println("未找到相应信息");
				return ;
			}
			if(temp.getNo() == id) {  //找到了
				if(temp.getNext() == null) {  //下一个节点为空
					temp.getPre().setNext(null);
					break;
				}
				//删除的语句
				temp.getPre().setNext(temp.getNext());
				temp.getNext().setPre(temp.getPre());
				return ;
			}
			temp = temp.getNext();
		}
	}
	
	/**
	 * 遍历链表
	 */
	public void list() {
		if(head.getNext() == null) {  //链表为空
			System.out.println("链表为空");
			return ;
		}
		Data temp = head.getNext();  //设置辅助节点
		//遍历链表输出
		while(true) {
			if(temp == null) {  //指针到链表最后
				break;
			}
			System.out.println(temp.toString());
			temp = temp.getNext();
		}
	}
}

/*
 * main 函数
 */
public class CaoGao {
	public static void main(String[] args) {
		Data data1 = new Data(1);
		Data data2 = new Data(22);
		Data data3 = new Data(3);
		Data data4 = new Data(4);
		DoubleLinked doubleLinked = new DoubleLinked();
		doubleLinked.add(data1);  //添加节点
		doubleLinked.add(data2);  //添加节点
		doubleLinked.add(data3);  //添加节点
		doubleLinked.add(data4);  //添加节点
		System.out.println("添加后的节点:");
		doubleLinked.list();  //遍历节点
		
		//修改节点
		System.out.println("修改后的节点:");
		doubleLinked.upData(1, 5);  //修改节点
		doubleLinked.list();  //遍历节点
		
		//删除节点
		System.out.println("删除后的节点:");
		doubleLinked.delete(22);  //删除节点
		doubleLinked.list();  //遍历节点
	}
}

程序运行结果:

  • 添加后的节点:
    Data [no=1] Data [no=3] Data [no=4] Data [no=22]
  • 修改后的节点:
    Data [no=5] Data [no=3] Data [no=4] Data [no=22]
  • 删除后的节点:
    Data [no=5] Data [no=3] Data [no=4]






约瑟夫问题

class Data{
	private int no;
	private Data next;  //指向下一个节点	
	public Data(int no) {
		this.no = no;
	}
	public int getNo() {
		return no;
	}
	public void setNo(int no) {
		this.no = no;
	}
	public Data getNext() {
		return next;
	}
	public void setNext(Data next) {
		this.next = next;
	}
	@Override
	public String toString() {
		return no + "->";
	}
}

/*
 * 功能实现类
 * 1、创建循环链表
 */
class LinkedList{
	private Data first = new Data(-1);
	/**
	 * 创建循环链表
	 * @param no  节点数目
	 */
	public void add(int no) {
		if(no < 1) {  //节点数少于 1
			System.out.println("数量有误");
			return ;
		}
		Data temp = null;  //设置辅助节点
		//循环创建循环链表
		for(int i = 1; i <= no; i++) {
			Data node = new Data(i);
			if(i == 1) {  //添加的第一个节点
				first = node;  
				first.setNext(first);
				temp = first;
			}else {
				temp.setNext(node);
				node.setNext(first);
				temp = node;
			}
		}
	}
	
	/**
	 * 约瑟夫问题:将节点一个一个的输出
	 * @param startNo  从第几个节点开始
	 * @param countNO  间隔节点数
	 * @param numsNo  总共的节点数
	 */
	public void countData(int startNo, int countNo, int numsNo) {
		if(startNo < 1 || startNo > numsNo || countNo < 1) {
			System.out.println("参数有误");
			return ;
		}
		add(numsNo);
		Data temp = first;  //设置辅助指针
		//将辅助指针移动到最后节点
		while(temp.getNext() != first) {
			temp = temp.getNext();
		}
		//将 first 移动到开始节点的下一个位置
		for(int i = 0; i < startNo; i++) {
			first = first.getNext();
			temp = temp.getNext();
		}
		//循环输出节点
		while(true) {
			if(temp == first) {  //只剩下一个节点
				break;
			}
			//将 first 和 temp 节点移动 countNo 步,此时first所在的节点是要出去的节点
			for(int i = 0; i < countNo - 1; i++) {
				first = first.getNext();
				temp = temp.getNext();
			}
			System.out.print(first);  //输出出去的节点
			//删除出去的节点
			first = first.getNext();
			temp.setNext(first);
		}
		System.out.print(first);
	}	
	
	/**
	 * 遍历环形链表
	 */
	public void list() {
		if(first == null) {  //链表为空
			System.out.println("链表为空");
			return ;
		}
		Data temp = first;  //设置辅助节点
		//循环输出链表信息
		while(true) {
			System.out.print(temp.toString());
			if(temp.getNext() == first) {
				return ;
			}else {
				temp = temp.getNext();
			}
		}
	}
}

/*
 * main 函数
 */
public class CaoGao {
	public static void main(String[] args) {
		LinkedList linkedList = new LinkedList();
		linkedList.countData(2, 2, 10);
	}
}

运行结果:

  • 4->6->8->10->2->5->9->3->1->7->






栈的使用

简单的加减乘除运算

/*
 * 运算的类
 */
class NumberStack{
	Stack<Integer> num = new Stack<Integer>();  //定义数据的栈
	Stack<Character> s = new Stack<Character>();  //定义运算符的栈
	/**
	 * 运算过程和结果
	 * @param str  运算的字符串
	 */
	public void fzk(String str) {
		//一位一位的取值
		for(int i = 0; i < str.length(); i++) {
			if(isOper(str.charAt(i))) {  //字符为运算符
				if(s.isEmpty()) {  //运算符的栈为空
					s.push(str.charAt(i));  //入栈
				}else {  //运算符栈不为空
					if(priority(str.charAt(i)) > priority(s.peek())) {  //该运算符的优先级比运算符栈的栈顶运算符高
						s.push(str.charAt(i));  //入栈
					}else {
						//取出运算符栈顶符号来与数据栈的两个数进行运算
						//并将运算的数值入栈
						//将该运算符入栈
						int x = num.pop();
						int y = num.pop();
						int n = count(y, x, s.pop());
						num.push(n);
						s.push(str.charAt(i));
					}
				}
			}else {  //数据入栈
				num.push(Integer.parseInt(str.substring(i, i + 1)));
			}
		}
		//运算符栈不为空
		//取出运算符栈顶符号来与数据栈的两个数进行运算
		//并将运算的数值入栈
		while(!s.isEmpty()) {
			int x = num.pop();
			int y = num.pop();
			int n = count(y, x, s.pop());
			num.push(n);
		}
		System.out.println(num.pop());
	}
	
	/**
	 * 判断是否为运算符
	 * @param ch  需要判断的字符
	 * @return  
	 */
	public static boolean isOper(char ch) {
		if(ch == '+' || ch == '-' || ch == '*' || ch == '/') {
			return true;
		}
		return false;
	}
	
	/**
	 * 模拟优先级
	 * @param ch  需要判断优先级的字符
	 * @return  优先级
	 */
	public static int priority(char ch) {
		int p = 0;
		if(ch == '*' || ch == '/') {
			p = 1;
		}else {
			p = 0;
		}
		return p;
	}
	
	/**
	 * 运算
	 * @param num1  数值1
	 * @param num2  数值2
	 * @param oper  运算符
	 * @return  运算结果
	 */
	public static int count(int num1, int num2, char oper) {
		int n = 0;
		switch (oper) {
		case '+':
			n = num1 + num2;
			break;
		case '-':
			n = num1 - num2;
			break;
		case '*':
			n = num1 * num2;
			break;
		case '/':
			n = num1 / num2;
			break;
		default:
			break;
		}
		return n;
	}
}

/*
 * main 函数
 */
public class CaoGao {
	
	public static void main(String[] args) {
		NumberStack numberStack = new NumberStack();
		numberStack.fzk("4+4*4+4*4");
	}
}

运行结果:

  • 36







发布了7 篇原创文章 · 获赞 0 · 访问量 254

猜你喜欢

转载自blog.csdn.net/qq_44002865/article/details/103728277
今日推荐