学习链表和二叉树
链表
一、单向链表
1.1单向链表- 添加数据到最后
Node --> Node --> Node --> Node --> 新Node
【data|next】–>【data|next】–>【data|next】–>【data|next】–>[ | ]
首先,创建一个 Node 对象 类
// 运行软件 idea
// JDK1.8
public class Node{
private Integer data; //节点中的数据
private Node next; //存储的下一个节点
//构造方法
public Node(Integer data){
this.data = data;}
//get set 方法
public Integer getData() {
return data;
}
public void setData(Integer data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
节点对象创建完毕,那么开始创建 单向链表 类
public class singlyLinkedList{
private Node head; // 表示单向链表的头指针
private int size; //表示单向链表的长度
//无参构造法
public singlyLinkedList(){
}
//get 和 set 方法,由于 size 长度不需要设置,所以仅仅需要 get方法
public Node getHead(){
return head;}
public void setHead(Node head){
this.head = head;}
public int getSize(){
return size;}
//下面就是关于链表的操作方法的编写 我写在下面的部分
//方法a *****将data 添加到单向链表的 最后 *******
//方法b *****将data 插入到单向链表中 *******
//方法c ***** 单向链表-删除元素,返回被删除元素 data****
//方法d ***** 单线链表-获取指定位置的数据 data *******
//遍历链表
public void print(){
Node temp = head;
while(temp != null){
//不是空节点的,就进行循环,直到节点为空,才退出循环
System.out.println(temp.getData()); //输出当前节点的 data
temp = temp.getNext(); //节点移动到下一位
}
}
}
为了整理复习方便,将 单向链表的 几个方法单独取出来。直接将对应的代码插入回singlyLinkedList 即可使用。 注释仅仅用来理解代码逻辑,不可用于真实环境。
a.添加Node 到单向链表的最后
//方法 *****将data 添加到单向链表的 最后 *******
//这个是添加 Node 到链表的最后
public boolean add(Integer data){
//创建 对象
Node node = new Node(data);
//如果链表是第一次添加,即 head(头结点) 为空,那么直接插入
if(head == null){
head = node; //直接让node 等于头结点
}else{
Node temp = head; //设定一个temp 用来存储节点,目的是 找到最后的那个节点 X
while(temp.getNext() != null){
//节点的指针为空,才会退出循环
temp = temp.getNext(); // 节点后移一位
}
temp.setNext(node); // 把X 的指针指向-->新插入节点 node.
}
size++; // 节点数量加一
return true; //这里插入完成。
}
b.将data 数据插入到单向链表的中间
//方法b *****将data 插入到单向链表中 *******
//插入元素到链表的中间
//index 表明插入位置,data 插入数据
public boolean add(int index,Integer data){
Node temp = new Node(data);
//拿到数据,首先应该判断,index 的值是否超出,链表的大小(size)
if(index >= size){
//抛出越界异常
throw new RuntimeException("越界异常!IndexOutOfBoundException,index:" + index + ",size:" + size);
}
//如果数据插入到第一位头结点,即index == 0;
if(index == 0){
node.setNext(head);
head = node; //及时把头结点更新为,新插入的那个节点
}else{
//插入到单向链表的中间
Node temp = head;
for(int i=0; i<index-1;i++){
//这里index -1 是因为,如果要插入到第4 位,用户输入4,但链表从0 开始计数,所以需要减一
temp = node.getNext(); //拿到指定位置的节点
}
node.setNext(temp.getNext());// 把temp 的指针复制给 node指针
temp.setNext(node); //把temp 的指针指向 node
}
size++;
return true;
}
c.单向链表-删除元素
单向链表中,删除B节点-即让A节点的指针指向C节点,B的指针置空
//******** 这个remove 是删除 最后一位的元素************
public Integer remove(){
//如果链表为空
if(head == null){
throw new RunTimeException("链表为空!不能删除");
}
//如果链表中就只有一个元素
if(head.getNext() == null){
//如果头节点的指针为空,只有头结点
Integer data = head.getData();
head = null;
return data; //返回这个元素
}
// 删除最后的元素
Node t0 = null;
Node t1 = head;
while(t1.getNext() != 0){
t0 = t1;
t1 = t1.getNext();
}// t0 在倒数第二个,t1 为倒数第一个
t0.setNext(null); // t0 的指针置空,表示自己成为了最后一个
return t1.getData(); // 返回删除节点的数据
}
//******** 这个remove 是删除 指定位置的元素************
public Integer remove(int index){
if(index >= size){
throw new RuntimeException("越界异常!IndexOfBoundException,index:"+index+",size:"+size);
}
//如果是头结点,那么直接删除头节点
if(head.getNext = null){
Integer data = head.getData(); //把数据从头里边取出来
head = head.getNext(); //把后一个节点定为头结点
return data;
}
// 删除指定位置的元素
Node t0 = null;
Node t1 = head;
for(int i = 0;i < index ;i++){
//实现 双指针依次向后移动
t0 = t1;
t1 = t1.getNext(); //t1 就是准备被删除的 节点
}
t0.setNext(t1.getNext()); //把 被删除节点的指针指向 复制给前一个节点
t1.setNext(null);
return t1.getData();
}
d 单线链表-获取指定位置的数据 data
//根据输入的index 值, 找到目标节点的data 放回这个data值
public Integer get(int index){
if(index < 0 || index >= size){
throw new RuntimeException("越界异常!OutOfBoundException,index:"+index+",size"+size);
}
Node temp = head;
for(int i = 0;i<index;i++){
temp = temp.getNext();
}
return temp.getData();
}
测试一下内容
创建 MainTest 类用来测试。
public static void MainTest(String[] args){
singlyLinkedList list = new singlyLinkedList(); //建立单向链表对象
list.add(1);
list.add(2);
list.add(3);
list.print(); // 遍历结果: 1 2 3
list.get(1) //输出结果 2
}