Java链表的代码
单链表的使用
功能:
- 链表节点的添加
- 链表节点的删除
- 链表节点的修改
- 遍历链表的节点
- 获取单链表的节点个数
- 查询单链表中倒数第 k 个节点
- 单链表的反转
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]
双向链表的使用
功能:
- 双线链表节点的添加
- 双线链表节点的删除
- 双线链表节点的修改
- 遍历双线链表的节点
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