package SingleLinkedList;
//链表结点
public class HeroNode {
//数据域
public int no;
public String name;
public String nickname;
//指针域
public HeroNode next;
//构造器
public HeroNode(int no,String name,String nickname){
this.name=name;
this.no=no;
this.nickname=nickname;
}
@Override
public String toString() {
return "HeroNode{" +
"no=" + no +
", name='" + name + '\'' +
", nickname='" + nickname +
'}';
}
}
package SingleLinkedList;
//链表类
public class SingleLinkedList {
//先初始化一个头结点,头结点不要动,不存放具体数据
private HeroNode head=new HeroNode(0,"","");
public HeroNode getHead() {
return head;
}
//添加结点到单链表
//思路,当不考虑编号顺序时,
//找到当前链表的最后结点,插入;
public void add(HeroNode heroNode){
//因为头结点不能动,需要一个辅助结点遍历temp;
HeroNode temp=head;
//遍历链表找到最后
while (true){
//找到链表最后
if (temp.next==null){
break;
}
//没有找到最后,temp后移
temp=temp.next;
}
//插入链表中
temp.next=heroNode;
}
//第二种添加英雄方式,根据排名将英雄插入到指定位置,如果有排名,则添加失败
public void addByOrder(HeroNode heroNode){
//找到添加位置的前一个结点
HeroNode temp=head;
boolean flag=false;//编号是否已经存在
//找位置
while (true){
if (temp.next==null){
//temp已到最后
break;
}
if (temp.next.no>heroNode.no){
break;
}else if (temp.next.no==heroNode.no){
//编号已存在
flag=true;
break;
}
temp=temp.next;//后移
}
//判断flag的值
if (flag){
//已存在,不能添加
System.out.printf("准备插入的英雄编号%d已存在,不能加入\n",heroNode.no);
}else {
//插入到temp后面
heroNode.next=temp.next;
temp.next=heroNode;
}
}
//修改结点
/**
* 根据编号来找到结点进行修改
* @param newHeroNode
*/
public void update(HeroNode newHeroNode ){
//判断是否为空
if (head.next==null){
System.out.println("链表为空。。。");
return;
}
HeroNode temp=head.next;
boolean flag=false;//表示是否找到该节点
while(true){
if (temp==null){
break;//遍历完成
}
if (temp.no==newHeroNode.no){
//找到
flag=true;
break;
}
temp=temp.next;
}
if (flag){
//修改结点
temp.name=newHeroNode.name;
temp.nickname=newHeroNode.nickname;
// temp=newHeroNode;//相当于把temp指向了newHeroNode,没有修改链表的值
}else {
//没有找到
System.out.printf("没有找到编号为 %d 的结点,不能修改\n",newHeroNode.no);
}
}
//删除结点
public void delete(int n){
if (head.next==null){
System.out.println("链表为空。。。");
return;
}
HeroNode temp=head;//注意!
Boolean flag=false;
while (true){
if (temp.next.no==n){
flag=true;
break;
}
temp=temp.next;
}
if (flag){
//删除
temp.next=temp.next.next;
}else {
System.out.printf("要删除的%d结点不存在\n",n);
}
}
//显示链表[遍历]
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=temp.next;
}
}
}
package SingleLinkedList;
public class SingleLinkedListDemo {
public static void main(String[] args) {
//进行测试
//创建结点
HeroNode hero1=new HeroNode(1,"宋江","及时雨");
HeroNode hero2=new HeroNode(2,"卢俊义","玉麒麟");
HeroNode hero3=new HeroNode(3,"吴用","智多星");
HeroNode hero4=new HeroNode(4,"林冲","豹子头");
//创建链表
SingleLinkedList singleLinkedList=new SingleLinkedList();
/*System.out.println("按照添加顺序排列:");
//加入链表
singleLinkedList.add(hero1);
singleLinkedList.add(hero2);
singleLinkedList.add(hero3);
singleLinkedList.add(hero4);*/
//按no排序
singleLinkedList.addByOrder(hero2);
singleLinkedList.addByOrder(hero4);
singleLinkedList.addByOrder(hero1);
singleLinkedList.addByOrder(hero3);
System.out.println("修改前...");
singleLinkedList.list();
/*//修改结点
HeroNode newHero=new HeroNode(1,"舒奇","魁拔");
singleLinkedList.update(newHero);
*/
singleLinkedList.delete(1);
singleLinkedList.delete(4);
System.out.println("修改后...");
//打印链表
singleLinkedList.list();
}
}
面试题!
package Interview_Questions;
import SingleLinkedList.*;
import java.util.Scanner;
import java.util.Stack;
public class SingleLinkedList_IQ extends SingleLinkedList{
public static void main(String[] args) {
//使用继承
SingleLinkedList_IQ singleLinkedList_iq=new SingleLinkedList_IQ();
//要在psvm内使用继承的方法!
HeroNode hero1=new HeroNode(1,"1","1");
HeroNode hero2=new HeroNode(2,"2","2");
HeroNode hero3=new HeroNode(3,"3","3");
HeroNode hero4=new HeroNode(4,"4","4");
HeroNode hero5=new HeroNode(5,"5","5");
HeroNode hero6=new HeroNode(6,"6","6");
/*singleLinkedList_iq.addByOrder(hero1);
singleLinkedList_iq.addByOrder(hero2);
singleLinkedList_iq.addByOrder(hero3);
singleLinkedList_iq.addByOrder(hero4);
singleLinkedList_iq.addByOrder(hero5);
singleLinkedList_iq.addByOrder(hero6);
singleLinkedList_iq.list();*/
//1,统计结点个数
//实例对象可以调用类(static)方法!编译器提示有点慢而已!
// System.out.println("结点个数为:"+singleLinkedList_iq.getLength(singleLinkedList_iq.getHead()));
//2,倒数第k个结点
/* Scanner scanner=new Scanner(System.in);
System.out.println("请输入要寻找倒数第几个结点?");
int k=scanner.nextInt();
System.out.printf("倒数第%d个结点是:"+singleLinkedList_iq.findLastIndexNode(singleLinkedList_iq.getHead(),k),k);*/
//3,单链表反转
/* singleLinkedList_iq.reverse(singleLinkedList_iq.getHead());
System.out.println("链表反转后为:");
singleLinkedList_iq.list();*/
//4,逆序打印单链表
// singleLinkedList_iq.reversePrint(singleLinkedList_iq.getHead());
//5,合并两个有序链表
SingleLinkedList_IQ linkedList1=new SingleLinkedList_IQ();
linkedList1.addByOrder(hero1);
linkedList1.addByOrder(hero3);
linkedList1.addByOrder(hero5);
SingleLinkedList_IQ linkedList2=new SingleLinkedList_IQ();
linkedList2.addByOrder(hero2);
linkedList2.addByOrder(hero4);
linkedList2.addByOrder(hero6);
/*//合并链表,返回的是不带头结点的链表!
HeroNode link3 = merge1(linkedList1.getHead().next, linkedList2.getHead().next);
while (link3!=null){
System.out.println(link3);
link3=link3.next;
}*/
/* merge2(linkedList1.getHead(), linkedList2.getHead());
linkedList1.list();*/
merge3(linkedList1.getHead(), linkedList2.getHead());
linkedList1.list();
}
//1,统计有效结点个数
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;
}
//2,查找单链表中的倒数第K个结点【新浪面试题】
/*思路:
1,首先遍历链表得到总的结点个数n
2,第二次遍历(n-k)个结点*/
public static HeroNode findLastIndexNode(HeroNode head,int k){
if (head.next==null){
System.out.println("链表为空!");
return null;
}
int size = getLength(head);
if (k<=0||k>size){
System.out.println("输入的K值有误!");
return null;
}
//定义赋值变量
HeroNode cur = head.next;
for (int i=1;i<=size-k;i++){
cur=cur.next;
}
return cur;
}
//3,链表反转(腾讯面试题)
/*思路:
* 头插法*/
public static void reverse(HeroNode head){
//如果是空链表或者节点个数为1,则不用反转
if (head.next==null||head.next.next==null){
System.out.println("链表为空或者结点个数为1不需反转。");
return;
}
HeroNode cur=head.next;
head.next=null;//原链表置空!
HeroNode next;//指向cur的下一个结点
while(cur!=null){
next=cur.next;//先保留cur的下一个结点,以防止断链!
cur.next=head.next;
head.next=cur;
cur=next;
}
}
//4,逆序打印链表(百度面试题)
/*
* 方法1:链表反转,再打印输出
* 方法2:使用栈*/
public static void reversePrint(HeroNode head){
if (head.next==null){
System.out.println("链表为空...");
return;
}
HeroNode cur=head.next;
Stack<HeroNode> stack = new Stack<>();
//链表入栈
while (cur!=null){
stack.push(cur);
cur=cur.next;
}
//链表出栈,打印
while (stack.size()>0){
System.out.println(stack.pop());
}
}
//5.1,合并两个有序(从小到大)列表,【合并为从小到大】
/*思路:
* 1,递归:相当于每次比较两个结点,返回较小的结点!(注意无头结点)
*/
public static HeroNode merge1(HeroNode head1,HeroNode head2){
//结点都为null,返回null
if (head1==null&& head2==null)
return null;
if (head1==null)
return head2;
if (head2==null)
return head1;
HeroNode newhead=null;
if (head1.no>head2.no){
//每次把小的结点返回
newhead=head2;
//继续比较head2的下一个结点
newhead.next=merge1(head1,head2.next);
}else {
newhead=head1;
newhead.next=merge1(head1.next,head2);
}
return newhead;
}
//5.2,合并两个有序(从小到大)列表,【合并为从小到大!!!】
//使用循环
public static HeroNode merge2(HeroNode head1,HeroNode head2){
HeroNode cur1=head1.next;
HeroNode cur2=head2.next;
HeroNode temp=null;//用来保存较小的结点
//合并到头结点head1后
head1.next=null;
HeroNode next=head1;
while (cur1!=null&&cur2!=null){
if (cur1.no>cur2.no){
temp=cur2;
cur2=cur2.next;//后移一位
}else {
temp=cur1;
cur1=cur1.next;
}
next.next=temp;
next=temp;
}
//当cur和cur2分别未结束
while(cur1!=null){
temp=cur1;
cur1=cur1.next;
next.next=temp;
next=temp;
}
while(cur2!=null){
temp=cur2;
cur2=cur2.next;
next.next=temp;
next=temp;
}
return head1;
}
//5.3,合并两个有序(从小到大)列表,【合并为从小到小!!!】
//使用循环
public static HeroNode merge3(HeroNode head1,HeroNode head2){
HeroNode cur1=head1.next;
HeroNode cur2=head2.next;
HeroNode temp=null;//用来保存较小的结点
//合并到头结点head1后
head1.next=null;
while (cur1!=null&&cur2!=null){
if (cur1.no>cur2.no){
temp=cur2;
cur2=cur2.next;//后移一位
}else {
temp=cur1;
cur1=cur1.next;
}
//找到较小的结点后,插入到新的链表(头插法,顺序变为从大到小)
temp.next=head1.next;
head1.next=temp;
}
//当cur和cur2分别未结束
while(cur1!=null){
temp=cur1;
cur1=cur1.next;
//头插法插入->从大到小
temp.next=head1.next;
head1.next=temp;
}
while(cur2!=null){
temp=cur2;
cur2=cur2.next;
//头插法插入->从大到小
temp.next=head1.next;
head1.next=temp;
}
return head1;
}
}