[笔记]python数据结构之线性表:linkedlist链表,stack栈,queue队列

python数据结构之线性表

python内置了很多高级数据结构,list,dict,tuple,string,set等,在使用的时候十分舒心。但是,如果从一个初学者的角度利用python学习数据结构时,这些高级的数据结构可能给我们以迷惑。

比如,使用list实现queue的时候,入队操作append()时间复杂度可以认为是O(1),但是,出队操作pop(0)的时间复杂度就是O(n)。

如果是想利用python学学数据结构的话,我觉得还是自己实现一遍基本的数据结构为好。

1.链表

在这里,我想使用类似于c语言链式存储的形式,借助于class,分别构成无序链表以及有序链表。

我们先看看链表节点的定义:

class ListNode(object):
    def __init__(self, data):
        self.data = data
        self.next = None

    def getData(self):
        return self.data

    def setData(self, newData):
        self.data = newData

    def getNext(self):
        return self.next

    def setNext(self, nextNode):
        self.next = nextNode

利用链表节点,组成无序链表类:

class UnorderedList(object):
    def __init__(self):
        self.head = None

    def getHead(self):
        return self.head

    def isEmpty(self):
        return self.head is None

    def add(self, item):
        node = ListNode(item)
        node.next = self.head
        self.head = node   # the head is the most recently added node

    def size(self):
        current = self.head
        count = 0
        while current is not None:
            count += 1
            current = current.getNext()

        return count

    def search(self, item):
        current = self.head
        found = False
        while current is not None and not found:
            if current.getData() == item:
                found = True
            else:
                current = current.getNext()
        return found

    def append(self, item):
        node = ListNode(item)
        if self.isEmpty():
            self.head = node
        else:
            current = self.head
            while current.getNext() is not None:
                current = current.getNext()
            current.setNext(node)

    def remove(self, item):
        current = self.head
        previous = None
        found = False
        while not found:
            if current.getData() == item:
                found = True
            else:
                previous = current
                current = current.getNext()

        if previous is None:
            self.head = current.getNext()
        else:
            previous.setNext(current.getNext())

在上面的链表中,每次添加元素都直接添加在链表头部,add()的时间复杂度为O(1),而append()操作在队尾,其时间复杂度为O(n)。有没有前后加入操作的时间复杂度都为O(1)的链表呢,当然是有的:

class UnorderedList(object):
    def __init__(self):
        self.head = None
        self.tail = None

    def getHead(self):
        return self.head

    def isEmpty(self):
        return self.head is None and self.tail is None

    def add(self, item):
        node = ListNode(item)
        if self.isEmpty():
            self.head = self.tail = node
        else:
            node.next = self.head
            self.head = node   # the head is the most recently added node

    def size(self):
        current = self.head
        count = 0
        while current is not None:
            count += 1
            current = current.getNext()

        return count

    def search(self, item):
        current = self.head
        found = False
        while current is not None and not found:
            if current.getData() == item:
                found = True
            else:
                current = current.getNext()
        return found

    def append(self, item):
        node = ListNode(item)
        self.tail.setNext(node)
        self.tail = node

    def remove(self, item):
        current = self.head
        previous = None
        found = False
        while not found:
            if current.getData() == item:
                found = True
            else:
                previous = current
                current = current.getNext()

        if current.getNext() is None:
            self.tail = previous

        if previous is None:
            self.head = current.getNext()
        else:
            previous.setNext(current.getNext())

对无序链表类加入一个属性,引用链表末尾节点,即可。做出了这样的改变,在add和remove操作也应作出相应变化。

下面再看看有序链表。有序链表在插入节点的时候便寻找适合节点的位置。

class OrderedList(object):
    def __init__(self):
        self.head = None

    def isEmpty(self):
        return self.head is None

    def search(self, item):
        stop = False
        found = False
        current = self.head
        while current is not None and not found and not stop:
            if current.getData() > item:
                stop = True
            elif current.getData() == item:
                found = True
            else:
                current = current.getNext()
        return found

    def add(self, item):
        previous = None
        current = self.head
        stop = False
        while current is not None and not stop:
            if current.getData() >item:
                stop = True
            else:
                previous = current
                current = current.getNext()
        node = ListNode(item)
        if previous is None:
            node.getNext(current)
            self.head = node
        else:
            previous.setNext(node)
            node.setNext(current)

2.栈stack

对于栈来说,python内置的列表已经可以满足栈的要求。

入栈操作为append(),出栈操作为pop()。它们的时间复杂度都为O(1).

class Stack(object):
    def __init__(self):
        self._items = []

    def is_empty(self):
        return self._items == []

    def push(self, item):
        self._items.append(item)

    def pop(self):
        return self._items.pop()

    def peek(self):
        return self._items[-1]

当然了,我们也可以自己实现链栈,跟链表的实现类似。

class StackNode(object):
    """docstring for StackNode"""
    def __init__(self, value):
        self.value = value
        self.next = None

class Stack(object):
    """docstring for Stack"""
    def __init__(self, top=None):
        self.top = top

    def get_top(self):
        return self.top

    def is_empty(self):
        return self.top is None

    def push(self, val):
        if self.is_empty():
            self.top = StackNode(val)
            return
        else:
            node = StackNode(val)
            node.next = self.top.next
            self.top = node
            return

    def pop(self):
        if self.is_empty():
            print("Stack is Empty, cannot pop anymore.\n")
            return
        node = self.top
        self.top = self.top.next
        return node

3.队列queue

队列如果利用链表实现的话会,出现文章开头提及的问题。

所以队列可以用链表实现。

class QueueNode(object):
    def __init__(self, value):
        self.value = value
        self.next = None

class Queue(object):
    def __init__(self):
        self.front = None
        self.rear = None

    def is_empty(self):
        return self.front is None and self.rear is None

    def enqueue(self, num):
        node = QueueNode(num)
        if self.is_empty():
            self.front = node
            self.rear = node
        else:
            self.rear.next = node
            self.rear = node

    def dequeue(self):
        if self.front is self.rear:
            node = self.front
            self.front = None
            self.rear = None
            return node.value
        else:
            node = self.front
            self.front = node.next
            return node.value

在python的库中,比如collections以及Queue中都有deque模块。

deque模块顾名思义,可以做双端队列。所以,deque模块也可以做队列,和栈。

dq
= deque([1,2,3,4,5,6,7,8,9])

dq.pop()
# pop 9

dq.popleft()
#pop 1

dq.apend(9)
# append 9

dq.appendleft(1)
#insert 1 in index 0

在多线程,多进程编程时,经常使用Queue模块的Queue类。

其实:假设q
= Queue.Queue() 那么 q.queue就是一个deque。

这个以后再谈。

时间: 2024-10-24 15:32:00

[笔记]python数据结构之线性表:linkedlist链表,stack栈,queue队列的相关文章

线性表 及Java实现 顺序表、链表、栈、队列

数据结构与算法是程序设计的两大基础,大型的IT企业面试时也会出数据结构和算法的题目, 它可以说明你是否有良好的逻辑思维,如果你具备良好的逻辑思维,即使技术存在某些缺陷,面试公司也会认为你很有培养价值,至少在一段时间之后,技术可以很快得到提高.同时,它也是软考的重点,我们需要对这部分的内容进行一下总结. 我们先看一下数据结构和算法的整体内容. 1.线性表 概念: 数据元素的排列方式是线性的. 分类: 分类规则是根据上图中元素的存储结构来划分的. (1)顺序表 基本思想:元素的存储空间是连续的.在内

数据结构之线性表(链表)

链表 1.链表的定义:线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是 连续的,也可以是不连续的).因此,为了表示每个数据元素ai与其直接后继数据元素ai+1之间的逻辑关系,对数据元素 ai来说,除了存储其本身的信息之外,还需存储一个指示其直接后继的信息(即直接后继的存储位置).这两部分信息组 成数据元素ai的存储映像,称为结点.它包括两个域,其中存储数据元素信息的域称为数据域:存储直接后继存储位置的 域称为指针域.指针域中存储的信息称做指针或链.n个结点

数据结构之 线性表---单链表操作A (删除链表中的指定元素)

数据结构上机测试2-1:单链表操作A Time Limit: 1000MS Memory limit: 4096K 题目描述 输入n个整数,先按照数据输入的顺序建立一个带头结点的单链表,再输入一个数据m,将单链表中的值为m的结点全部删除.分别输出建立的初始单链表和完成删除后的单链表. 输入 第一行输入数据个数n: 第二行依次输入n个整数: 第三行输入欲删除数据m. 输出 第一行输出原始单链表的长度: 第二行依次输出原始单链表的数据: 第三行输出完成删除后的单链表长度: 第四行依次输出完成删除后的

数据结构之 线性表---单链表的操作B(先逆序+再删除重复元素)

数据结构上机测试2-2:单链表操作B Time Limit: 1000MS Memory limit: 65536K 题目描述 按照数据输入的相反顺序(逆位序)建立一个单链表,并将单链表中重复的元素删除(值相同的元素只保留最后输入的一个). 输入 第一行输入元素个数n: 第二行输入n个整数. 输出 第一行输出初始链表元素个数: 第二行输出按照逆位序所建立的初始链表: 第三行输出删除重复元素后的单链表元素个数: 第四行输出删除重复元素后的单链表. 示例输入 10 21 30 14 55 32 63

数据结构之 线性表---单链表的应用(重复元素删除)

数据结构上机测试1:顺序表的应用 Time Limit: 1000MS Memory limit: 65536K 题目描述 在长度为n(n<1000)的顺序表中可能存在着一些值相同的“多余”数据元素(类型为整型),编写一个程序将“多余”的数据元素从顺序表中删除,使该表由一个“非纯表”(值相同的元素在表中可能有多个)变成一个“纯表”(值相同的元素在表中只能有一个). 输入 第一行输入表的长度n: 第二行依次输入顺序表初始存放的n个元素值. 输出 第一行输出完成多余元素删除以后顺序表的元素个数: 第

数据结构之 线性表---有序链表的建立

mxjj130304杨少鹏(13110581086)        注销 数据结构实验之链表六:有序链表的建立 数据结构实验之链表六:有序链表的建立 Time Limit: 1000MS    Memory limit: 65536K 题目描述 输入N个无序的整数,建立一个有序链表,链表中的结点按照数值非降序排列,输出该有序链表. 输入 第一行输入整数个数N: 第二行输入N个无序的整数. 输出 依次输出有序链表的结点值. 示例输入 6 33 6 22 9 44 5 示例输出 5 6 9 22 3

数据结构之 线性表---有序链表的归并

数据结构实验之链表四:有序链表的归并 Time Limit: 1000MS Memory limit: 65536K 题目描述 分别输入两个有序的整数序列(分别包含M和N个数据),建立两个有序的单链表,将这两个有序单链表合并成为一个大的有序单链表,并依次输出合并后的单链表数据. 输入 第一行输入M与N的值: 第二行依次输入M个有序的整数: 第三行依次输入N个有序的整数. 输出 输出合并后的单链表所包含的M+N个有序的整数. 示例输入 6 5 1 23 26 45 66 99 14 21 28 5

数据结构之 线性表---单链表的拆分

数据结构实验之链表五:单链表的拆分 Time Limit: 1000MS Memory limit: 65536K 题目描述 输入N个整数顺序建立一个单链表,将该单链表拆分成两个子链表,第一个子链表存放了所有的偶数,第二个子链表存放了所有的奇数.两个子链表中数据的相对次序与原链表一致. 输入 第一行输入整数N;: 第二行依次输入N个整数. 输出 第一行分别输出偶数链表与奇数链表的元素个数: 第二行依次输出偶数子链表的所有数据: 第三行依次输出奇数子链表的所有数据. 示例输入 10 1 3 22

数据结构_线性表_链表实现

之前已经完全忘了指针怎么用了.复习了一下,目前只写了一点点. #include<iostream> #include<cstdio> #include<malloc.h> using namespace std; struct Node { int e; double c; Node* next; }; struct Head { int cnt; Node* elem; }; Head* inilHead() { Head *head; head=(Head*)mal