在Java中没有struct来定义结构体,我们可以封装一个类来当结构体(快捷键alt+shift+S)
public class LinkNode {
public int data;//数据域
public LinkNode next;//指向下一个节点(指针域)
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public LinkNode getNext() {
return next;
}
public void setNext(LinkNode next) {
this.next = next;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + data;
result = prime * result + ((next == null) ? 0 : next.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
LinkNode other = (LinkNode) obj;
if (data != other.data)
return false;
if (next == null) {
if (other.next != null)
return false;
} else if (!next.equals(other.next))
return false;
return true;
}
public LinkNode(int data, LinkNode next) {
super();
this.data = data;
this.next = next;
}
public LinkNode() {
super();
}
@Override
public String toString() {
return "[data=" + data + ", next->\n" + next + "]";
}
}
构造一个空的链表,也就是头结点,并把头结点的数据域赋为0,指针域赋为null
private static void initLnode(LinkNode L) {
L.setData(0);
L.setNext(null);
}
链表的遍历
private static int traverse(LinkNode L) {
LinkNode p = L;
int count = 0;//计数器 计算节点的个数
while (p.next != null) {
p = p.next;
count++;
}
return count;
}
在第i个位置插入一节点
//L是传递过来的链表 count是传递过来的节点的个数
private static void insertLnode(LinkNode L, int count) {
Scanner scanner = new Scanner(System.in);
System.out.println("please enter the data:");
int data = scanner.nextInt();
System.out.println("please enter the position:");
int pos = scanner.nextInt();
//待插入的位置最大就是结点个数加一,且不能小于零
if (pos > count + 1 || pos <= 0) {
System.out.println("Illegal location!");
} else {
LinkNode p = L;// 把头结点赋给p
LinkNode q = new LinkNode();//待插入的节点
int i = 0;// 循环变量
//要在第i位置插入一个元素,要找到第i-1个元素,然后在它后面插入一个节点
while (p.next != null && i < pos - 1) {
p = p.next;
i++;
}
//在第i个位置插入节点
if (p.next == null) {
q.setData(data);
q.setNext(null);
p.setNext(q);
} else {
q.setData(data);
q.setNext(p.next);
p.setNext(q);
}
System.out.println("Insert success.");
}
}
删除第i个节点
private static void deleteLnode(LinkNode l, int pos) {
int count = traverse(l);
LinkNode p = l;
LinkNode r = new LinkNode();//记录p的上一个节点
//确保pos在合法范围内
if (pos <= 0 || pos > count) {
System.out.println("Illegal location!");
} else {
//向后移动pos个位置,找到第pos个节点
for (int j = 0; j < pos; j++) {
r = p;
p = p.next;
}
if (p.next == null) {//如果第pos个节点是最后一个节点
r.setNext(null);
} else {
r.setNext(p.next);
}
}
}
两个有序的链表合并后仍然有序
private static LinkNode merge(LinkNode L, LinkNode L1) {
LinkNode Lm = new LinkNode();//合并后的链表
LinkNode p = L;
LinkNode q = L1;
initLnode(Lm);
LinkNode r = Lm;
p = p.next;//从头结点向后移动一位,指向第一个节点
q = q.next;//从头结点向后移动一位,指向第一个节点
//L:2 5 7 9 10 11
//L1:3 5 6 8
//L有6个节点 L1有4个节点 先把前4个节点合并
while (p != null && q != null) {
if (p.data > q.data) {
LinkNode s = new LinkNode();
s.setData(q.data);
s.setNext(null);
r.setNext(s);
q = q.next;//L向后移动一位
r = r.next;//Lm向后移动一位
} else if (p.data < q.data) {
LinkNode s = new LinkNode();
s.setData(p.data);
s.setNext(null);
r.setNext(s);
p = p.next;
r = r.next;
} else {// 两数相等 同一个数据要在Lm上连接两次
LinkNode s = new LinkNode();//第一次连接
s.setData(q.data);
s.setNext(null);
r.setNext(s);
r = r.next;
LinkNode t = new LinkNode();//第二次连接
t.setData(q.data);
t.setNext(null);
r.setNext(t);
r = r.next;
q = q.next;
p = p.next;
}
}
//L:2 5 7 9 10 11
//L1:3 5 6 8
//合并后Lm:2 3 5 5 6 7 8 9 L还有两个节点,把剩下的两个节点直接合并到Lm后面
if (p != null && q == null) {//L链表还有剩余节点
while (p != null) {
LinkNode s = new LinkNode();
s.setData(p.data);
s.setNext(null);
r.setNext(s);
r = r.next;
p = p.next;
}
}
if (p == null && q != null) {//L1链表还有剩余节点
while (q != null) {
LinkNode s = new LinkNode();
s.setData(q.data);
s.setNext(null);
r.setNext(s);
r = r.next;
q = q.next;
}
}
return Lm;
}
测试方法
public class LNodeTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int m = 0;
System.out.println("1.init Lnode");
System.out.println("2.insert Lnode");
System.out.println("3.delete Lnode");
System.out.println("4.traverse");
System.out.println("5.Linked list merging");
System.out.println("6.output Lnode");
LinkNode L = new LinkNode();
while (true) {
System.out.println("please enter the opration code:");
int n = sc.nextInt();
switch (n) {
case 1:
initLnode(L);
System.out.println(L);
m++;
break;
case 2:
if (m == 0) {
System.out.println("please initialize first.");
} else {
int count = traverse(L);
System.out.println("count = " + count);
insertLnode(L, count);
}
break;
case 3:
if (m == 0) {
System.out.println("please initialize first.");
} else {
System.out.println("please enter the position:");
int pos = sc.nextInt();
deleteLnode(L, pos);
}
break;
case 4:
if (m == 0) {
System.out.println("please initialize first.");
} else {
int c = traverse(L);
System.out.println("count = " + c);
}
break;
case 5:
if (m == 0) {
System.out.println("please initialize first.");
} else {
LinkNode L1 = new LinkNode();
initLnode(L1);
while (true) {
int count = traverse(L1);
System.out
.println("Do you want to continue input elements?(Y|N)");
char c = sc.next().charAt(0);
if (c == 'Y' || c == 'y') {
insertLnode(L1, count);
} else if (c == 'N' || c == 'n') {
break;
}
}
LinkNode L2 = merge(L, L1);
System.out.println("combine");
System.out.println(L2);//调用LinkNode封装类中的toString方法
}
break;
case 6:
if (m == 0) {
System.out.println("please initialize first.");
} else {
System.out.println(L);//调用LinkNode封装类中的toString方法
}
break;
default:
System.out.println("Opcode error.");
break;
}
}
}
以L:2 5 7 9 10 11,L1:3 5 6 8为例,运行程序
运行结果: