链表----链表原理

来源:互联网 发布:兄弟连高洛峰 php教程 编辑:程序博客网 时间:2024/06/06 07:20

一、简单的链表结点类

1、单链表的两个属性:

1)value:值

2)next:指向下一个结点的指针

对于双链表则多了一个属性:pre:表示指向上一个结点的指针

2、链表结点类的代码:

package com.hnust.List;/** * 链表结点类 * */public class ListNode<T> {//链表结点类    public T value;//数据域    public ListNode<T> next;//指针域,指向下一个结点    public ListNode(T value, ListNode<T> next) {//有参构造函数        super();        this.value = value;        this.next = next;    }    public ListNode() {//无参构造函数        super();    }    public ListNode<T> pre;//链表中指向前一个结点的指针(双链表)}

二、链表的增删改查、逆序打印链表(递归和非递归)以及求链表最大元素等操作

package com.hnust.List;import java.util.Comparator;import java.util.Stack;public class MiniList<T> {    private ListNode<T> head = new ListNode<T>(null, null);//头结点    /**     * 链表的最大元素     */    public Comparator<T> comp;//自定义一个比较器    public int compare(T a , T b){//比较a和b的大小        if(comp!=null){//如果自己定义的比较器不为空            return comp.compare( a, b);//调用比较器的compare方法        }else{             Comparable<T> c = (Comparable<T>) a;//把a强制转换为Comparable接口            return c.compareTo(b);        }    }    public T getMax(){        if(head.next==null){            return null;        }        ListNode<T> p = head.next;        T max = p.value;        p = p.next;        while(p!=null){            if(compare(p.value,max)>0){                max = p.value;            }            p = p.next;        }        return max;    }    // 把数组转换成链表    public void arrayToList(T[] array) {        ListNode<T> p = head;//定义p指针,指向头结点        for (T t : array) {            ListNode<T> node = new ListNode<T>(t, null);            p.next = node;            p = node;        }    }    // 链表的插入,在index位置后插入值value    public void insert(int index, T value) {        ListNode<T> p = head;//定义指针p,指向head        for (int i = 0; i <= index; i++) {//不断移动指针p,找到要在哪个结点后插入            p = p.next;        }        ListNode<T> node = new ListNode<T>(value, null);//新建要插入的结点node        //插入结点node        node.next = p.next;         p.next = node;    }    // 链表结点的删除    public void remove(int index) {        ListNode<T> p = head;//定义前驱结点,让他指向头结点        for (int i = 0; i <= index - 1; i++) {            p = p.next;//将前驱结点向后移动        }        p.next = p.next.next;    }    // 查询    public T get(int index) {        ListNode<T> p = head;        for (int i = 0; i <= index; i++) {            p = p.next;        }        System.out.println(p.value);        return p.value;    }    // 修改结点    public void set(int index, T value) {        ListNode<T> p = head;        for (int i = 0; i <= index; i++) {            p = p.next;        }        p.value = value;    }    // 逆序打印链表(非递归)    public void printInverse() {        if (head.next == null) {// 边界检查            return;        }        Stack<T> stack = new Stack();// new一个栈类的对象        ListNode<T> p = head.next;        while (p != null) {            stack.push(p.value);            p = p.next;        }        while (!stack.isEmpty()) {            System.out.print(stack.pop() + " ");        }        System.out.println();    }    // 递归实现 逆序打印链表    private void recursive(ListNode<T> p) {//对于某个结点p        if (p != null) {//如果p为非空            recursive(p.next);//递归p的下一个结点            System.out.print(p.value+" ");        }    }    public void printRecursive(){        if (head.next == null) {// 边界检查            return;        }        recursive(head.next);    }    // 打印链表    public void printList() {        ListNode<T> p = head.next;//定义p指正指向头结点的下一个元素, 因为不需要打印头结点head        while (p != null) {// 判断链表是否遍历完毕            System.out.print(p.value + " ");            p = p.next;        }        System.out.println();    }}

三、链表测试类

package com.hnust.List;/** * 链表测试类 * */import java.util.Comparator;import org.junit.Test;public class TestList {    @SuppressWarnings("unused")    @Test    public void testNode01() {        ListNode<Integer> p4 = new ListNode<Integer>(4, null);        ListNode<Integer> p3 = new ListNode<Integer>(3, p4);        ListNode<Integer> p2 = new ListNode<Integer>(2, p3);        ListNode<Integer> p1 = new ListNode<Integer>(1, p2);    }    @SuppressWarnings("unused")    @Test    public void testNode02() {        ListNode<Integer> p1 = new ListNode<Integer>(1,                new ListNode<Integer>(2, new ListNode<Integer>(3, new ListNode<Integer>(4, null))));    }    @Test    public void testMiniList() {        MiniList<Integer> list = new MiniList<Integer>();        Integer[] array = new Integer[] { 0, 1, 2, 3, 4, 5 };//新建整型数组        list.arrayToList(array);//将数组转换成链表        list.printList();//打印链表        list.insert(3, 6);        list.printList();        list.remove(3);        list.printList();        list.get(2);        list.printList();        list.set(5, 10);        list.printList();    }    @Test    public void testPrintInverse() {        MiniList<Integer> list = new MiniList<Integer>();        Integer[] array = new Integer[] { 0, 1, 2, 3, 4, 5 };        list.arrayToList(array);        list.printList();        list.printInverse();        list.printRecursive();    }    @Test    public void testMaxInteger() {        MiniList<Integer> list = new MiniList<Integer>();        Integer[] array = { 1, 43, 53, 4, 73, 10, 8, 9, 7, 22, 35 };        list.arrayToList(array);        System.out.println(list.getMax());    }    @Test    public void testMaxPerson() {        MiniList<Person> list = new MiniList<Person>();        list.comp = new Comparator<Person>() {            @Override            public int compare(Person o1, Person o2) {                // TODO Auto-generated method stub                return o1.getId() - o2.getId();            }        };        Person[] per = { new Person(1, "Wupeng"), new Person(2, "Kobe"), new Person(3, "James") };        list.arrayToList(per);        System.out.println(list.getMax());    }}
0 0