JAVA单循环链表和双循环链表简单操作

1、删除单循环链表某结点的直接前驱点

问题描述:假设在长度大于 1 的单循环链表中,既无头结点也无头指针。s 为指向某 个结点的指针,试编写算法删除结点*s 的直接前驱结点。

这里考虑的是:既然是删除某个节点的直接前驱,举个例子:假设现在我们有编号为 1 2 3 4 5 的5 个结点,现在我们要删除结点3的直接前驱结点,也就是2,那么只需要让结点 1 的next指向3就可以了,直接越过2,这样就实现了。
不过这里有一个问题,就是如果说输入 2,那么我们要删除1,也就是让5的next指向2,这时候会出错,我们需要加一个判定为表尾时的特殊情况

如果当前节点的下一个结点的下一个结点是我们输入的结点,那么就让当前结点的next指向下一个结点的下一个结点(这里要考虑一下当前结点是不是表尾的结点)

public void Delete(char e ){//删除某结点直接前驱结点的方法
    Node_lp current=this.header;
   // Node_lp p=this.header;
    for (int i = 0; i < size; i++) {//   O(n)    
        if (current.next.next.getData()==e) {//如果当前节点的下一个结点的下一个结点是我们输入的结点
            if(tail.equals(current)){//如果当前结点是尾结点,那么让当前结点的指向下一个结点的下一个结点
                current.setNext(current.next.next);
                header=current.next;//然后此时需要修改header为当前结点的下一个结点,否则header仍然是原来的头节点
                size--;
                break;
            }
            current.setNext(current.next.next);//非特殊情况,同上

            size--;
            break;
        }
        current = current.next;
    }
    System.out.println("删除后的链表:"+this);
}

2、三个循环链表储存一个循环链表的不同类字符

问题描述:已知由单链表表示的线性表中,含有三类字符的数据元素(如:字母、 数字和其它字符),设计算法构造三个以循环链表示的线性表,使每一个表中只 含同一类的字符,且利用原表中的结点空间作为这三个表的空间。(头结点可以 另辟空间)
(实际上这里我偷懒了,没用原空间)
(实际上这里我偷懒了,没用原空间)
(实际上这里我偷懒了,没用原空间)

public void divi_3(){
    Node current=header;
    Loop_list a1=new Loop_list();
    Loop_list a2=new Loop_list();
    Loop_list a3=new Loop_list();

    while(current!=null){//O(n)
        if((current.getData()>='A' && current.getData()<='Z')||(current.getData()>='a' && current.getData()<='z')){
            a1.add(current.data);
        }
       else if(current.getData()>='0' && current.getData()<='9'){
           a2.add(current.data);
        }
        else{
            a3.add(current.data);
        }
        current=current.next;
    }
    System.out.println("字母:"+a1);
    System.out.println("数字:"+a2);
    System.out.println("符号:"+a3);
}

3、有一双链表,每个结点中除有 prior、data 和 next 域外,还有一访问频度 域freq,在链表被启用前,其值均初始化为零。每当在链表上进行一次LOCATE(L,x) 运算,元素值为 x 的结点中 freq 域的值增 1,并使此链表中结点保持按 freq 递减 的顺序排列,以便使频繁访问的结点总是靠近表头。设计满足上述要求的LOCATE 算法。(问题描述是c/c++版的,使用JAVA写这段代码的时候是不需要传递LOCATE里面的L的,因为此时L是链表本身,L实际上就是this)

//这个链表在建立的时候是有头结点的,头节点里什么都没有存
public void LOCATE(char x){//O(n+m)
   Node current=header.next;//操作的开始先略过空的头结点
   int k;
while (current!=null&&current.data!=x)//找到这个输入的x之前一直往下走
{
    current=current.next;
}
    Node tem=header.next;//让临时结点为第一个保存数据的结点
    current.freq++;//当前结点值域+1
    while(tem.freq>=current.freq){//让临时结点从头开始找,找到值域大于等于当前结点的那个结点
        tem=tem.next;//让它向下走=移动一个
    }
    current.prior.next=current.next;//先将当前结点的前一个结点的next指向当前结点的后一个结点
    current.next.prior=current.prior;//再将当前结点的后一个结点的prior指向当前节点的前一个结点
    				    //此时当前结点只有piror和next连接它的前一个结点和后一个结点了
    				    //但是它的前一个结点和后一个结点都不指向它了,我们可以认为已经把它从链表上“卸”下来了
    				    
    current.prior=tem.prior;//此时再将当前结点的prior指向临时结点的前一个结点
    current.next=tem;//再让当前结点的next指向临时结点
    tem.prior.next=current;//然后让临时结点前一个结点的next指向当前结点,
    tem.prior=current;//再把临时结点的prior指向当前结点,这样就把current又挂到链表上了

}

我们可以参考下面的图,可以以结点3为例画一下图(图中的结点1是不保存数据的,实际上未参与操作)

想看完整代码可以私信我(虽然写得很辣鸡)(我的图好像挂了 发不上来 有点可惜)
在这里插入图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值