• 双向链表


    双向链表

    一种更复杂的链表是“双向链表”或“双面链表”。每个节点有两个链接:一个指向前一个节点,当此节点为第一个节点时,指向空值;而另一个指向下一个节点,当此节点为最后一个节点时,指向空值。

    双向链表

    操作

    • is_empty() 链表是否为空
    • length() 链表长度
    • travel() 遍历链表
    • add(item) 链表头部添加
    • append(item) 链表尾部添加
    • insert(pos, item) 指定位置添加
    • remove(item) 删除节点
    • search(item) 查找节点是否存在

    实现

    Python实现

    class Node(object):
        """双向链表节点"""
        def __init__(self, item):
            self.item = item
            self.next = None
            self.prev = None
    
    
    class DLinkList(object):
        """双向链表"""
        def __init__(self):
            self._head = None
    
        def is_empty(self):
            """判断链表是否为空"""
            return self._head == None
    
        def length(self):
            """返回链表的长度"""
            cur = self._head
            count = 0
            while cur != None:
                count += 1
                cur = cur.next
            return count
    
        def travel(self):
            """遍历链表"""
            cur = self._head
            while cur != None:
                print cur.item,
                cur = cur.next
            print ""
    
        def add(self, item):
            """头部插入元素"""
            node = Node(item)
            if self.is_empty():
                # 如果是空链表,将_head指向node
                self._head = node
            else:
                # 将node的next指向_head的头节点
                node.next = self._head
                # 将_head的头节点的prev指向node
                self._head.prev = node
                # 将_head 指向node
                self._head = node
    
        def append(self, item):
            """尾部插入元素"""
            node = Node(item)
            if self.is_empty():
                # 如果是空链表,将_head指向node
                self._head = node
            else:
                # 移动到链表尾部
                cur = self._head
                while cur.next != None:
                    cur = cur.next
                # 将尾节点cur的next指向node
                cur.next = node
                # 将node的prev指向cur
                node.prev = cur
    
    
    
        def search(self, item):
            """查找元素是否存在"""
            cur = self._head
            while cur != None:
                if cur.item == item:
                    return True
                cur = cur.next
            return False
    
    

    指定位置插入节点

    双向链表指定位置插入元素

        def insert(self, pos, item):
            """在指定位置添加节点"""
            if pos <= 0:
                self.add(item)
            elif pos > (self.length()-1):
                self.append(item)
            else:
                node = Node(item)
                cur = self._head
                count = 0
                # 移动到指定位置的前一个位置
                while count < (pos-1):
                    count += 1
                    cur = cur.next
                # 将node的prev指向cur
                node.prev = cur
                # 将node的next指向cur的下一个节点
                node.next = cur.next
                # 将cur的下一个节点的prev指向node
                cur.next.prev = node
                # 将cur的next指向node
                cur.next = node
    
    

    删除元素

    双向链表删除节点

        def remove(self, item):
            """删除元素"""
            if self.is_empty():
                return
            else:
                cur = self._head
                if cur.item == item:
                    # 如果首节点的元素即是要删除的元素
                    if cur.next == None:
                        # 如果链表只有这一个节点
                        self._head = None
                    else:
                        # 将第二个节点的prev设置为None
                        cur.next.prev = None
                        # 将_head指向第二个节点
                        self._head = cur.next
                    return
                while cur != None:
                    if cur.item == item:
                        # 将cur的前一个节点的next指向cur的后一个节点
                        cur.prev.next = cur.next
                        # 将cur的后一个节点的prev指向cur的前一个节点
                        cur.next.prev = cur.prev
                        break
                    cur = cur.next
    
    

    测试

    if __name__ == "__main__":
        ll = DLinkList()
        ll.add(1)
        ll.add(2)
        ll.append(3)
        ll.insert(2, 4)
        ll.insert(4, 5)
        ll.insert(0, 6)
        print "length:",ll.length()
        ll.travel()
        print ll.search(3)
        print ll.search(4)
        ll.remove(1)
        print "length:",ll.length()
        ll.travel()
    

    Java实现

    package linkList;
    
    /**
     * @class: linkList.DLinkList
     * @description:双向链表
     * @author: ylg
     */
    public class DLinkList {
    	Node head = null;
    
    	/**
    	 * @class: linkList.Node
    	 * @description: 节点类
    	 */
    	class Node {
    		int item;
    		Node pre;
    		Node next;
    
    		public Node(int item) {
    			this.item = item;
    		}
    	}
    
    	/**
    	 * @return 链表为空返回true,否则返回false
    	 */
    	public boolean is_empty() {
    		return head == null;
    	}
    
    	/**
    	 * @return 链表的长度
    	 */
    	public int length() {
    		Node cur = head;
    		int count = 0;
    		while (cur != null) {
    			count++;
    			cur = cur.next;
    		}
    		return count;
    	}
    
    	/**
    	 * 打印链表
    	 */
    	public void travle() {
    		Node cur = head;
    		System.out.print("[ ");
    		while (cur != null) {
    			System.out.print(cur.item + " ");
    			cur = cur.next;
    		}
    		System.out.println(" ]");
    
    	}
    
    	/**
    	 * 头部添加元素
    	 * 
    	 * @param item
    	 *            添加的元素
    	 */
    	public void add(int item) {
    		Node node = new Node(item);
    		if (is_empty()) {
    			head = node;
    		} else {
    			node.next = head;
    			head.pre = node;
    			head = node;
    		}
    	}
    
    	/**
    	 * 尾部添加元素
    	 * 
    	 * @param item
    	 *            添加的元素
    	 */
    	public void append(int item) {
    		Node node = new Node(item);
    		if (is_empty()) {
    			head = node;
    		} else {
    			Node cur = head;
    			while (cur.next != null) {
    				cur = cur.next;
    			}
    			cur.next = node;
    			node.pre = cur;
    		}
    	}
    
    	/**
    	 * 指定位置添加元素
    	 * 
    	 * @param pos
    	 *            位置
    	 * @param item
    	 *            添加的元素
    	 */
    	public void insert(int pos, int item) {
    		if (pos <= 0) {
    			add(item);
    		} else if (pos > length() - 1) {
    			append(item);
    		} else {
    			Node node = new Node(item);
    			Node cur = head;
    			int count = 0;
    			while (count < pos - 1) {
    				count++;
    				cur = cur.next;
    			}
    			node.pre = cur;
    			node.next = cur.next;
    			cur.next.pre = node;
    			cur.next = node;
    		}
    	}
    
    	/**
    	 * 删除给定的元素
    	 * 
    	 * @param item
    	 *            删除的元素
    	 */
    	public void remove(int item) {
    		if (is_empty()) {
    			return;
    		} else {
    			Node cur = head;
    			if (cur.item == item) {
    				if (cur.next == null) {
    					head = null;
    				} else {
    					cur.next.pre = null;
    					head = cur.next;
    				}
    				return;
    			}
    			while (cur.next != null) {
    				if (cur.item == item) {
    					cur.pre.next = cur.next;
    					cur.next.pre = cur.pre;
    					break;
    				}
    				cur = cur.next;
    			}
    			if (cur.item == item) {
    				cur.pre.next = null;
    			}
    		}
    	}
    
    	/**
    	 * @param item
    	 *            查找的元素
    	 * @return 查找到返回true,否则返回false
    	 */
    	public boolean search(int item) {
    		Node cur = head;
    		while (cur != null) {
    			if (cur.item == item) {
    				return true;
    			}
    			cur = cur.next;
    		}
    		return false;
    	}
    
    	public static void main(String[] args) {
    		DLinkList dlink = new DLinkList();
    		dlink.append(1);
    		dlink.append(2);
    		dlink.add(3);
    		dlink.travle();
    		dlink.insert(1, 4);
    		dlink.travle();
    		dlink.remove(2);
    		dlink.travle();
    		System.out.println(dlink.search(4));
    	}
    }
    
    
  • 相关阅读:
    iOS6和iOS7代码的适配(3)——坐标适配
    iOS6和iOS7代码的适配(2)——status bar
    iOS6和iOS7代码的适配(1)
    深入Blocks分析
    文字溢出加省略号
    点击图表每一部分触发某事件
    图表添加红线
    比较月份是否存在封装数据
    云上示范区项目总结
    页面之间通过地址栏传参
  • 原文地址:https://www.cnblogs.com/yangliguo/p/8372293.html
Copyright © 2020-2023  润新知