[从头学数学] 第262节 Python实现数据结构:双向链表

剧情提要:
阿伟看到了一本比较有趣的书,是关于《计算几何》的,2008年由北清派出版。很好奇
它里面讲了些什么,就来看看啦。


正剧开始:
星历2016年09月17日 12:07:43, 银河系厄尔斯星球中华帝国江南行省。

[工程师阿伟]正在和[机器小伟]一起研究[计算几何]]。


[从头学数学] 第262节 Python实现数据结构:双向链表_第1张图片


[从头学数学] 第262节 Python实现数据结构:双向链表_第2张图片


#
###
# @usage   双向链表
# @author  mw
# @date    2016年07月25日  星期一  09:41:23 
# @param
# @return
#
###
class DoubleLinkedList:
    def info(self):
        s = '[';
        for x in self:
            s+=str(x)+', ';
        
        s = s[:-2]+']' if len(s) > 2 else s + ']';
        print(s);

    def __len__(self):
        return self.numItems;
        
    def __iter__(self):
        cursor = self.first.getNext();
        for i in range(self.numItems):            
            yield cursor.getItem();
            cursor = cursor.getNext();    

        
    # This class is used internally by the DoubleLinkedList class. It is
    # invisible from outside this class due to the two underscores
    # that precede the class name. Python mangles names so that they
    # are not recognizable outside the class when two underscores
    # precede a name but aren’t followed by two underscores at the
    # end of the name (i.e. an operator name).
    class __Node:
        def __init__(self,item,prev=None, next=None):
            self.item = item;
            self.prev = prev;
            self.next = next;
        def getItem(self):
            return self.item
        def getPrev(self):            
            return self.prev;
        def getNext(self):
            return self.next
        def setItem(self, item):
            self.item = item
        def setPrev(self, prev):
            self.prev = prev;
        def setNext(self,next):
            self.next = next

        def __str__(self):
            return str(self.item);

        def __repr__(self):
            return '__Node('+str(self.item)+', '+str(self.prev)+', '+str(self.next)+')';
    
    def __init__(self,contents=[]):
        # Here we keep a reference to the first node in the linked list
        # and the last item in the linked list. They both point to a
        # dummy node to begin with. This dummy node will always be in
        # the first position in the list and will never contain an item.
        # Its purpose is to eliminate special cases in the code below.
        self.first = DoubleLinkedList.__Node(None,None, None)
        self.last = DoubleLinkedList.__Node(None,None, None)
        self.first.next = self.last;
        self.last.prev = self.first;
        self.numItems = 0
        
        for e in contents:
            self.append(e)

    def __getitem__(self,index):
        if index >= 0 and index < self.numItems:
            cursor = self.first.getNext()
            for i in range(index):
                cursor = cursor.getNext()
            return cursor.getItem()
        raise IndexError("DoubleLinkedList index out of range")

    def __setitem__(self,index,val):
        if index >= 0 and index < self.numItems:
            cursor = self.first.getNext()
            for i in range(index):
                cursor = cursor.getNext()
            cursor.setItem(val)
            return
        raise IndexError("DoubleLinkedList assignment index out of range")

    def __add__(self,other):
        if type(self) != type(other):
            raise TypeError("Concatenate undefined for " + \
                            str(type(self)) + " + " + str(type(other)))
        result = DoubleLinkedList()
        cursor = self.first.getNext()
        while cursor != None:
            result.append(cursor.getItem())
            cursor = cursor.getNext()
            
        cursor = other.first.getNext()
        while cursor != None:
            result.append(cursor.getItem())
            cursor = cursor.getNext()
        return result

    def append(self,item):
        node = DoubleLinkedList.__Node(item)

        tail = self.last.prev;
        tail.next = node;
        node.prev = tail;
        self.last.prev = node;
        node.next = self.last;        
        self.numItems += 1;
        
        return node;

    def insert(self,index,item):
        cursor = self.first
        index = index if index >= 0 else len(self) + index+1;
        
        if index < self.numItems:
            for i in range(index+1):
                cursor = cursor.getNext()
            node = DoubleLinkedList.__Node(item)

            if (cursor == self.first):
                prev = self.last;   
            else:
                prev = cursor.prev;
            prev.next = node;
            node.prev = prev;
            node.next = cursor;
            cursor.prev = node;

            if (cursor == self.first):
                self.first = node;   
            
            self.numItems += 1
        else:
            self.append(item)

    #获取结点
    def get(self, index):
        length = len(self);

        index = index if index >= 0 else length + index;
        if index >= length or index < 0:
            return None
        node = self.first.next
        while index > 0:
            node = node.next
            index -= 1
        return node

    def getPrev(self, node):
        if node == self.first.next:
            return self.last.prev;
        else:
            return node.prev;

    def getNext(self, node):
        if node == self.last.prev:
            return self.first.next;
        else:
            return node.next;

    def __delitem__(self, index):
        node = self.get(index);
        if node != None:
            node.prev.next = node.next;
            node.next.prev = node.prev;
            self.numItems -= 1

        return;

    def delete(self, index):
        del self[index];

    """反转链表"""
    def __reversed__(self):
        """
        1.node.next --> node.pre
          node.pre --> node.next
        2.head.next --> None
          tail.pre --> None
        3.head-->tail
         tail-->head
        :return:
        """
        pre_head = self.first
        tail = self.last

        def reverse(pre_node, node):
            if node:
                next_node = node.next
                node.next = pre_node
                pre_node.prev = node
                if pre_node is self.first:
                    pre_node.next = None
                if node is self.last:
                    node.prev = None
                return reverse(node, next_node)
            else:
                self.first = tail
                self.last = pre_head

        return reverse(self.first, self.first.next)

    """清空链表"""
    def clear(self):
        self.first.next = self.last
        self.last.prev = self.first
        self.numItems = 0;

    def __eq__(self,other):  
        if type(other) != type(self):  
            return False  
  
        if self.numItems != other.numItems:  
            return False  

        cursor1 = self.first;
        cursor2 = other.first;
        
        for i in range(self.numItems):             
            if cursor1.getItem() != cursor2.getItem():  
                return False

            cursor1 = cursor1.getNext();
            cursor2 = cursor2.getNext();
  
        return True 

    def __contains__(self,item):
        cursor = self.first;
        for i in range(self.numItems):  
            if cursor.getItem() == item:  
                return True

            cursor = cursor.getNext();
  
        return False

    def find(self, item, start = 0):
        cursor = self.first;
        for i in range(self.numItems):
            cursor = cursor.getNext();
            if (i >= start):
                if cursor.getItem() == item:  
                    return i;
  
        return -1;
        
    def __str__(self):
        s = '[';
        for x in self:
            s+=repr(x)+', ';

        s = s[:-2]+']';

        return s;

    def __repr__(self):
        s ='DoubleLinkedList([';

        for x in self:
            s+=repr(x)+', ';

        s = s[:-2]+'])';

        return s;

#

用例:

#
>>> 
0
[]
---
10
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
---
14
[22, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 15, 17, 30]
---
12
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 17, 30]
---
-1
True
__Node(0, None, 1)
__Node(1, 0, 2)
__Node(2, 1, 3)
__Node(3, 2, 4)
__Node(4, 3, 5)
__Node(5, 4, 6)
__Node(6, 5, 7)
__Node(7, 6, 8)
__Node(8, 7, 9)
__Node(9, 8, 17)
__Node(17, 9, 30)
__Node(30, 17, None)
---
__Node(None, None, 0)
__Node(None, 30, None)
---
[30, 17, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 17, 30]
11
[0, 1, 3, 4, 5, 6, 7, 8, 9, 17, 30]
0
[]
---

def test1():
    d = DoubleLinkedList();
    print(len(d));
    d.info();
    print('---');

    for i in range(10):
        d.append(i);

    print(len(d));
    d.info();
    print('---');

    d.insert(0, 22);
    d.insert(-1, 15);
    d.append(30);
    d.insert(-2, 17);
    print(len(d));
    d.info();
    print('---');

    #删除,参数是第几个元素
    d.delete(0);
    d.delete(-3);
    print(len(d));
    d.info();
    print('---');

    print(d.find(15));
    print(17 in d);

    for i in range(len(d)):
        print(repr(d.get(i)));
    print('---');
    
    print(repr(d.first));
    print(repr(d.last));
    print('---');

    reversed(d);
    print(d);
    reversed(d);
    print(d);

    del d[2];
    print(len(d));
    d.info();
    d.clear();
    print(len(d));
    d.info();
    print('---');

#

参见:http://blog.csdn.net/qq490691606/article/details/49948263


本节到此结束,欲知后事如何,请看下回分解。

你可能感兴趣的:(从头学数学,从头学数学)