数据结构(列表,队列,栈,链表)

1.说明

1.1 概念

  简单来说,数据结构是用来设计数据以何种方式组织并存储在计算机中,像我们常见的列表,字典,元祖等都属于数据结构

1.2 分类

  按照其逻辑可以分为线性结构,树结构,图结构

  线性结构:数据结构中的元素存在一对一的相互关系,如列表

  树结构:数据结构中的元素存在一对多的相互关系

  图结构:数据结构中的元素存在多对多的相互关系

2.关于列表(数组)

  在其他语言中列表被称为数组(像c),在Python中被称为列表,这两者之间还是存在区别的:

    列表可以可以混合存储元素类型,像字符串,整数等,而数组不行,要求元素类型一致

    数组长度是固定的,而Python中长度不够会开辟新的内存地址,再把原来的内容拷过来

3.关于队列(queue)

  它属于一种数据集合,仅允许在列表的一端进行插入,另外一端进行删除

  特点:联想我们排队打饭,都是先进先出,对头出队,队尾进队

  双向队列:队列的两端都支持进队和出队操作

3.1 python队列内置模块

  基本操作:

    创建队列:queue = deque(li)

    进队:append

    出队:popleft

    双向队列队首进队:appendleft

    双向队列队尾进队:pop

from collections import deque

lis = [9,5,2,7]
q = deque(lis,8)    # 最大长度是8
q.append(4)     # 从队尾追加
q.popleft()     # 队首出队

# 对于双向对列
q.appendleft(99)    # 队首进队
q.pop()             # 队尾出队

4.关于栈(stack)

  栈也是一个数据集合,只能在一端进行插入或删除操作的列表

  特点:后进先出。联想一摞书,我们取书只能从上取,存入也只能从上面存

利用python代码实现一个栈

class Stack(object):
   # 初始化栈
   def __init__(self):
      self.items = []
   # 判断栈是否为空
   def is_empty(self):
      return self.items == []
   # 返回栈顶
   def peek(self):
      return self.items[len(self.items) - 1]
   # 返回栈大小
   def size(self):
      return len(self.items)
   # 压栈
   def push(self, item):
      self.items.append(item)
   # 出栈
   def pop(self):
      return self.items.pop()

4.1 python栈内置模块

  栈的基本操作:

    进栈(压栈):push

    出栈:pop

    取栈顶:gettop(查看栈顶元素,但不取走)  li[-1]

博客参考链接

 5.关于链表

属于一种动态数据结构,链表中每一个元素都是一个对象每个对象称为一个节点,包含有数据域key和指向下一个节点的指针next。通过各个节点之间的相互连接,最终串联成一个链表

链表的基本元素:

  节点:每个节点有两个部分,左边部分称为值域,用来存放用户数据;右边部分称为指针域,用来存放指向下一个元素的指针。

  head:head节点永远指向第一个节点

  tail: tail永远指向最后一个节点

  None:链表中最后一个节点的指针域为None值

链表和数组的区别:

  1.数组需要提前定义大小,数据小于定义长度会浪费空间,大于定义长度则无法插入。而链表是动态增删数据,可以随意增加

  2.数组适用于获取元素的操作,直接get索引即可。链表对于获取元素需要从头一直寻找,但是适用与增删,直接修改节点的指向即可

  3.数组从栈中分配空间,操作方便,但是自由度小,链表从堆中分配空间, 自由度大但申请管理比较麻烦

 节点定义:

class Node:
    def __init__(self,data=None,next=None):
        self.data = data
        self.next = next        # 保存下一个节点对象

    def __repr__(self):
        return str(self.data)

定义链表:

# 定义节点
node1 = Node(1)
node2 = Node(2)
node3 = Node(3)

# 将每个节点的关系表示出来
node1.next = node2
node2.next = node3

链表出数:

# 顺序出数
def printList(node):
    while node:
        print(node)
        node = node.next

printList(node1)


# 逆序出数
def printBackward(lists):
    if lists == None: return
    printBackward(lists.next)
    print(lists)

printBackward(node1)

5.1 链表基本操作

链表翻转(面试常见问题)

class Node:
    def __init__(self, data=None, next=None):
        self.data = data
        self.next = next  # 保存下一个节点对象

    def __repr__(self):
        return str(self.data)


# 时间消耗O(n),空间消耗O(1)
def rever(head):
    if head == None or head.next == None:  # 边界条件
        return head

    cur = head  # 链表头
    tmp = None  # 临时变量
    newhead = None  # 翻转链表表头
    while cur:  # 存在链表头
        tmp = cur.next  # tmp为链表头下一节点
        cur.next = newhead  # 此时cur.next为None
        newhead = cur  # 把链表头赋值给翻转链表头
        cur = tmp  # 把下一节点赋值给链表头
    return newhead


if __name__ == '__main__':

    head = Node(1)
    a1 = Node(2)
    a2 = Node(3)
    a3 = Node(4)
    head.next = a1
    a1.next = a2
    a2.next = a3

    p = rever(head)
    while p:
        print(p.data)
        p = p.next

最终打印结果4,3,2,1

 链表翻转的四种方式:链接

单向链表的详细操作方式:链接

常见数据结构:参看链接

posted @ 2018-10-02 22:07  -Learning-  阅读(868)  评论(0编辑  收藏  举报