单链表的各种操作

Node类

package com.siglelikedlist.test;

public class Node {
    
    private int id;    //编号
    private String name;    //姓名
    Node next;            //指向下一个节点
    
    public Node(int id,String name){
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "id = " + this.getId() + "\t"
                + "name = " + this.getName() + "\n";
    }

    
}


Sigle类

package com.siglelikedlist.test;

import java.util.Stack;

/**
 * 1.求单链表中有效节点的个数
2.查找单链表中的倒数第k个结点
3.单链表反转
4.从尾到头打印单链表
5.合并两个有序的单链表,合并之后的链表依然有序
 *
 */
public class Sigle {
    
    private int size = 0;     //单链表中节点的个数
    private Node head = new Node(0, "");       //头结点
    
    /*
     * 单链表中结点个数
     */
    public int getSize(){
        return size;
    }
    
    /*
     * 判断结点编号是否存在
     */
    private boolean ifNodeNumberExists(Node node){
        Node tmp_index = head.next;
        for (int i = 1; i <= size; i++) {
            if(node.getId() == tmp_index.getId()){
                System.out.println("结点编号已存在!!!");
                return true;
            }
            tmp_index = tmp_index.next;
        }
        return false;
    }
    
    /*
     *取头结点
     */
    public Node getHead(){
        return head;
    }
    
    /*
     * 单链表中加入结点
     * 从头部加入
     */
    public void  add(Node node){
        //判断是否加入的结点的编号是否已存在
        if(ifNodeNumberExists(node)){
            return;
        }
        
        //头结点第一加入结点
        Node tmp = null;
        if(head.next == null){
            head.next = node;
            node.next = null;
        }else {    
            tmp = head.next;
            head.next = node;
            node.next = tmp;
        }
        size++;    
    }
    
    /*
     * 从尾部加入
     */
    public void add2(Node node){
        //判断是否加入的结点的编号是否已存在
        if(ifNodeNumberExists(node)){
            return;
        }
        
        Node tmp = head;
        while (true) {
            if(tmp.next == null){
                break;
            }
            tmp = tmp.next;
        }
        
        tmp.next = node;
        size++;
    }
    
    /*
     * 指定位置插入结点
     */
    public void add3(int index,Node node){
        //判断是否加入的结点的编号是否已存在
        if(ifNodeNumberExists(node)){
            return;
        }
        
        if(index < 1 || index > size + 1){
            System.out.println("插入位置不正确!!!");
            return;
        }
        
        Node tmp = head;   
            //单链表中的第一个结点不是头结点
            for (int i = 1; i < index; i++) {
                tmp = tmp.next;
            }
            node.next = tmp.next;
            tmp.next = node;
            size++;
    }
    
    /*
     * 指定位置删除结点
     */
    public void delIndexNode(int index){
        if(index < 1 || index > size){
            System.out.println("指定删除结点的位置不存在!!!");
            return;
        }
        
        Node tmp = head;
        for (int i = 1; i < index; i++) {
            tmp = tmp.next;
        }
        tmp.next = tmp.next.next;
        size--;
    }
    
    /*
     * 指定编号进行删除
     */
    public void delIdNode(int id){
        Node tmp_id = head.next;
        Node tmp = head;
        
        for (int i = 1; i <= size; i++) {
            if(id == tmp_id.getId()){
                System.out.println("结点删除成功!!!");
                tmp.next = tmp_id.next;
                size--;
                break;
            }else {
                tmp_id = tmp_id.next;
                tmp = tmp.next;
            }
        }
    }
    
    /*
     * 查找单链表中的倒数第k个结点
     * 倒数k个结点就是顺size - k + 1个结点
     */
    public Node inquireNode(int k){
        Node tmp = head;
        if(k < 1 || k > size){
            System.out.println("输入有误!!!");
            return null;
        }else{
            for (int i = 1; i <= size - k + 1; i++) {
                tmp = tmp.next;
            }
            return tmp;
        }    
    }
    
    /*
     * 单链表反转
     */
    public void reverseLike(){
        if(head.next == null || head.next.next == null){
            System.out.println("链表无法反转!!!");
            return;
        }
        
        Node cur = head.next;    //表示当前(原链表)的结点
        Node next = null;        //表示当前结点的下一个结点
        Node tmp_head = new Node(0,"");   //设置一个头结点
        
        while (cur != null) {
            next = cur.next;
            cur.next = tmp_head.next;
            tmp_head.next = cur;
            cur = next;
        }
        head = tmp_head;
    }
    
    /*
     * 从尾到头打印单链表
     * 使用栈---先进后出
     */
    public void reversePrint(){
        if(head.next == null){
            System.out.println("空链表!!!");
            return;
        }
        
        Node tmp = head;
        Stack<Node> stack = new Stack<>();   //stack继承了vector
        for (int i = 1; i <= size; i++) {
            tmp = tmp.next;
            stack.push(tmp);
        }
        
        while (stack.size() > 0) {
            System.out.println(stack.pop().toString());        
        }
    }
    
    /*
     * 单链表有序
     */
    private void  orderlyNode(){
        Node newHead = head.next;
        for(int i = 0; i< size - 1; i++){
            //前一个元素指针
            Node preNode  = null;
            
            //当前处理的元素
            Node curNode = newHead;

            for(int j = 0; j < size - i - 1;j++){
                if(curNode.getId() > curNode.next.getId()){
                    //交换两个结点的引用,此时curNode的指针交换后会前移,只需要更新preNode指向即可
                    //缓存下下个结点
                    Node tmpNode = curNode.next.next;
                    curNode.next.next = curNode;
                
                    //前驱结点指向nextNode
                    if(preNode != null){
                        preNode.next = curNode.next;
                    }else{
                        //没有前驱结点证明结点为头结点,更新头结点
                        newHead = curNode.next;
                    }

                    //因为需要把preNode指向原来的下个结点,所以此处复制preNode,preNode后移
                    preNode = curNode.next;

                    //curNode指向下下个结点
                    curNode.next = tmpNode;

                //更新preNode & curNode指针
                }else{
                    preNode = curNode;
                    curNode = curNode.next;
                }
            }
        }    
         head.next = newHead;
    }
    
    /*
     * 两个有序单链表合并,并且有序
     */
    public static void combinNodeToNode(Sigle srcSigleLink,Sigle desSigleLink){
        Node srcHeadNode = srcSigleLink.getHead();
        Node desHeadNode = desSigleLink.getHead();
        
        for (int i = 1; i <= srcSigleLink.getSize(); i++) {
            srcHeadNode = srcHeadNode.next;
        }
        srcHeadNode.next = desHeadNode.next;

        //排序
        srcSigleLink.size = srcSigleLink.getSize() + desSigleLink.getSize();
        srcSigleLink.orderlyNode();
    }
    
    /*
     * 输出
     */
    public void print(){
        Node tmp = head;
        for (int i = 1; i <= size; i++) {
            tmp = tmp.next;
            System.out.println(tmp.toString());
            
        }
    }    
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值