链表

一.链表由N个结点组成。结点的结构如下

1.head.val表示结点head的值,用于比较,或者重设

2.head.next表示结点head的next指针存储(连接)下一个结点的内存地址

class ListNode {
    int val;
    ListNode next;
    ListNode(int x) {
        val = x;
        next = null;
    }
}

二.改变链表结构的操作(插入、删除),需要注意空结点,防止出现越界异常。

1.在head结点后插入新结点,前提head结点不是空结点

new_node.next = head.next;(新结点的next指针记录了head结点下个结点的内存地址。)

head.next=new_node; (head结点的next指针记录了新结点的地址。)

2.删除head后一个结点,前提要head的下一个结点不是空结点。

head.next = head.next.next;(head.next.next表示head结点的next指针存储了head结点的下下一个结点的内存地址。)

三.虚拟结点

1.ListNode dummy = head;(表示将head结点的内存地址赋值给dummmy变量,引用的概念,head与dummy内存地址一样,作为虚拟结点,方便遍历结点,输出结果)

 

测试

class ListNode {
    int val;
    ListNode next;
    ListNode(int x) {
        val = x;
        next = null;
    }
}

public class Main {

    public static void main(String[] args) {
    // write your code here
        ListNode node1 = new ListNode(1);
        ListNode node2 = new ListNode(2);
        ListNode node3 = new ListNode(3);
        ListNode head = node1;

        node1.next = node2;
        node2.next = node3;

        for (ListNode node = head;node != null;node = node.next)
        {
            System.out.printf("%d",node.val);
            System.out.printf("->");
        }
        System.out.printf("\n\n");
        node1 = node2;

        for (ListNode node = head;node != null;node = node.next)
        {
            System.out.printf("%d",node.val);
            System.out.printf("->");
        }

        System.out.printf("\n\n%d",node1.next.val);

    }
}

 

2.删除链表中倒数第n个结点

//删除链表中倒数第n个结点
    static ListNode removeNthFromEnd(ListNode head, int n) {
        if (n < 0)
        {
            return null;
        }

        ListNode dummy = new ListNode(0);
        dummy.next = head;
        for (int i = 0; i < n; i++)
        {
            if (head == null)
            {
                return null;
            }
            head = head.next;
        }

        ListNode preDelete = dummy;
        while (head != null)
        {
            head = head.next;
            preDelete = preDelete.next;
        }

        preDelete.next = preDelete.next.next;
        return dummy.next;
    }

3.将小于x的值放在x结点的左边,大于x的值放在x结点的右边。

public ListNode partition(ListNode head,int x)
    {
        if (head == null)
        {
            return null;
        }

        ListNode leftDummy = new ListNode(0);
        ListNode rightDummy = new ListNode(0);
        ListNode left = leftDummy;
        ListNode right = rightDummy;
        while (head != null)
        {
            if (head.val < x)
            {
                left.next = head;
                left = head;
            }
            else
            {
                right.next = head;
                right = head;
            }
            head = head.next;
        }
        right.next = null;
        left.next = rightDummy.next;
        return leftDummy.next;
    }

4.去除链表中重复的数

public static ListNode deleteDuplicates(ListNode head)
    {
        if (head == null || head.next == null)
        {
            return head;
        }

        ListNode dummy = new ListNode(0);
        dummy.next = head;
        //
        head = dummy;

        while (head.next != null && head.next.next != null)//要比较的2个数都存在
        {
            if (head.next.val == head.next.next.val)//相邻2数是否相等
            {
                int val = head.next.val;
                while (head.next != null && head.next.val == val)//是否存在连续相等的情况
                {
                    //删除操作
                    head.next = head.next.next;
                }
            }
            else
            {
                //移动手指
                head = head.next;
            }
        }
        return dummy.next;
    }

 5.重排链表,重排后的顺序(L1)->(Ln)->(L2)->(Ln-1)->(L3)->(Ln-2)

public static void reorderList(ListNode head)
    {
        //
        if (head == null || head.next == null)
        {
            return;
        }
        ListNode mid = findMiddle(head);
        ListNode tail = reverse(mid.next);
        mid.next = null;//防止回环
        merge(mid,tail);
    }

    //找中间位置(经典)
    public static ListNode findMiddle(ListNode head)
    {
        ListNode fast = head.next;
        ListNode slow = head;
        while (fast != null && fast.next != null)
        {
            fast = fast.next.next;
            slow = slow.next;
        }
        return slow;
    }

    //1->2->3->null (null<-1<-2<-3)翻转链表(经典)
    public static ListNode reverse(ListNode head)
    {
        //
        ListNode newHead = null;
        while (head != null)
        {
            ListNode temp = head.next;
            head.next = newHead;
            newHead = head;
            head = temp;
        }
        return newHead;
    }

    //合并2链表(经典)
    public static void merge(ListNode head1,ListNode head2)
    {
        ListNode dummy = new ListNode(0);
        int index = 0;
        while (head1 != null && head2 != null)
        {
            if (index % 2 == 0)
            {
                dummy.next = head1;
                head1 = head1.next;
            }
            else
            {
                dummy.next = head2;
                head2 = head2.next;
            }
            index++;
            dummy = dummy.next;
        }
        //补刀,加入最后1个数
        if (head1 != null)
        {
            dummy.next = head1;
        }
        else
        {
            dummy.next = head2;
        }
    }

 

posted @ 2016-02-26 09:56  forrHuen  阅读(367)  评论(0编辑  收藏  举报