算法通关村第一关|双链表操作

双向链表是如何构造的,元素的插入和删除是如何实现的?

1.双向链表的构造

在这里插入图片描述

2.双向链表元素插入

流程图

在这里插入图片描述

3.C语言实现

//头部插入
void insertFirst(int data) {
    DoubleNode* newDoubleNode = (DoubleNode*)malloc(sizeof(DoubleNode));
    newDoubleNode->data = data;
    if (first == NULL) {
        last = newDoubleNode;
    } else {
        newDoubleNode->prev = first;
    }
    newDoubleNode->next = first;
    first = newDoubleNode;
}

//尾部插入
void insertLast(int data) {
    DoubleNode* newDoubleNode = (DoubleNode*)malloc(sizeof(DoubleNode));
    newDoubleNode->data = data;
    if (first == NULL) {
        first = newDoubleNode;
    } else {
        newDoubleNode->prev = last;
        last->next = newDoubleNode;
    }
    last = newDoubleNode;
}

void insertAfter(int key, int data)
{
    DoubleNode *newDoubleNode = (DoubleNode *)malloc(sizeof(DoubleNode));
    newDoubleNode->data = data;
    DoubleNode *current = first;
     //current为null有两种情况 一种是链表为空,一种是找不到key值
    if (current == NULL)
    {
        if (first == NULL) //1、链表为空
        {
            first = newDoubleNode; //则插入第一个结点(其实可以调用其它的Insert方法)
            last = newDoubleNode; //first和last均指向该结点(第一个结点)
        }
        else //2、找不到key值,则在链表尾部插入一个新的结点
        {
            last->next = newDoubleNode;
            newDoubleNode->prev = last;
            last = newDoubleNode;
        }
    }
    else{
        if (current == last) //第三种情况,找到了key值,分两种情况
        { //1、key值与最后结点的data相等,由于newNode将是最后一个结点,则将last指向newNode
            newDoubleNode->next = current->next;
            last = newDoubleNode;
        }
        else //2、两结点中间插入
        {
            newDoubleNode->next = current->next;
            current->next->prev = newDoubleNode;
        }
        current->next = newDoubleNode;
        newDoubleNode->prev = current;
    }
}

4.Java实现

//中间插入
    public void insertAffter(int key, int data) {
        DoubleLinkNode newNode = new DoubleLinkNode(data);
        DoubleLinkNode current = firstNode;
        while (current != null && current.getValue() != key) {
            current = current.getNextNode();
        }
        //若当前结点current为空
        if (current == null){
            if (isEmpty()){
                firstNode = newNode;
                lastNode = newNode;
            }else {
//                找不到key值,则在链表尾部插入一个新的结点
                lastNode.setNextNode(newNode);
                newNode.setPrevNode(lastNode);
                lastNode = newNode;
            }
        }else {
            //找到了key,但位置在最后一位
            if (current == lastNode){
                newNode.setNextNode(null);
                lastNode = newNode;
            }else {
                //在两个结点间插入
                newNode.setNextNode(current.getNextNode());
                current.getNextNode().setPrevNode(newNode);
            }
            current.setNextNode(newNode);
            newNode.setPrevNode(current);
        }
    }


// 测试方法
 public static void main(String[] args) {
        DoubleLinkNodeListDemo linkNodeListDemo = new DoubleLinkNodeListDemo();
        linkNodeListDemo.insertFirst(20);
        linkNodeListDemo.insertFirst(30);
        linkNodeListDemo.insertLast(10);
        linkNodeListDemo.insertAffter(30,5);
        linkNodeListDemo.displayForward();
    }

// 输出结果
List(first--->last): {30} {5} {20} {10}

5双链表元素删除

  //删除首元素
    public DoubleLinkNode deleteFirst() {
        DoubleLinkNode temp = firstNode;
        //若链表只有一个结点,删除后链表为空,将last指向null
        if (firstNode.getNextNode() == null) {
            lastNode = null;
        } else {
            //若链表有两个及以上的结点 ,因为是头部删除,则first.next将变成第一个结点,其previous将变成null
            firstNode.getNextNode().setPrevNode(null);
        }
        //将first.next赋给first
        firstNode = firstNode.getNextNode();
        //返回删除的结点
        return temp;
    }

    //从尾部删除结点
    public DoubleLinkNode deleteLast() {
        DoubleLinkNode temp = lastNode;
        //如果链表只有一个结点,则删除以后为空表,last指向null
        if (firstNode.getNextNode() == null) {
            firstNode = null;
        } else {
            //将上一个结点的next域指向null
            lastNode.getPrevNode().setNextNode(null);
        }
        //上一个结点称为最后一个结点,last指向它
        lastNode = lastNode.getPrevNode();
        //返回删除的结点
        return temp;
    }

   // 从中间删除结点
   public DoubleLinkNode deleteKey(int key){
        DoubleLinkNode current = firstNode;
        while (current != null && current.getValue() != key){
            current = current.getNextNode();
        }

        if (current == null){
            return null;
        }else {
            if (current == firstNode){
                firstNode.getNextNode().setPrevNode(null);
                firstNode = current.getNextNode();
            }else if (current == lastNode){
                lastNode.getPrevNode().setNextNode(null);
                lastNode = current.getPrevNode();
            }else {
                current.getNextNode().setPrevNode(current.getPrevNode());
                current.getPrevNode().setNextNode(current.getNextNode());
            }
        }
        return current;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值