实现单链表的基本结构:
创建空链表
与C语言不同在节点是通过对象创建的而不是结构体
添加数据至链尾
根据序号排序插入
通过循环比较节点序号大小将其插入相应位置
删除节点
修改节点内容
查找倒数第n个节点
链表显示
输出链表所有节点内容信息
查找链表中有效节点个数
链表反转
(1)通过创建新链表
通过循环原链表,将每一次循环到的第一个节点将其插入新链表头节点后面
(2)通过栈方式实现
通过栈的先进后出特点反向输出节点
话不多说上代码,看代码会清楚很多(一定要自己多运行~)
import java.util.Scanner;
import java.util.Stack;
public class SingleList {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
//初始化链表数据
pNode node1 = new pNode(1, "小明", "数学天才");
pNode node2 = new pNode(5, "李华", "英语幽灵");
pNode node3 = new pNode(4, "小红", "数学辅助");
pNode node4 = new pNode(3, "珍妮", "绿恐龙");
pNode node5 = new pNode(2, "周树人", "鲁迅");
pNode node6 = new pNode(7, "唐僧", "长生不老肉");
//修改某节点内容
pNode changenode=new pNode(4,"孙悟空","弼马温");
//创建链表
Slist slist = new Slist();
//插入多个节点
slist.orderAdd(node1);
slist.orderAdd(node2);
slist.orderAdd(node3);
slist.orderAdd(node4);
slist.orderAdd(node5);
slist.orderAdd(node6);
System.out.println("链表输出:");
slist.showData();
//修改和删除
slist.uodata(changenode);
slist.delete(node1);
System.out.println("修改4和删除1后:");
slist.showData();
//输出有效节点个数
System.out.printf("有效节点个数为:%d\n",slist.valid());
//查找倒数第n个节点
System.out.println("倒数第3个节点内容为:"+slist.backn(3));
//反转链表
System.out.println("反转链表结果为:");
slist.reverse();
slist.showData();
//通过栈方式反转链表
System.out.println("通过栈方式反转链表:");
slist.stackway();
}
}
//单链表对象
//管理节点和方法
class Slist{
//初始化链表(只有一个头节点)
private pNode head=new pNode(0,"","");
//返回头节点
public pNode getHead() {
return head;
}
//判断链表是否为空
public boolean isEmpty(){
return head.next==null;
}
//添加节点
public void addData(pNode node){
//创建辅助节点
pNode temp=head;
//添加在链表末尾
while (true){
if(temp.next==null)break;
temp=temp.next;
}
temp.next=node;
}
//按序号排名添加
public void orderAdd(pNode p){
pNode temp=head;
if(isEmpty()){
// System.out.println("链表为空,将新节点直接加入末尾");
temp.next=p;
return;
}
while (temp.next!=null){
if (temp.next.info>p.info){
// System.out.printf("找到p要插入的位置啦!在%d和%d之间插入%d\n",temp.info,temp.next.info,p.info);
break;
}
temp=temp.next;
}
p.next=temp.next;
temp.next=p;
}
//修改节点内容
public void uodata(pNode p){
pNode temp=head.next;
if(isEmpty()){
System.out.println("链表为空无法进行修改!");
return;
}
while (true){
if(temp.info==p.info){
// System.out.printf("找到要修改值为%d的节点了\n",temp.info);
break;
}
if(temp.next==null){
System.out.println("没找到要修改的节点");
return;
}
temp=temp.next;
}
temp.name=p.name;
temp.nickname=p.nickname;
// System.out.println("修改成功!");
}
//删除节点
public void delete(pNode p){
pNode temp=head;
if(isEmpty()){
System.out.println("链表为空无法删除!");
return;
}
while (true){
if(temp.next.info==p.info){
// System.out.println("找到要删除的节点了!");
break;
}
temp=temp.next;
}
temp.next=p.next;
// System.out.println("删除成功!");
}
//查找链表中的有效节点个数(去掉头节点)
public int valid(){
pNode temp=head;
int length=0;
if(isEmpty()){
System.out.println("链表为空!");
return 0;
}
while (temp.next!=null){
length++;
temp=temp.next;
}
return length;
}
//查找倒数第n个节点
public pNode backn(int n){
pNode temp=head.next;
pNode p;
if(isEmpty()){
System.out.println("链表为空,无法查找第n个节点");
return null;
}
int len=valid()-n;
for(int i=0;i<len;i++){
if(temp.next==null){
System.out.println("没找到倒数第n个节点");
break;
}
temp=temp.next;
}
p=temp;
return p;
}
//显示链表所有数据
public void showData(){
if(isEmpty()){
System.out.println("链表是空哒,请先填写");
return;
}
pNode temp=head.next;
while (true){
if(temp==null)break;
System.out.println(temp);
temp=temp.next;
}
}
private pNode newnode=new pNode(0,"","");
//链表反转(创建一个新的链表)
public void reverse(){
pNode temp=head.next;
pNode p=null;
if(isEmpty()){
System.out.println("链表为空无法进行反转");
return;
}
while (temp!=null){
p=temp.next;
temp.next=newnode.next;
newnode.next=temp;
temp=p;
}
head.next=newnode.next;
}
//链表反转(利用栈倒着输出(先进后出))
public void stackway(){
if(head.next==null){
System.out.println("链表为空无法使用栈结构输出");
return;
}
Stack<pNode> stack = new Stack<pNode>();
pNode temp=head.next;
//入栈
while (temp!=null){
stack.push(temp);
temp=temp.next;
}
//出栈
while (stack.size()>0){
System.out.println(stack.pop());
}
}
}
//节点对象
class pNode{
public int info;
public String name;
public String nickname;
public pNode next;
public pNode(int info, String name, String nickname){
this.info=info;
this.name=name;
this.nickname=nickname;
}
@Override
public String toString() {
return "pNode{" +
"info=" + info +
", name='" + name + '\'' +
", nickname='" + nickname + '\'' +
'}';
}
}
运行结果展示:
链表输出: pNode{info=1, name='小明', nickname='数学天才'} pNode{info=2, name='周树人', nickname='鲁迅'} pNode{info=3, name='珍妮', nickname='绿恐龙'} pNode{info=4, name='小红', nickname='数学辅助'} pNode{info=5, name='李华', nickname='英语幽灵'} pNode{info=7, name='唐僧', nickname='长生不老肉'} 修改4和删除1后: pNode{info=2, name='周树人', nickname='鲁迅'} pNode{info=3, name='珍妮', nickname='绿恐龙'} pNode{info=4, name='孙悟空', nickname='弼马温'} pNode{info=5, name='李华', nickname='英语幽灵'} pNode{info=7, name='唐僧', nickname='长生不老肉'} 有效节点个数为:5 倒数第3个节点内容为:pNode{info=4, name='孙悟空', nickname='弼马温'} 反转链表结果为: pNode{info=7, name='唐僧', nickname='长生不老肉'} pNode{info=5, name='李华', nickname='英语幽灵'} pNode{info=4, name='孙悟空', nickname='弼马温'} pNode{info=3, name='珍妮', nickname='绿恐龙'} pNode{info=2, name='周树人', nickname='鲁迅'} 通过栈方式反转链表: pNode{info=2, name='周树人', nickname='鲁迅'} pNode{info=3, name='珍妮', nickname='绿恐龙'} pNode{info=4, name='孙悟空', nickname='弼马温'} pNode{info=5, name='李华', nickname='英语幽灵'} pNode{info=7, name='唐僧', nickname='长生不老肉'} |