单链表
基本概念
单链表分为带头结点和不带头节点。带头结点的单链表,头指针head指向头结点,头结点中不包含任何的信息。例如下图
单链表的基本操作
单链表的增加
单链表的无序增加
思路
head是头指针,它不能动,因此我们需要创建临时遍历。
主要使用的方法便是尾插法,首先遍历整个链表,找到最后一个节点。再在链表的尾部插入结点。
代码实现
//创建英雄节点
package LinkedList链表;
import java.util.Stack;
public class SingleLinkedListDemo {
public static void main(String[] args) {
HeroNode heroNode1 = new HeroNode(1,"宋江","及时雨");
HeroNode heroNode2 = new HeroNode(2,"吴用","智多星");
HeroNode heroNode3 = new HeroNode(3,"林冲","豹子头");
HeroNode heroNode4 = new HeroNode(4,"卢俊义","玉麒麟");
HeroNode heroNode5 = new HeroNode(4,"卢哥","玉麒麟~~");
SingleLinkedList singleLinkedList = new SingleLinkedList();
singleLinkedList.add(heroNode1);
singleLinkedList.add(heroNode4);
singleLinkedList.add(heroNode2);
singleLinkedList.add(heroNode3);
}
}
//创建单链表
class SingleLinkedList{
private HeroNode head = new HeroNode(0,"","");
public HeroNode getHead() {
return head;
}
public void add(HeroNode heroNode){
//因为head是头指针,因此我们要创建一个临时变量
HeroNode temp = head;
//遍历链表,找到最后
while (true){
if(temp.next == null){
break;
}
//如果没有找到最后,继续往后找
temp = temp.next;
}
//退出循环说明找到最后一个,将最后一个指向新的节点
temp.next = heroNode;
}
}
class HeroNode{
public int num;
public String name;
public String nickname;
public HeroNode next;
//生成构造器
public HeroNode(int num, String name, String nickname) {
this.num = num;
this.name = name;
this.nickname = nickname;
}
//重写toString
@Override
public String toString() {
return "heroNode{" +
"num=" + num +
", name='" + name + '\'' +
", nickname='" + nickname + '\'' +
'}';
}
}
单链表的有序增加
思路
在单链表中,我们需要找到的temp是位于添加位置的前一个结点,不然插入不了
1)因为head为头结点,不能变动,因此还是创建一个临时变量。同时需要创建一个boolean标志值变量,用来判断添加的标号是否存在
2)判断链表是否为空
3)判断结点中数据类的编号的大小
代码实现
单链表内部方法
public void addByOrder(HeroNode heroNode){
HeroNode temp = head;
boolean flag = false;
while (true){
if(temp.next == null){
break;
}
if (temp.next.num > heroNode.num){
break;
}else if (temp.next.num == heroNode.num){
flag = true;
break;
}
temp = temp.next;
}
if(flag){
System.out.println("输入的编号已经存在");
}else {
heroNode.next = temp.next;
temp.next = heroNode;
}
}
单链表的遍历
思路
主要原理为循环遍历单链表,判定结点是否为空。
代码实现
单链表内部方法
public void list(){
if(head.next == null){
System.out.println("链表为空");
return;
}
//因为head是头指针,因此我们要创建一个临时变量
HeroNode temp = head.next;
while (true){
if(temp == null){
break;
}
System.out.println(temp);
temp = temp.next;
}
}
单链表的删除
思路
给定形参编号,删除数据域为该编号的结点
1)创建临时变量代替头结点,创建boolean标志值。
2)循环遍历单链表,找到数据域为指定编号的结点。
代码实现
单链表内部方法
public void delete(int no){
HeroNode temp = head;
boolean flag = false;
while (true){
if(temp.next == null){
break;
}
if (temp.next.num == no){
flag = true;
break;
}
temp = temp.next;
}
if (flag){
temp.next = temp.next.next;
}else {
System.out.println("没有该节点");
}
}
单链表的修改
思路
删除指定编号的结点
1)循环遍历单链表,找到指定编号的结点
2)进行删除操作(被删除结点的上一个结点的next指针指向被删除结点下一个结点)
代码实现
public void update(HeroNode heroNode){
HeroNode temp = head.next;
boolean flag = false;
while (true){
if(temp == null){
break;
}
if (temp.num == heroNode.num){
flag = true;
break;
}
temp = temp.next;
}
if(flag){
temp.name = heroNode.name;
temp.nickname = heroNode.nickname;
}else {
System.out.println("没有找到");
}
}
单链表的进阶操作
返回单链表中有效节点个数,不包含头结点
思路
主要是利用循环遍历单链表,节点不为空。
代码实现
public static int getLength(HeroNode head){
if (head.next == null){
return 0;
}
int length = 0;
HeroNode temp = head.next;
while (temp != null){
temp = temp.next;
length++;
}
return length;
}
打印倒数第k个结点
思路
找到有效个数,(打印倒数第k个 )== (打印整数length-k个)
代码实现
public static HeroNode getLastNode(HeroNode head, int k){
if(head.next == null){
return null;
}
int length = getLength(head);
if(k<=0 || k>length){
return null;
}
HeroNode temp = head.next;
for (int i = 0;i < length - k;i++){
temp = temp.next;
}
return temp;
}
单链表的反转
思路
1)先定义一个新的头结点
2)从头遍历原来的链表,每遍历一个结点,就取出,放在新的头结点最前端。
3)head.next = reverseHead.next,使新的头结点第一个元素连接到原来头结点后边
代码实现
public static void reversetList(HeroNode head){
if(head.next == null || head.next.next == null){
return;
}
HeroNode cur = head.next;
HeroNode next = null;
HeroNode reverseHead = new HeroNode(0,"","");
while (cur != null){
//记录当前节点的下一个结点内容,如果不记录链表会断开
next = cur.next;
//将新节点后边的结点连接点当前指针的后边
cur.next = reverseHead.next;
//每次循环都令新的头结点后面插入cur结点
reverseHead.next = cur;
//令指针向后移动
cur = next;
}
head.next = reverseHead.next;
}
不改变单链表结构逆序输入单链表中内容
思路
1)先将单链表进行反转,再遍历。缺点会改变单链表的结构。
2)利用栈这个数据结构先进后出的特点。实现逆序打印。
代码实现
public static void printContent(SingleLinkedList singleLinkedList){
if (singleLinkedList.getHead().next == null){
return;
}
Stack<HeroNode> stack = new Stack<HeroNode>();
while (singleLinkedList.getHead().next != null){
stack.push(singleLinkedList.getHead().next);
singleLinkedList.getHead().next = singleLinkedList.getHead().next.next;
}
while (stack.size()>0){
System.out.println(stack.pop());
}
}
声明
本文是作者在学习数据结构中的一些笔记,希望能够帮助到大家。作者才疏学浅,如有错误,欢迎批评指正。