单链表;
单链的增删改查。
1、求单链中的节点个数。
2、查找单链中的倒数第K 个元素。
3、单链表反转(两根线,最后再指向head)
4、从尾到头打印单链(利用栈,反转会改变链的结构,下次不能正常使用)
5、合并两个有序单链。(****)
package com.yhc.linkedlist;
import java.util.Stack;
public class SingleLinkedList {
public static void main(String[] args) {
//先创建头节点head;表示单链表的头。
//每添加一个节点,直接加到链表的最后。
HeroNode hero1 = new HeroNode(1,"宋江","及时雨");
HeroNode hero2 = new HeroNode(2,"卢俊义","玉麒麟");
HeroNode hero3 = new HeroNode(3,"吴用","智多星");
HeroNode hero4 = new HeroNode(4,"林冲","豹子头");
Single single = new Single();
single.add(hero4);
single.add(hero1);
single.add(hero2);
single.add(hero3);
single.list();
// //反转。
// System.out.println("反转之后的列表。");
// reverse(single.getHead());
// single.list();
//反向遍历
System.out.println("利用栈反向遍历:");
reversePrint(single.getHead());
// //插入顺序不按照no顺序。
single.add(hero1);
single.add(hero2);
single.add(hero3);
single.add(hero4);
// //测试 修改
single.addByOrder(hero4);
single.addByOrder(hero1);
single.addByOrder(hero2);
single.addByOrder(hero3);
single.addByOrder(hero3);
single.list();
HeroNode heroNode1 = new HeroNode(1,"老黑","及时雨~~~~~");
single.updata(heroNode1);
System.out.println("修改之后:");
single.list();
// //测试删除
//
// single.addByOrder(hero4);
// single.addByOrder(hero1);
// single.addByOrder(hero2);
// single.addByOrder(hero3);
// single.list();
// single.delete(1);
// single.delete(4);
//
// System.out.println("删除之后:");
// single.list();
//
// System.out.println(getLength(single.getHead()));
// HeroNode findLast = FindLast(single.getHead(), 2);
// System.out.println(findLast);
}
//查找单链表中的倒数第K个节点【新浪面试题】
public static HeroNode FindLast(HeroNode head,int index){
//思路
//1. 编写一个方法,接收head 节点,同时接收一个index
//2. index 表示是倒数第index 个节点
//3. 先把链表从头到尾遍历,得到链表的总的长度getLength
//4. 得到size 后,我们从链表的第一个开始遍历(size-index)个,就可以得到
//5. 如果找到了,则返回该节点,否则返回nulll
if(head.next == null){
return null;
}
int size = getLength(head);
HeroNode cr = head.next;
if(index <= 0 || index > size){
return null;
}
for (int i = 0; i < size-index; i++) {
cr = cr.next;
}
return cr;
}
//将单链表进行反转
public static void reverse(HeroNode head){
//先判断是否为空或者只有一个
if(head.next == null || head.next.next == null){
return;
}
//正常反转
HeroNode cur = head.next;
HeroNode next = null;
HeroNode reverse = new HeroNode(0,"","");
while(cur != null){
next = cur.next;
//其实就是两根线,把cur插到reverse后面
cur.next = reverse.next;
reverse.next = cur;
cur = next;
}
head.next = reverse.next;
}
//利用 栈 将 链表逆序打印。
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);
cur = cur.next;
}
while (stack.size() > 0){
System.out.println(stack.pop());
}
}
//获取单链表中的节点个数
public static int getLength(HeroNode head){
if (head.next == null){ //空链表
return 0;
}
int length = 0;
//不统计头节点,头节点无数据。
HeroNode cur = head.next;
while (cur != null){
length++;
cur = cur.next;
}
return length;
}
}
class Single{
//先初始化一个头节点,头节点一般不存放具体的数据
private HeroNode head = new HeroNode(0,"","");
public HeroNode getHead(){
return head;
}
//添加方法
//第一种添加方式,不按照顺序直接插入到最后面
public void add(HeroNode heroNode){
//找到最后一个节点;
HeroNode temp = head;
while (true){
if (temp.next == null){
break;
}
//如果没有找到,将temp 向后移动
temp = temp.next;
}
//找到最后一个节点,把最后一个节点的next 指向新加的节点
temp.next = heroNode;
}
//第二种添加方式,按照顺序来排
public void addByOrder(HeroNode heroNode){
HeroNode temp = head;
boolean flag = false; //是否找到该节点
while (true){
//判断不能插入的情况
if(temp.next == null){
//表示到最后没有找到
break;
}if(temp.next.no > heroNode.no){
//表示找到了要插入的位置,在temp 后面插入
break;
}else if(temp.next.no == heroNode.no){
flag = true;//说明编号存在
break;
}
temp=temp.next;
}
if(flag){
System.out.println("要插入的"+heroNode.no+"号已经存在!");
}else {
heroNode.next = temp.next;
temp.next = heroNode;
}
}
//修改操作
public void updata(HeroNode heroNode){
//判断是否为空
if(head.next == null){
System.out.println("该链表为空链表!");
return;
}
HeroNode temp = head.next;
Boolean flag = false;
while (true){
if (temp == null){
break;
}if(temp.no == heroNode.no){
flag = true;
break;
}
temp = temp.next;
}
if(flag) {
//表示找到
temp.name = heroNode.name;
temp.sickname = heroNode.sickname;
}else{
//表示没有找到
System.out.println("修改的数据不存在");
}
}
//删除节点
public void delete(int num){
HeroNode temp = head;
Boolean flag = false;
while (true){
if (temp.next == null){
break;//最后一个节点
}if(temp.next.no == num){
flag = true;
break;
}
temp = temp.next;
}
if (flag){
//存在这个节点,并找到了。删除
temp.next = temp.next.next;
}else {
System.out.println("您要删除的" + num +"号不存在!");
}
}
//显示遍历
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;
}
}
}
//先创建头节点
class HeroNode{
public int no;
public String name;
public String sickname;
public HeroNode next;
public HeroNode(int no, String name, String sickname) {
this.no = no;
this.name = name;
this.sickname = sickname;
}
@Override
public String toString() {
return "headNode{" +
"no=" + no +
", name='" + name + '\'' +
", sickname='" + sickname + '\'' +
'}';
}
}
双向链表;
增删改查
package com.yhc.linkedlist;
public class DoubleLinkedList {
public static void main(String[] args) {
System.out.println("双链表测试。");
HeroNode2 hero1 = new HeroNode2(1,"宋江","及时雨");
HeroNode2 hero2 = new HeroNode2(2,"卢俊义","玉麒麟");
HeroNode2 hero3 = new HeroNode2(3,"吴用","智多星");
HeroNode2 hero4 = new HeroNode2(4,"林冲","豹子头");
Double aDouble = new Double();
// aDouble.add(hero1);
// aDouble.add(hero2);
// aDouble.add(hero3);
// aDouble.add(hero4);
// aDouble.list();
// aDouble.delete(4);
// aDouble.list();
// aDouble.add(new HeroNode2(5,"夐赨","dage"));
// aDouble.list();
System.out.println("有序插如:");
aDouble.addByOrder(hero4);
aDouble.addByOrder(hero3);
aDouble.addByOrder(hero1);
aDouble.addByOrder(hero2);
aDouble.list();
}
}
//创建 双向链表的类
class Double{
//增删改查
private HeroNode2 head = new HeroNode2(0,"","");
//返回头节点
public HeroNode2 getHead(){
return head;
}
//遍历双向链表
public void list(){
//判断是否为空
if(head.next == null){
System.out.println("链表为空!");
return;
}
HeroNode2 temp = head.next;
while (true){
if (temp == null){
break;
}
System.out.println(temp);
temp = temp.next;
}
}
public void add(HeroNode2 heroNode){
HeroNode2 temp = head;
//直接添加到最后,先找到最后的节点
while(true){
if (temp.next == null){
break;
}
temp = temp.next;
}
temp.next = heroNode;
heroNode.pre = temp;
}
public void addByOrder(HeroNode2 heroNode2){
HeroNode2 temp = head;
boolean flag = false; //判断是否存在
boolean flag1 = false;//是否为最后一个节点
while (true){
if (temp.next == null){
flag1 = true;
break;
}
if(temp.next.no == heroNode2.no){
//该元素存在
flag = true;
break;
}else if(temp.next.no > heroNode2.no){
break;
}
temp = temp.next;
}
if (flag){
System.out.println("元素 已存在!");
}else if (flag1){
//最后面的元素插入
temp.next = heroNode2;
heroNode2.pre = temp;
}else {
//正常情况,temp 前后都有值 四根线
heroNode2.next = temp.next;
temp.next.pre = heroNode2;
temp.next = heroNode2;
heroNode2.pre = temp;
}
}
public void updata(HeroNode2 newHeroNode){
//判断是否为空
if(head.next == null){
System.out.println("链表为空--");
return;
}
//找到该节点
HeroNode2 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.sickname = newHeroNode.sickname;
}else{
System.out.println("没有找到!不能修改!");
}
}
//删除
public void delete(int no){
//判断是否为空
if(head.next == null){
System.out.println("链表为空--");
return;
}
//找到该节点
HeroNode2 temp = head.next;
boolean flag = false;
while(true){
if(temp == null){
break;
}
if(temp.no == no){
flag = true;
break;
}
temp = temp.next;
}
if(flag){
temp.pre.next = temp.next;
//判断找到的是不是最后一个,
if(temp.next != null){
temp.next.pre = temp.pre;
}
}else{
System.out.println("没有找到!不能删除!");
}
}
}
class HeroNode2{
public int no;
public String name;
public String sickname;
public HeroNode2 next; //双向链表,指向下一个节点,默认值null
public HeroNode2 pre; //指向前一个节点 null
public HeroNode2(int no, String name, String sickname) {
this.no = no;
this.name = name;
this.sickname = sickname;
}
@Override
public String toString() {
return "headNode{" +
"no=" + no +
", name='" + name + '\'' +
", sickname='" + sickname + '\'' +
'}';
}
}