数据结构(三)--链表
数据结构(三)–链表
介绍
链表又分:
- 单链表
- 双链表
单链表
- 头节点不存储数据,所有操作临时引用指向head;
- 删除/插入节点:先判断当前节点是否满足删除或插入条件,然后判断是否可以移动,最后移动(反复)
- 遍历节点:判断是否可以移动,移动,打印
- 打印某一节点:判断是否可以移动,移动,判断当前节点是否可以打印(反复)
代码实现
先实现节点
根据需要可以将数据域data的类型改为泛型**< T >**
public class NodeT<T>{
private T data;
private Node next;
public NodeT(){}
public NodeT(T data,Node next){
this.data = data;
this.next = next;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
@Override
public String toString() {
return "NodeT{" +
"data='" + data + '\''+"}";
}
}
实现单链表
public class LinelistT<T> {
private NodeT head ;
public LinelistT(){
head = new NodeT<T>(null,null);
}
//打印所有节点
public void printNodes(){
NodeT tepm = head;
while (true){
if (tepm.getNext()==null) break;
tepm = tepm.getNext();
System.out.println(tepm);
}
}
//尾部添加数据
public void addNode(T data){
NodeT<T> node = new NodeT<T>(data,null);
NodeT<T> temp = head;
while (true){
if (temp.getNext()==null){
temp.setNext(node);
break;
}
temp = temp.getNext();
}
}
//插入数据
public void insertNode(int index,T data){
//判断越界
if (index<=0) throw new RuntimeException("越界");
NodeT<T> node = new NodeT<T>(data,null);
NodeT temp = head;
int i=0;
while (true){
//添加节点
if (i==index-1){
node.setNext(temp.getNext());
temp.setNext(node);
break;
}
//判断越界
if (temp.getNext()==null) throw new RuntimeException("越界!!!");
//移动
temp = temp.getNext();
i++;
}
}
//删除节点
public NodeT deleteNode(int index) {
//判断越界
if (index <=0 )
new RuntimeException("越界!!!");
NodeT temp = head;
int i = 0;
while (true) {
//删除节点
if (i == index - 1 && temp.getNext() != null) {
NodeT temp2 = temp.getNext();
temp.setNext(temp2.getNext());
temp2.setNext(null);
return temp2;
}
//判断越界
if (temp.getNext()==null)
throw new RuntimeException("越界!!!");
//移动
temp = temp.getNext();
i++;
}
}
//打印某一节点
public void printNode(int index){
//判断越界
if (index<=0) new RuntimeException("越界!!!");
NodeT temp = head;
int i=0;
while (true){
//判断越界
if (temp.getNext()==null) {
new RuntimeException("越界!!!");
}
//移动
i++;
temp = temp.getNext();
//打印
if (i==index){
System.out.println(temp);
break;
}
}
}
}
主函数
public static void main(String[] args) {
LinelistT<String> line = new LinelistT<String>();
line.addNode("节点一");
line.addNode("节点二");
line.addNode("节点三");
line.printNodes();
System.out.println("-----------------------------");
line.deleteNode(2);
line.printNodes();
System.out.println("-----------------------------");
line.insertNode(2,"插入节点");
line.printNodes();
System.out.println("-----------------------------");
}
结果
NodeT{data='节点一'}
NodeT{data='节点二'}
NodeT{data='节点三'}
-----------------------------
NodeT{data='节点一'}
NodeT{data='节点三'}
-----------------------------
NodeT{data='节点一'}
NodeT{data='插入节点'}
NodeT{data='节点三'}
-----------------------------
翻转链表
在单链表中添加以下方法即可,思路如下:
- 创建一个新的临时链表reverseHead
- 取出原链表的第一个有效节点
- 将原链表的第一个有效节点插入到临时链表的第一个有效位置(head后面)
- 将原链表Heda的next指向reverseHead的next即可
public void reverse(){
//创建新链表
LinelistT reverseHead = new LinelistT<T>();
NodeT temp = head;
while (true){
try {
NodeT node = this.deleteNode(1);
reverseHead.insertNode(1,node.getData());
}catch (RuntimeException e) {
break;
}
}
head.setNext(reverseHead.head.getNext());
}
取出倒数第n个有效节点
获取有效节点个数
先写一个统计有效节点个数的函数,当然如果你想优化的话,完全可以在链表类中添加一个私有属性Num,用来记录个数,因为这里没写,所以就多写一个函数去遍历。
public int getNodeNum(){
NodeT temp = head;
int num = 0;
while (true){
//判断是否到尾部
if (temp.getNext() == null) return num;
temp = temp.getNext();
num++;
}
}
获取倒数有效节点
public NodeT<T> getNodeByreverse(int reverseIndex){
int num = this.getNodeNum();
if (reverseIndex>num || reverseIndex<=0)
throw new RuntimeException("越界");
NodeT<T> temp = head;
int i = 0;
while (true){
if (i==num-reverseIndex+1) break;
temp = temp.getNext();
i++;
}
return temp;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)