如何从链表中删除重复数据

来源:互联网 发布:ios炫字体 源码 编辑:程序博客网 时间:2024/06/05 23:48

1. 利用 Hashtable

如何从链表中删除重复数据,最容易想到的方法就是遍历链表,把遍历的值存储到一个 Hashtable 中,在遍历过程中,若当前访问的值在 Hashtable 中已经存在,则说明这个数据是重复的,因此可以删除。具体实现如下:

public static void deleteDuplecateHashtable(Node head) {        Hashtable <Integer,Integer> table = new Hashtable <Integer, Integer> ();        Node tmp = head;        Node pre = null;        while(tmp != null) {            if(table.containsKey(tmp.data))                pre.next = tmp.next;            else {                table.put(tmp.data, 1);                pre = tmp;            }            tmp = tmp.next;        }    }

该方法的优点是:时间复杂度低;
缺点是:在遍历过程中需要额外的存储空间来保存已遍历过的值。

2. 双重循环遍历链表

这种方法的主要思路为对链表进行双重循环遍历,外循环正常遍历链表,假设外循环当前遍历的结点为 cur,内循环在遍历过程中会删除掉与 cur 结点值相同的所有结点。在实现时可以采用不同的方法。

2.1 方法一

这种方法的的思路为:
外循环正常遍历链表,假设外循环当前遍历的结点为 cur,内循环从 cur 开始遍历,若碰到与 cur 所指结点值相同,则删除这个重复结点。具体实现如下:

public static void deleteDuplecateFromCur(Node head) {        Node p = head;        while(p != null) {            Node q = p;            while(q.next != null) {                if(p.data == q.next.data) {                    q.next = q.next.next;                }else                    q = q.next;            }            p = p.next;        }    }

2.2 方法二:

这种方法的的思路为:
外循环正常遍历链表,假设外循环当前遍历的结点为 cur,内循环链表头开始遍历至 cur,只要碰到与 cur 值相同的结点就删除该结点,同时内层循环结束。因为与 cur相同的结点只可能存在一个(如果存在多个,在前面遍历过程中已经被删除了)。采用这种方法在特定的数据发布的情况下会提高算法的时间复杂度。具体实现如下:

public class DeleteDuplecate {    public static Node deleteDuplecateFromHead(Node head) {        Node p = head;        Node preNode = null;        while(p != null) {            Node q = head;            while(q != p) {                if(p.data == q.data) {                    if(q == head) {                        head = head.next;                    }else {                        preNode.next = q.next;                    }                    break;                }else {                    preNode = q;                    q = q.next;                }            }            p = p.next;        }        return head;    }}

注意:这种方法头结点会改变。

这两种方法的优点是:不需要额外的存储空间;
缺点:时间复杂度较高。

0 0
原创粉丝点击