Loading

数据结构实现之单向链表

date: 2018-11-26 15:14:54
updated: 2018-11-26 16:45:05

数据结构实现之单向链表

	/**
	 * Copyright (C), 2015-2018, XXX有限公司
	 * FileName: LinkedList
	 * Author:   猫熊小才天
	 * Date:     2018/11/26 10:43
	 * Description: 单向链表
	 * History:
	 * <author>          <time>          <version>          <desc>
	 * 作者姓名           修改时间           版本号              描述
	 */
	package main.List;
	
	/**
	 * 〈一句话功能简述〉<br> 
	 * 〈单向链表〉
	 *
	 * @author 猫熊小才天
	 * @create 2018/11/26
	 * @since 1.0.0
	 */
	public class LinkedList {

    private Node head = null;

    /***
     * data 存放数据
     * next 存放下一个结点
     */
    private class Node {
        int data; // 结点中的数据
        Node next = null; // 下一个结点的地址信息

        public Node(int data){
            this.data = data;
        }

        public Node() {
            super();
        }
    }

  	/**
     * 插入新的结点(尾插法)
     * 头插法:
     * Node newNode = new Node(d);
     * newNode.next = head;
     * head = newNode;
     * @param data
     */
    public void addNode(int data){
        Node newNode = new Node(data); // 初始化一个结点
        if(head == null){
            head = newNode;
            return;
        }else {
            Node tmp = head;
            while(tmp.next != null){
                tmp = tmp.next;
            }
            tmp.next = newNode;
        }
    }

    /**
     * 删除第index个结点
     * @param index
     * @return
     */
    public boolean deleteNodeByIndex(int index){
        /**
         * 如果输入的下标超过单向链表的范围
         */
        if(index < 1 || index > length()){
            System.out.println("输入下标不在单向链表的范围中");
            return false;
        }

        /**
         * index == 1,即删除第一个,将head往后移
         */
        if(index == 1){
            head = head.next;
            System.out.println("删除头结点成功");
            return true;
        }

        int i = 2; // 比较下标,head下标为1,所以从2开始判断
        Node preNode = head;
        Node curNode = head.next;
        while(curNode != null){
            if(index == i){
                preNode.next = curNode.next;
                System.out.println("删除第" + index + "个结点成功");
                return true;
            }
            preNode = curNode;
            curNode = curNode.next;
            ++i;
        }
        System.out.println("删除失败");
        return false;
    }

    /**
     * 返回单向链表的长度
     * @return
     */
    public int length(){
        int len = 0;
        Node tmp = head;
        while(tmp != null){
            ++len;
            tmp = tmp.next;
        }
        return len;
    }

    /**
     * 删除单向链表中数据为data的所有结点
     * @param data
     * @return
     */
    public boolean deleteNodeByData(int data){
        if(head == null){
            System.out.println("单向链表为空");
            return false;
        }
        boolean flag = false;
        int count = 0;
        // 先循环将头结点删除,直到头结点中的data≠data
        Node tmp = head;
        while(tmp != null){
            if(tmp.data == data){
                tmp = tmp.next;
                head = tmp;
                ++count;
                flag = true;
            }else {
                break;
            };
        }
        Node preNode = head;
        Node curNode = head.next;
        while(curNode != null){
            if(curNode.data == data){
                preNode.next = curNode.next;
                flag = true;
                ++count;
            }
            preNode = curNode;
            curNode = curNode.next;
        }
        if(flag == true){
            System.out.println("共删除了" + count + "个结点");
            return true;
        }else {
            System.out.println("删除失败");
            return false;
        }
    }

    /**
     * 获取所有符合data数据的结点的下标
     * @param data
     * @return
     */
    public String getDataIndex(int data){
        String indexStr = "";
        if(head == null){
            System.out.println("单向链表为空");
            return indexStr + "查无此数据";
        }
        int idx = 1;
        Node tmp = head;
        while(tmp != null){
            if(tmp.data == data){
                indexStr = indexStr + idx + ",";
            }
            ++idx;
            tmp = tmp.next;
        }
        if(indexStr.equals("")){
            indexStr = "查无此数据";
        }else {
            indexStr = "符合查询数据的结点下标是:" + indexStr.substring(0,indexStr.length() - 1);
        }
        return indexStr;
    }

    /**
     * 打印单向链表
     * 如果传过来的参数head是list.reHead即为逆向输出
     * @param head
     */
    public void printLinkedList(Node head) {
        Node tmp = head;
        while (tmp != null) {
            System.out.print(tmp.data);
            tmp = tmp.next;
            if(tmp != null){
                System.out.print(" -> ");
            }
        }
        System.out.println();
    }

    /**
     * 非递归方式反转单向链表
     */
    public void reverseList(){
        if (head == null)
            return;
        Node pre = head; // 上一结点
        Node cur = head.next; // 当前结点
        Node tmp = null; // 临时结点,用于保存当前结点的指针域(即下一结点)
        while(cur != null){ // 当前结点为null,说明位于尾结点
            tmp = cur.next;
            cur.next = pre; // 反转指针指向

            // 指针向下移动
            pre = cur;
            cur = tmp;
        }
        // 最后将原链表的头节点的指针域置为null,还回新链表的头结点,即原链表的尾结点
        head.next = null;
        reHead = pre;
    }

    /**
     * 采用递归方式逆向输出单向链表
     * @param head
     */
    public void printReverse(Node head){
        if(head != null){
            printReverse(head.next);
            System.out.println(head.data + " ");
        }
    }

    public static void main(String[] args) {
        LinkedList list = new LinkedList();
        list.addNode(5);
        list.addNode(3);
        list.addNode(1);
        list.addNode(5);
        list.addNode(2);
        list.addNode(55);
        list.addNode(36);
        list.addNode(5);

        /*System.out.println("单向链表的长度为:" + list.length());
        System.out.println("打印单向链表:");
        list.printLinkedList(list.head);*/

        /*list.deleteNodeByIndex(2);
        System.out.println("单向链表的长度为:" + list.length());
        System.out.println("打印单向链表:");
        list.printLinkedList(list.head);*/

        /*list.deleteNodeByData(5);
        System.out.println("单向链表的长度为:" + list.length());
        System.out.println("打印单向链表:");
        list.printLinkedList(list.head);*/

        /*System.out.println(list.getDataIndex(5));*/

        list.printLinkedList(list.head);
        list.reverseList();
        list.printLinkedList(list.reHead);

        // list.printReverse(list.head);
    }
	}

输出结果:

	单向链表的长度为:8
	打印单向链表:
	5 -> 3 -> 1 -> 5 -> 2 -> 55 -> 36 -> 5

	删除第2个结点成功
	单向链表的长度为:7
	打印单向链表:
	5 -> 1 -> 5 -> 2 -> 55 -> 36 -> 5

	共删除了3个结点
	单向链表的长度为:4
	打印单向链表:
	1 -> 2 -> 55 -> 36

	单向链表的长度为:8
	打印单向链表:
	5 -> 3 -> 1 -> 5 -> 2 -> 55 -> 36 -> 5
	符合查询数据的结点下标是:1,4,8

	5 -> 3 -> 1 -> 5 -> 2 -> 55 -> 36 -> 15
	15 -> 36 -> 55 -> 2 -> 5 -> 1 -> 3 -> 5

	15 36 55 2 5 1 3 5 
posted @ 2020-10-20 17:17  猫熊小才天  阅读(55)  评论(0编辑  收藏  举报