LinkList——链表结构——JAVA
一、readme
实现了:
增——(头插入,尾插入,后期任意位置插入)
删——(删除某个位置,删除某个具体data)
查——(查找某一位置的data,根据data查找所有位置)
改——(用新的data代替所有旧的data,在所有匹配的旧的data中用新的data代替特定选择的一个位置旧的data)
备注:思路在注释部分;
TArrayList 就是一个改写的一个数组 ,代码看->另外一篇文章——链接到:
希望指出错误和不足;
二、写代码部分
1.创建LNode类
public class LNode {
/**
* 定义结点结构
* 1、数据 data
* 2、指针 next(下一个结点)
*
* 写自己的构造方法
*
*/
public Object data;
public LNode next;
public LNode(Object data) {
this.data = data;
}
}
2.创建LNodeOp操作类
(0)总体框架
/**
* 定义数据域
* 1、头结点 head
* 2、尾结点 last(就可以从实现尾插法的实现 O(1))
* 3、链表长度size
* .
* 写方法{
* 实现了以下方法:
* 1、从尾部插入O(1)实现
* public void addLast(Object data)
* 2、从头部插入O(1)实现
* public void add(Object data)
* 3、返回index位置的节点的值
* public Object get(int index)
* 4、返回所有值为data的节点的位置
* public TArrayList getPlace(Object data) 备注:这里的TArrayList对象是自己写的动态数组(包含扩容)
* 5、删除index位置的节点 备注:head是第一个节点
* public Object remove(int index)
* 6、删除所有值为data对象的节点
* public void removeObjects(Object data)
* 7、在index位置插入data
* public void set(int index, Object data)
* 8、用newObject取代所有的oldData;
* public void replaceObjects(Object oldData, Object newData)
* }
*
*/
(1) 写数据域——操作结点形成链表对象的
/**
* 定义数据域
* 1、头结点 head
* 2、尾结点 last(就可以从实现尾插法的实现 O(1))
* 3、链表长度size
*/
LNode head = null;
LNode last = null;
int size;
(2)尾插法插入新节点,实现O(1),不再用while循环到最后了
//从尾部插入O(1)实现
/**
* 思路:
* 1、先创建一个新节点(要插入的)
* 2、判断一下是否链表为空(head==null)的情况
* 3、如果为空,则head和last指针就都指向这个新节点就好啦
* 4、如果不为空,则让last指针指向新节点
* 然后,last指针后移(更新last结点)
* 5、size++
*/
public void addLast(Object data) {
LNode newNode = new LNode(data);
if (head == null) {
head = newNode;
last = newNode;
size++;
return;
}
last.next = newNode;
last = newNode;
size++;
}
(3)头插法插入新节点,实现O(1)
//从头部插入O(1)实现
/**
* 思路:
* 1、创建一个新的节点
* 2、判断链表是否为空
* 3、如果为空,那么head和last都指向新节点
* 4、如果不为空,直接让newNode指向head;
* 更新head到newNode(最前面)
* 5、size++
*
*/
public void addHead(Object data){
LNode newNode =new LNode(data);
if(head== null){
head =newNode;
last= newNode ;
size++;
return ;
}
newNode.next=head;
head=newNode;
size++;
}
(4)返回index位置的节点的值
//返回index位置的节点的值
/**
* 思路:
* 1、判断index是否合法
* 2、创建一个指针temp指向head
* 3、for循环遍历index次,temp = temp.next
* 4、返回temp.data
*/
//head里面有data
public Object get(int index) {
if (index < 0 || index >= size) {
return null;
}
LNode temp = head;
for (int i = 0; i < index; i++) {
temp = temp.next;
}
return temp.data;
}
(5)返回所有值为data的节点的位置
/**
* 思路:
* 1、创建一个TArrayList数组对象place(来返回所有位置)
* 2、判断链表是否为空
* 3、创建一个指针temp指向 head
* 4、for循环遍历链表,如果temp.data == data,那么就把i添加到TArrayList对象中
* 5、返回TArrayList数组对象
* -
* 备注:这里的TArrayList对象是自己写的动态数组(包含扩容)
*/
public TArrayList getPlace(Object data) {
TArrayList place = new TArrayList(10);
if (head == null) {
System.out.println("没有数据节点");
return place;
}
LNode temp = head;
int i = 0;
while (temp != null) {
if (temp.data.equals(data)) {
place.addOneObject(i);
}
temp = temp.next;
i++;
}
return place;
}
(6)根据index,删除index位置的节点
/**
* 思路:
* 1、判断index是否合法
* 2、创建一个指针temp指向head
* 3、for循环遍历index-1次,temp = temp.next
* 4、创建一个对象e,把temp.next.data赋值给e
* 5、temp.next = temp.next.next
* 6、size--
* 7、返回e
* 备注:head是第一个节点
*/
public Object remove(int index) {
if (index < 0 || index >= size) {
System.out.println("没有可删除的对象");
return null;
}
LNode temp = head;
for (int i = 0; i < index; i++) {
temp = temp.next;
}
Object e;
e = temp.next.data;
temp.next = temp.next.next;
size--;
return e;
}
(7)删除所有值为data对象的节点
/**
* 思路:
* 1、判断链表是否为空
* 2、创建一个指针temp指向head
* 3、单独判断一下头结点,有存放data的,如果temp.data == data,那么head = head.next
* 4、while循环遍历链表(要判断next),如果temp.next.data == data,那么temp.next = temp.next.next
* 5、size--
*/
public void removeObjects(Object data) {
if (head == null) {
System.out.println("没有可删除的对象");
return;
}
LNode temp = head;
if (temp.data.equals(data)) {
head = head.next;
size--;
}
while (temp.next != null) {
if (temp.next.data.equals(data)) {
temp.next = temp.next.next;
size--;
}
temp = temp.next;
}
}
(8)在index位置插入data
/**
* 思路:
* 1、判断index是否合法
* 2、创建一个指针temp指向head
* 3、for循环遍历index-1次,temp = temp.next
* 4、创建一个新的节点newNode
* 5、newNode.next = temp.next
* 6、temp.next = newNode
* 7、size++
*/
public void set(int index, Object data) {
if (index < 0 || index >= size) {
System.out.println("没有可替换的对象");
return;
}
LNode temp = head;
for (int i = 0; i < index; i++) {
temp = temp.next;
}
temp.data = data;
}
(9)用newObject取代所有的oldData
/**
* 思路:
* 1、判断链表是否为空
* 2、创建一个指针temp指向head
* 3、单独判断一下头结点,因为下面的循环不包括头结点的判断,如果temp.data == oldData,那么temp.data = newData
* 4、while循环遍历链表,如果temp.next.data == oldData,那么temp.next.data = newData
*/
public void replaceObjects(Object oldData, Object newData) {
if (head == null) {
System.out.println("没有可替换的对象");
return;
}
LNode temp = head;
if (temp.data.equals(oldData)) {
temp.data = newData;
}
while (temp.next != null) {
if (temp.next.data.equals(oldData)) {
temp.next.data = newData;
}
temp = temp.next;
}
}
(10)在所有匹配的oldData列表中用新的data替换某一个oldData,(让用户选择)
//得到所有匹配oldData的节点列表,然后让用户选择要替换的节点,然后替换
/**
* 思路:
* 1、判断链表是否为空
* 2、创建一个TArrayList数组对象place(来返回所有位置)
* 3、创建一个指针temp指向head
* 4、for循环遍历链表,如果temp.data == oldData,那么就把i添加到TArrayList对象中
* 5、判断一下place.size是否为0,如果为0,那么就没有可替换的对象
* 6、让用户输入要替换的对象的位置
* 7、判断一下index是否合法,如果不合法,那么就没有可替换的对象
* 8、set(index,newData)
*/
public void replaceOneObject(Object oldData,Object newData){
if(head==null){
System.out.println("没有可替换的对象");
return;
}
TArrayList place ;
place=getPlace(oldData);//调用上面的方法;
if(place.size==0){
System.out.println("没有可替换的对象");
return;
}
Scanner sc=new Scanner(System.in);
System.out.println("请输入要替换的对象的位置");
int index=sc.nextInt();
if(index<0||index>=place.size){
System.out.println("没有可替换的对象");
return;
}
set(index,newData);//调用上面的方法;
}
附录完整代码如下:
package Linklist;
public class LNode {
/**
* 定义结点结构
* 1、数据 data
* 2、指针 next(下一个结点)
*
* 写构造方法
*
*/
public Object data;
public LNode next;
public LNode(Object data) {
this.data = data;
}
}
package Linklist;
import TArrayList.TArrayList;
import java.util.Scanner;
/**
* 定义数据域
* 1、头结点 head
* 2、尾结点 last(就可以从实现尾插法的实现 O(1))
* 3、链表长度size
* .
* 写方法{
* 实现了以下方法:
* 1、从尾部插入O(1)实现
* public void addLast(Object data)
* 2、从头部插入O(1)实现
* public void add(Object data)
* 3、返回index位置的节点的值
* public Object get(int index)
* 4、返回所有值为data的节点的位置
* public TArrayList getPlace(Object data) 备注:这里的TArrayList对象是自己写的动态数组(包含扩容)
* 5、删除index位置的节点 备注:head是第一个节点
* public Object remove(int index)
* 6、删除所有值为data对象的节点
* public void removeObjects(Object data)
* 7、在index位置插入data
* public void set(int index, Object data)
* 8、用newObject取代所有的oldData;
* public void replaceObjects(Object oldData, Object newData)
* }
*
*/
public class LinkOp {
/**
* 定义数据域
* 1、头结点 head
* 2、尾结点 last(就可以从实现尾插法的实现 O(1))
* 3、链表长度size
*/
LNode head = null;
LNode last = null;
int size;
//从尾部插入O(1)实现
/**
* 思路:
* 1、先创建一个新节点(要插入的)
* 2、判断一下是否链表为空(head==null)的情况
* 3、如果为空,则head和last指针就都指向这个新节点就好啦
* 4、如果不为空,则让last指针指向新节点
* 然后,last指针后移(更新last结点)
* 5、size++
*/
public void addLast(Object data) {
LNode newNode = new LNode(data);
if (head == null) {
head = newNode;
last = newNode;
size++;
return;
}
last.next = newNode;
last = newNode;
size++;
}
//从头部插入O(1)实现
/**
* 思路:
* 1、创建一个新的节点
* 2、判断链表是否为空
* 3、如果为空,那么head和last都指向新节点
* 4、如果不为空,直接让newNode指向head;
* 更新head到newNode(最前面)
* 5、size++
*
*/
public void addHead(Object data){
LNode newNode =new LNode(data);
if(head== null){
head =newNode;
last= newNode ;
size++;
return ;
}
newNode.next=head;
head=newNode;
size++;
}
//返回index位置的节点的值
/**
* 思路:
* 1、判断index是否合法
* 2、创建一个指针temp指向head
* 3、for循环遍历index次,temp = temp.next
* 4、返回temp.data
*/
//head里面有data
public Object get(int index) {
if (index < 0 || index >= size) {
return null;
}
LNode temp = head;
for (int i = 0; i < index; i++) {
temp = temp.next;
}
return temp.data;
}
//返回所有值为data的节点的位置
/**
* 思路:
* 1、创建一个TArrayList数组对象place(来返回所有位置)
* 2、判断链表是否为空
* 3、创建一个指针temp指向 head
* 4、for循环遍历链表,如果temp.data == data,那么就把i添加到TArrayList对象中
* 5、返回TArrayList数组对象
* 备注:这里的TArrayList对象是自己写的动态数组(包含扩容)
*/
public TArrayList getPlace(Object data) {
TArrayList place = new TArrayList(10);
if (head == null) {
System.out.println("没有数据节点");
return place;
}
LNode temp = head;
int i = 0;
while (temp != null) {
if (temp.data.equals(data)) {
place.addOneObject(i);
}
temp = temp.next;
i++;
}
return place;
}
//根据index,删除index位置的节点
/**
* 思路:
* 1、判断index是否合法
* 2、创建一个指针temp指向head
* 3、for循环遍历index-1次,temp = temp.next
* 4、创建一个对象e,把temp.next.data赋值给e
* 5、temp.next = temp.next.next
* 6、size--
* 7、返回e
* 备注:head是第一个节点
*/
public Object remove(int index) {
if (index < 0 || index >= size) {
System.out.println("没有可删除的对象");
return null;
}
LNode temp = head;
for (int i = 0; i < index; i++) {
temp = temp.next;
}
Object e;
e = temp.next.data;
temp.next = temp.next.next;
size--;
return e;
}
//删除所有值为data对象的节点
/**
* 思路:
* 1、判断链表是否为空
* 2、创建一个指针temp指向head
* 3、单独判断一下头结点,有存放data的,如果temp.data == data,那么head = head.next
* 4、while循环遍历链表(要判断next),如果temp.next.data == data,那么temp.next = temp.next.next
* 5、size--
*/
public void removeObjects(Object data) {
if (head == null) {
System.out.println("没有可删除的对象");
return;
}
LNode temp = head;
if (temp.data.equals(data) ) {
head = head.next;
size--;
}
while (temp.next != null) {
if (temp.next.data.equals(data)) {
temp.next = temp.next.next;
size--;
}
temp = temp.next;
}
}
//在index位置插入data
/**
* 思路:
* 1、判断index是否合法
* 2、创建一个指针temp指向head
* 3、for循环遍历index-1次,temp = temp.next
* 4、创建一个新的节点newNode
* 5、newNode.next = temp.next
* 6、temp.next = newNode
* 7、size++
*/
public void set(int index, Object data) {
if (index < 0 || index >= size) {
System.out.println("没有可替换的对象");
return;
}
LNode temp = head;
for (int i = 0; i < index; i++) {
temp = temp.next;
}
temp.data = data;
}
//用newObject取代所有的oldData
/**
* 思路:
* 1、判断链表是否为空
* 2、创建一个指针temp指向head
* 3、单独判断一下头结点,因为下面的循环不包括头结点的判断,如果temp.data == oldData,那么temp.data = newData
* 4、while循环遍历链表,如果temp.next.data == oldData,那么temp.next.data = newData
*/
public void replaceObjects(Object oldData, Object newData) {
if (head == null) {
System.out.println("没有可替换的对象");
return;
}
LNode temp = head;
if (temp.data.equals(oldData) ) {
temp.data = newData;
}
while (temp.next != null) {
if (temp.next.data .equals(oldData)) {
temp.next.data = newData;
}
temp = temp.next;
}
}
//得到所有匹配oldData的节点列表,然后让用户选择要替换的节点,然后替换
/**
* 思路:
* 1、判断链表是否为空
* 2、创建一个TArrayList数组对象place(来返回所有位置)
* 3、创建一个指针temp指向head
* 4、for循环遍历链表,如果temp.data == oldData,那么就把i添加到TArrayList对象中
* 5、判断一下place.size是否为0,如果为0,那么就没有可替换的对象
* 6、让用户输入要替换的对象的位置
* 7、判断一下index是否合法,如果不合法,那么就没有可替换的对象
* 8、set(index,newData)
*/
public void replaceOneObject(Object oldData,Object newData){
if(head==null){
System.out.println("没有可替换的对象");
return;
}
TArrayList place ;
place=getPlace(oldData);//调用上面的方法;
if(place.size==0){
System.out.println("没有可替换的对象");
return;
}
Scanner sc=new Scanner(System.in);
System.out.println("请输入要替换的对象的位置");
int index=sc.nextInt();
if(index<0||index>=place.size){
System.out.println("没有可替换的对象");
return;
}
set(index,newData);//调用上面的方法;
}
}