双向链表增删改查C语言代码,实现双向链表提供增删改查

MyLinkedList.java

后期会添加更多操作

/**

* 双向链表

* 对外提供CRUD

*

* 链表索引起点:0

*/

class MyLinkedList {

private Node head;// 头结点,可变化。管理链表的核心。

private Node tail;// 尾节点的引用。

private int size;// 链表节点的个数

// 初始化

public MyLinkedList() {

head = new Node<>(null, null, null);

tail = head;

// head只有next会变

// tail只有pre会变

size = 0;

}

private boolean isNull() {

return head == tail;

}

private void checkIndex(int pos) {

if (pos >= size) {

throw new RuntimeException("查询失败,越界的pos值:" + pos);

}

}

// 遍历打印

@Override

public String toString() {

// head不打印

// if ! isNull printn(tail) else 不打印

if (isNull()) {

return "0 []";

}

StringBuilder sb = new StringBuilder(String.format("%d [", size));

for (Node it = head.next; it.next != null; it = it.next) {

sb.append(String.format("%s, ", it.data));

}

sb.append(String.format("%s]", tail.data));

return sb.toString();

}

// 尾部追加

public void append(T element) {

// 分第一次和其他次

if (tail.pre != null) {

// System.out.println("并非第一次追加");

Node node = new Node<>(tail, element, null);// 新节点指向尾节点

tail.next = node;// 尾节点指向新节点

tail = node;// 设置新的尾节点

} else {

// System.out.println("第一次追加");

Node node = new Node<>(head, element, null);// 新节点指向第一个head

head.next = node;// 设置head的下一个是node

tail = node;// 设置新的tail

}

size++;

}

// 修改

public void set(int pos, T element) {

checkIndex(pos);

Node it = head.next;// iterator

for (int i = 0; i < pos; i++) {

it = it.next;

}

it.data = element;

}

// 查询

public T get(int pos) {

checkIndex(pos);

Node it = head.next;

for (int i = 0; i < pos; i++) {

it = it.next;

}

return it.data;

}

// 插入

public void insert(int pos, T element) {

checkIndex(pos);

Node it = head.next;// iterator

for (int i = 0; i < pos; i++) {

it = it.next;

}

// it指向了要挪窝的节点

Node node = new Node<>(it.pre, element, it);// 新节点指向前后节点

it.pre.next = node;// it的前置节点的下一个节点不指it,改为指向node。

it.pre = node;// it的前置节点改为node

size++;

}

// 删除

public T delete(int pos) {

checkIndex(pos);

Node it = head.next;

for (int i = 0; i < pos; i++) {

it = it.next;

}

// it指向了要删除的节点。前后节点忽略IT。

it.pre.next = it.next;

it.next.pre = it.pre;

T tmp = it.data;

it = null;

size--;

return tmp;

}

}

测试

public static void main(String[] args) {

MyLinkedList list = new MyLinkedList<>();

System.out.println(list);

list.append(123);

System.out.println(list);

list.append(456);

System.out.println(list);

list.append(789);

list.append(1);

list.append(2);

System.out.println(list);

list.set(0, 111);// pos 属于 [0, pos]

System.out.println(list.size - 1);

list.set(list.size - 1, 666);

System.out.println(list);

list.insert(3, 999999);

System.out.println(list);

list.insert(3, 8888);

System.out.println(list);

System.out.println(list.get(0));

System.out.println(list.get(list.size - 1));

System.out.println(list);

System.out.println(list.delete(3));

System.out.println(list);

}

输出

0 []

1 [123]

2 [123, 456]

5 [123, 456, 789, 1, 2]

4

5 [111, 456, 789, 1, 666]

6 [111, 456, 789, 999999, 1, 666]

7 [111, 456, 789, 8888, 999999, 1, 666]

111

666

7 [111, 456, 789, 8888, 999999, 1, 666]

8888

6 [111, 456, 789, 999999, 1, 666]

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值