链表-单链表的增删操作(2)

一、添加结点到单链表的任意位置
public class MyLinkedList {
	Node head = null; // 链表头的引用

	/**
	 * 添加头结点
	 */
	public void addFirstNode(Person person){
		Node node = new Node(person);
		node.next = head;
		head = node;
	}
	
	/**
	 * 删除头结点
	 */
	public Node deleteFirstNode(){
		Node temp = head.next;
		head = head.next;
		return temp;
	}

	/**
	 * 在任意位置插入结点,在index的后面插入
	 */
	public boolean addNode(int index, Person p) {
		Node node = new Node(p);
		Node current = head;
		Node previous = head;
		int pos = 0;
		int length = length();
		
		if (index > 0 && index <= length) {
			while (pos != index) {
				previous = current;
				current = current.next;
				pos++;
			}
			node.next = current;
			previous.next = node;
			pos = 0;
		} else if (index == 0) {
			addFirstNode(p);
		} else {
			return false;
		}
		return true;
	}
}


二、从链表中删除重复数据
最容易想到的方法就是遍历链表,把遍历到的值存储到一个Hashtable中,在遍历的过程中,如果当前访问的值在Hashtable中已存在,说明是重复数据,可以删除,代码如下:
	public void deleteDuplecate(){
		Node current = head ;
		Node previous = null;
		Hashtable<Integer, Person> hashTable=new Hashtable<Integer, Person>();
		
		int pos=0;
		while(current !=null){
			pos++;
			Person person = current.data;
			if(hashTable.contains(person)){
				previous.next=current.next;
			}else{
				hashTable.put(pos, person);
				previous=current;
			}
			current=current.next;
		}
	}


以上这种方法的优点是时间复杂度较低,缺点是遍历的过程中需要额外的存储空间来保存已遍历过的值,下面介绍一种不需要额外存储空间的算法。
这种方法的主要思路是对链表进行双重循环遍历,外循环正常遍历链表,假设外循环当前遍历的结点为cur,内循环从cur开始遍历,若碰到与cur所指结点值相同,就可以删除这个重复结点。代码如下:
	public void deleteDuplecate() {
		Node current = head;
		
		while (current != null) {
			Person curPerson = current.data;
			
			Node nextNode = current.next;
			while (nextNode!= null) {
				Person nextPerson = nextNode.data;
				if (curPerson.equals(nextPerson)) {
					current.next = nextNode.next;
				} 
				nextNode = nextNode.next;
			}
			current = current.next;
		}
	}

这种方法的优点是不需要额外的存储空间,缺点是时间复杂度比第一种方法要高。

猜你喜欢

转载自margaret0071.iteye.com/blog/2353691