@单链表功能实现顺序添加,倒置,逆序打印等
Welcome to Lee’s Code
你好! 这是我第一次使用写博客,我将在空闲时间更新java实现数据结构,因为代码手敲,更新需要在写出代码的基础上加入详细的注释,以便读者阅读代码,持续更新数据结构和算法,喜欢留个关注,有问题留言
代码功能
完整注释,每个语句都有
1.添加 排序!!!!
2.删除
3.找到倒数index结点
4.倒置
5.逆序打印
6.获取单链表结点的个数(如果带头结点的链表,不统计头结点)
7.更新结点
8.遍历
package linkedlist;
import java.util.Stack;
public class SingleLinkedList {
public static void main(String[] args) {
// TODO Auto-generated method stub
HeroNode hero1 = new HeroNode(1, "宋江", "及时雨");
HeroNode hero2 = new HeroNode(2, "卢俊义", "玉麒麟");
HeroNode hero3 = new HeroNode(3, "吴用", "智多星");
HeroNode hero4 = new HeroNode(4, "林冲", "豹子头");
HeroNode hero5 = new HeroNode(5, "武松", "打虎哥");
SingleLinkedList_ singleLinkedList = new SingleLinkedList_();
/**
//正常添加 不排序!!!!
singleLinkedList.add(hero1);
singleLinkedList.add(hero2);
singleLinkedList.add(hero3);
singleLinkedList.add(hero5);
singleLinkedList.add(hero4);
singleLinkedList.list();
*/
System.out.println("顺序添加结点链表为:");
singleLinkedList.addByOrder(hero1);
singleLinkedList.addByOrder(hero2);
singleLinkedList.addByOrder(hero5);
singleLinkedList.addByOrder(hero5);
singleLinkedList.addByOrder(hero3);
singleLinkedList.addByOrder(hero4);
singleLinkedList.list();
System.out.println("修改后结点链表为:");
HeroNode hero6 = new HeroNode(5, "武松", "武二郎");
singleLinkedList.update(hero6);
singleLinkedList.list();
//删除
System.out.println("删除结点的链表为:");
singleLinkedList.delete(2);
singleLinkedList.list();
System.out.println("有效结点个数:"+getLength(singleLinkedList.gethead()));
//倒数index结点
int index = 2;
HeroNode res = findLastIndexNode(singleLinkedList.gethead(),index);
System.out.println("倒数第"+index+"个结点 :"+res);
//倒置
System.out.println("倒置后结点链表为:");
reverseList(singleLinkedList.gethead());
singleLinkedList.list();
//逆序打印
System.out.println("逆序打印链表为:");
reversePrint(singleLinkedList.gethead());
}
//方法:获取单链表结点的个数(如果带头结点的链表,不统计头结点)
public static int getLength(HeroNode head) {
if(head.next == null) {
return 0;
}
int length = 0;
HeroNode temp = head.next;
while (temp != null) {
length++;
temp = temp.next;
}
return length;
}
//编写一个方法,接受head;index 倒数第index个结点
//遍历到length-index +1个结点
//就是说 遍历length-index步骤**for循环
public static HeroNode findLastIndexNode(HeroNode head,int index) {
if(head.next == null) {
return null;//没找到
}
int size = getLength(head);
if(index<=0||index>size) {
return null;
}
HeroNode cur = head.next;
for(int i= 0;i<size-index;i++) {
cur = cur.next;
}
return cur;
}
/**编写一个方法 倒置节点链表 接受head
* 1.HeroNode reversehead ;
* 第一个遍历到的直接连到reversehead后,cur = reversehead.next
* 2.遍历到一个节点就连接到reversehead后,此节点.next = cur,
* cur = 此节点 , reversehead.next = cur;
* 3.重复2,直到遍历到最后一个
* 4.head.next = cur(revese.next);
*/
public static void reverseList(HeroNode head) {
//空链表 ||一个节点 直接返回 不倒置
if(head.next == null||head.next.next == null) {
System.out.println("空链表 或一个结点,无需倒置!! ");
return;
}
//定义一个辅助 的指针(变量) 帮助我们遍历原来的链表
HeroNode cur = head.next;
HeroNode next = null;//cur的下一个
HeroNode reverseHead = new HeroNode (0,"","");
//遍历原来的链表 完成倒置步骤
while(cur!=null) {
next = cur.next;//暂时保存cur的下一个结点
cur.next = reverseHead.next;
reverseHead.next = cur;
cur = next;
}
head.next = reverseHead.next;
}
/**
* 逆序打印单链表
* 1.倒置操作,会破坏单链表,不建议!!!!!!!!浪费空间
* 2.利用栈的操作 先进后出
* */
public static void reversePrint(HeroNode head) {
if(head.next == null) {
return;
}
//创建栈,压栈
Stack<HeroNode> stack = new Stack<HeroNode>();
HeroNode cur = head.next;
while(cur!=null) {
stack.push(cur);//add或push
cur = cur.next;
}
//遍历栈
while(stack.size()>0) {
System.out.println(stack.pop());
}
}
}//主类尾巴
//定义一个SingleLinkedList管理HeroNode
class SingleLinkedList_{
//先初始化一个头结点
private HeroNode head = new HeroNode(0,"","");
public HeroNode gethead() {
return head;
}
//添加节点到单向链表
//思路:当不考虑编号的顺序时
//1.找到当前链表的最后节点,2.将next指向新节点
public void add(HeroNode heroNode) {
HeroNode temp = head;
while(true) {
if(temp.next ==null) {
break;//temp到了最后的结点
}
//temp后移
temp = temp.next;
}
//连接到最后的节点上
temp.next = heroNode;
}
//顺序添加
public void addByOrder(HeroNode heroNode) {
//temp找到要插入的前一个结点
HeroNode temp = head;
boolean falg = false;
//标记添加的编号是否存在,默认false
while(true) {
if(temp.next ==null) {
break;
}
if(temp.next.no > heroNode.no) {
break;
}
else if(temp.next.no ==heroNode.no) {
falg = true;
break;
}
temp =temp.next;
}
if(falg) {
System.out.printf("%d号结点已经存在!!\n",heroNode.no);
}else {
heroNode.next = temp.next; //第一个结点特殊意思: 加入结点的下一个置空 temp.next是null
temp.next = heroNode;
}
}
//修改结点信息
public void update(HeroNode heroNode) {
if(head.next == null) {
System.out.println("链表为空!!");
return;
}
HeroNode temp = head.next;
while(true) {
if(temp == null) {
System.out.printf("没有找到编号为%d的结点!!\n",heroNode.no);
break;//已近遍历完毕 到最后节点的next空域
}
if(temp.no == heroNode.no) {
temp.name = heroNode.name;
temp.nickname = heroNode.nickname;
break;
}
temp = temp.next;
}
}
//删除结点
public void delete(int id) {
HeroNode temp = head;
if(head.next==null) {
System.out.println("链表为空!!");
}
else {
while(true) {
if(temp.next == null) {
System.out.printf("没找到%d号结点!!",id);
break;
}
if(temp.next.no==id) {
temp.next =temp.next.next;
break;
}
temp = temp.next;
}
}
}
//显示链表
public void list() {
if(head.next ==null) {
System.out.println("链表为空!!");
return;
}
HeroNode temp = head.next;
while(true) {
if(temp==null) {
break;
}
System.out.println(temp);
temp = temp.next;
}
}
}
//定义一个HeroNode,每个HeroNode对象都是一个节点
class HeroNode{
public int no ;
public String name;
public String nickname;
public HeroNode next;
//构造器
public HeroNode (int no,String name,String nickname) {
this.no = no;
this.name = name;
this.nickname =nickname;
}
//注意!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//为了显示方便,我们重新toString()
public String toString() {
return "HeroNode [no = " + no+ ",name="+name+",nickname="+nickname+"]";
}
}