• 链表


    /**
     * 链表的结点
     *
     */
    class Node{
        Object data;   //数据元素
        Node next;     //后驱结点
        public Node() {
            this(null);
        }
        public Node(Object data) {
            this.data = data;
            this.next = null;
        }
    }
    /**
     * 带头结点的链式链表,下标从0开始; 
     *
     */
    public class SinglyLinkedList<E>{
        Node head; //头结点
        int size;  //链表的大小
        public SinglyLinkedList() {
            head = new Node();
            size = 0;
        }
        public SinglyLinkedList(E[] datas) {
            int n = datas.length;
            head = new Node();
            Node p = head;
            for(int i=0; i<n; i++) {
                p.next = new Node(datas[i]);
                p = p.next;
            }
            size = n;
        }
        public SinglyLinkedList(SinglyLinkedList list) {
            head = list.head;
            size = list.size();
        }
        public void add(Object e) {
            Node p;
            if(0 == size) {
                p = head;
            } else {
                p = index(size-1);
            }
            p.next = new Node(e);
            size ++;
        }
         
        public void concat(SinglyLinkedList list) {
            Node lastNode = this.index(size - 1);
            lastNode.next = list.index(0);
            size += list.size();
        }
     
        public void clear() {
            head.next = null;
            size = 0;
        }
     
        public Object get(int i) {
            Node p = index(i);
            return p.data;
        }
         
        private Node index(int i) {
            Node p = null;
            if(i>=0 && i<size){
                p = head;
                for(int j=0; j<=i; j++) {
                    p = p.next;
                }
            } 
            return p;
        }
     
        public int indexOf(Object e) {
            Node p = head.next;
            int i = 0;
            while(!p.data.equals(e)) {
                p = p.next;
                i++;
            }
            if(i<size)
                return i;
            else 
                return -1;
        }
     
        public void insert(int i, Object e) {
            Node p = index(i);
            Node p2 = new Node(e);
            p2.next = p.next;
            p.next = p2;
            size ++;
        }
     
        public boolean isEmpty() {
            if(size ==0)
                return true;
            else
                return false;
        }
     
        public int lastIndexOf(Object e) {
            int i = size-1;
            while(!get(i).equals(e)) {
                i--;
            }
            if(i>=0)
                return i;
            else 
                return -1;
        }
     
        public void remove(int i) {
            if(i>=0 && i<size) {
                Node p = null;
                if(i == 0)
                    p = head;
                else {
                    p = index(i-1);
                }
                p.next = index(i).next;
            }
            size --;
        }
     
        public void set(int i, Object e) {
            Node p = index(i);
            p.data = e;
        }
     
        public int size() {
            return size; 
        }
        @Override
        public boolean equals(Object obj) {
            SinglyLinkedList list = (SinglyLinkedList)obj;
            if(this == obj && size == list.size) {
                return true;
            }
            return false;
        }
     /**
         * 测试线性表
         * @param args
         */
        public static void main(String args[]) {
            //List list = new LinkList();
            //List list = new DoubleLinkList();
            SinglyLinkedList list1 = new SinglyLinkedList();
            for(int i=0; i<10; i++) {
                list1.add(new Integer(i));
            }
            Integer [] a = {101, 102, 103, 104, 105, 106, 107, 108, 109, 110};
            SinglyLinkedList list = new SinglyLinkedList(a);
            list.remove(9);
            System.out.print("size:" + list.size() + "
    ");
            System.out.println("isEmpty:" + list.isEmpty());
            System.out.print("第7个位置的元素:" + list.get(7) + "
    ");
            list.concat(list1);
            for(int i=0; i<list.size(); i++) {
                System.out.print(list.get(i) + "    ");
            }
             
            list.add(21);
            list.add(22);
            list.insert(3, new Integer(5));
            System.out.print("size:" + list.size() + "
    ");
            System.out.print("第一次出现5的索引:" + list.indexOf(5) + "
    ");
            System.out.print("最后一次出现5的索引:" + list.lastIndexOf(5) + "
    ");
            list.set(0, new Integer(30));
            for(int i=0; i<list.size(); i++) {
                System.out.print(list.get(i) + "    ");
            }
             
            SinglyLinkedList list2 = list;
            System.out.println("
     is equels?  " + list2.equals(list));
    
        /**
         * 有序插入
         * @param value 要插入的值
         */
        public void insertByOrder(TestList list,int value) {
            int j=0;
            //查询要插入的位置索引
            if(value<=list.get(0)){
                //insert方法是在索引后插入,不适合插入在第一位的
                Node p = new Node(value);//新建
                Node p1 = index(0);
                //拼接
                p.next = p1;
                list.head.next=p;
                size ++;
            }else if(value>=list.get(list.size-1)){
                j=list.size-1;
            }else{
                for(int i=0;i<list.size;i++){
                    while(list.get(i)<=value&&list.get(i+1)>=value){
                        j=i;
                        break;
                    }
                }
            }
            if(j!=0){
                insert(j, value);
            }
        }
        }
    }

     带头结点链表的好处

    1、防止单链表是空的而设的.当链表为空的时候,带头结点的头指针就指向头结点.如果当链表为空的时候,单链表没有带头结点,那么它的头指针就为NULL.
    2、是为了方便单链表的特殊操作,插入在表头或者删除第一个结点.这样就保持了单链表操作的统一性!
    3、单链表加上头结点之后,无论单链表是否为空,头指针始终指向头结点,因此空表和非空表的处理也统一了,方便了单链表的操作,也减少了程序的复杂性和出现bug的机会。
    4、对单链表的多数操作应明确对哪个结点以及该结点的前驱。不带头结点的链表对首元结点、中间结点分别处理等;而带头结点的链表因为有头结点,首元结点、中间结点的操作相同 ,从而减少分支,使算法变得简单 ,流程清晰。对单链表进行插入、删除操作时,如果在首元结点之前插入或删除的是首元结点,不带头结点的单链表需改变头指针的值,在C 算法的函数形参表中头指针一般使用指针的指针(在C+ +中使用引用 &);而带头结点的单链表不需改变头指针的值,函数参数表中头结点使用指针变量即可。
  • 相关阅读:
    vue 如何在循环中 "监听" 的绑定v-model数据
    验证正则表达式,同时验证手机号码和固定电话号码
    vue 图片上传功能
    localStorage使用总结
    vue2.0 父子组件通信 兄弟组件通信
    SVN使用教程总结
    详解SVN 的使用
    彻底理解setTimeout()
    如何实现一个HTTP请求库——axios源码阅读与分析 JavaScript
    2、Zookeeper原理及应用汇总
  • 原文地址:https://www.cnblogs.com/itliucheng/p/5433386.html
Copyright © 2020-2023  润新知