栈、队列、链表、数组

本文介绍了数据结构中的四种基本类型:栈、队列、链表和数组。栈涉及其定义、特点和Python实现,特别讨论了匹配括号问题。队列讲解了定义、Python实现及应用场景,强调了与列表的区别。链表部分涵盖了单链表和双链表的概念及操作。最后,对比了数组和Python中list的差异,突出数组在不同编程语言中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 栈

1、栈的定义

栈是一种数据集合,可以理解为只能在一端进行插入或删除操作的列表

2、栈的特点

后进先出(last-in, first-out)

3、栈的概念

栈顶,栈底

4、栈的基本操作

进栈(压栈):push

出栈:pop

取栈顶:gettop

5、python实现栈

class Stack(object):

    def __init__(self):
        self.stack = []              # 初始化一个栈

    def push(self,item):             # 入栈
        self.stack.append(item)

    def gettop(self):                # 获取栈顶元素
        return self.stack[-1]

    def pop(self):                   # 出栈
        return self.stack.pop()


if __name__ == '__main__':
    s = Stack()
    s.push(1)
    s.push(2)
    print(s.stack)

6、栈的使用:匹配括号是否成对出现

def check_kuohao(s):
   stack = []
   for char in s:
      if char in ['(','[','{']:
         stack.append(char)
      elif char == ')':
         if len(stack)>0 and stack[-1] == '(':
            stack.pop()
         else:
            return False
      elif char == ']':
         if len(stack) > 0 and stack[-1] == '[':
            stack.pop()
         else:
            return False
      elif char == '}':
         if len(stack) > 0 and stack[-1] == '{':
            stack.pop()
         else:
            return False
   if len(stack) == 0:
      return True
   else:
      return False
print(check_kuohao('(){}{}[]'))  #True

2. 队列

1、队列定义

 1、队列是一个数据集合,仅允许在列表的一端进行插入,另一端进行删除
 2、插入的一端称为队尾(rear),插入动作叫进队或入队
 3、进行删除的一端称为对头(front),删除动作称为出队
 4、队列性质:先进先出(First-in, First-out)
 5、双向队列:队列的两端都允许进行进队和出队操作

2、队列使用方法
  1、导入: from collectios import deque
  2、创建队列:queue = deque(li)
  3、进队: append
  4、出队: popleft
  5、双向队列队首进队:appendleft
  6、双向队列队尾出队:pop
3、python实现队列

from queue import Queue
#1. 基本FIFO队列  先进先出 FIFO即First in First Out,先进先出
#2. maxsize设置队列中,数据上限,小于或等于0则不限制,容器中大于这个数则阻塞,直到队列中的数据被消掉
q = Queue(maxsize=0)

#3. 写入队列数据
q.put(0)
q.put(1)
q.put(2)

#4. 输出当前队列所有数据
print(q.queue)

#5. 删除队列数据,并返回该数据
q.get()

#6. 输也所有队列数据
print(q.queue)

4、队列应用场景

  1. 队列主要的功能是在多个进程间共享数据,实现业务解耦,提高效率

  2. 生产者线程只需要把任务放入队列中,消费者线程只需要到队列中取数据进行处理

5、队列与列表区别
 列表中数据虽然是排列的,但数据被取走后还会保留,而队列中这个容器的数据被取后将不会保留

3. 链表

1、单链表
:链表中每个元素都是一个对象,每个对象称为一个节点,包含有数据域key和指向下一节点的指针next,通过各个节点间的相互连接,最终串联成一个链表
在这里插入图片描述
python模拟链表数据类型

class Node(object):
    def __init__(self, item,next=None):
        self.item = item
        self.next = next
l = Node(1,Node(2,Node(3,Node(4))))
print(l.item)
print(l.next.item)

单链表增删改查

class Node(object):
    def __init__(self, item):
        self.item = item
        self.next = None


class DLinkList(object):
    def __init__(self):
        self._head = None

    def is_empty(self):
        return self._head == None

    def append(self, item):
        '''尾部追加元素'''
        node = Node(item)
        if self.is_empty():
            self._head = node
        else:
            cur = self._head
            while cur.next != None:
                cur = cur.next
            cur.next = node

    def add(self, item):
        """头部插入元素"""
        node = Node(item)
        if self.is_empty():
            self._head = node         # 如果是空链表,将_head指向node
        else:
            node.next = self._head      # 将node的next指向_head的头节点
            self._head = node        # 将_head 指向node

    def travel(self):
        cur = self._head
        while cur != None:
            print cur.item,
            cur = cur.next
        print ""

    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:  # 将_head指向第二个节点
                    self._head = cur.next
                return
            while cur != None:
                if cur.next.item == item:
                    cur.next = cur.next.next
                    break
                cur = cur.next

    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_next = cur.next
            # 将node的next指向cur的下一个节点
            cur.next = node
            node.next = cur_next

    def length(self):
        """返回链表的长度"""
        cur = self._head
        count = 0
        while cur != None:
            count += 1
            cur = cur.next
        return count


if __name__ == '__main__':
    ll = DLinkList()
    # 1、将链表后面追加三个元素:1,2,3
    ll.append(1)
    ll.append(2)
    ll.append(3)
    ll.travel()  # 1 2 3

    # 2、将链表头部插入一个元素:0
    ll.add(0)
    ll.travel()  # 1 2 3  ==>  0 1 2 3

    # 3、删除链表中的元素:3
    ll.remove(3)
    ll.travel()  # 0 1 2 3  ==>  0 1 2

    # 4、在链表的第2号位置插入元素:8
    ll.insert(2,8)
    ll.travel()  # 0 1 2  ==>  0 8 1 2 

链表反转

class Node(object):
    def __init__(self, val):
        self.val = val
        self.next = None

def list_reverse(head):
    if head == None:
        return None
    L, R, cur = None, None, head  # 左指针、有指针、游标
    while cur.next != None:
        L = R             # 左侧指针指向以前右侧指针位置
        R = cur           # 右侧指针前进一位指向当前游标位置
        cur = cur.next    # 游标每次向前进一位
        R.next = L        # 右侧指针指向左侧实现反转
    cur.next = R          # 当跳出 while 循环时 cur(原链表最后一个元素) R(原链表倒数第二个元素)
    return cur

if __name__ == '__main__':
    '''
    原始链表:1 -> 2 -> 3 -> 4
    反转链表:4 -> 3 -> 2 -> 1
    '''
    l1 = Node(1)
    l1.next = Node(2)
    l1.next.next = Node(3)
    l1.next.next.next = Node(4)
    l = list_reverse(l1)
    print l.val         # 4  反转后链表第一个值4
    print l.next.val    # 3  第二个值3

2、双链表
:双链表中每个节点有两个指针:一个指针指向后面节点、一个指向前面节点
在这里插入图片描述
双链表追加和遍历

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 append(self, item):
        node = Node(item)
        if self.is_empty():
            self._head = node
        else:
            cur = self._head
            while cur.next != None:
                cur = cur.next
            cur.next = node
            node.prev = cur

    def travel(self):
        cur = self._head
        while cur != None:
            print cur.item,
            cur = cur.next


if __name__ == '__main__':
    ll = DLinkList()
    ll.append(1)
    ll.append(2)
    ll.append(3)
    # print ll._head.item              # 打印第一个元素:1
    # print ll._head.next.item         # 打印第二个元素:2
    # print ll._head.next.next.item    # 打印第三个元素:3
    ll.travel()    # 1 2 3

4. 数组

1、数组定义

  1. 所谓数组,就是相同数据类型的元素按一定顺序排列的集合

  2. 在Java等其他语言中并不是所有的数据都能存储到数组中,只有相同类型的数据才可以一起存储到数组中。

  3. 因为数组在存储数据时是按顺序存储的,存储数据的内存也是连续的,所以他的特点就是寻址读取数据比较容易,插入和删除比较困难。
    在这里插入图片描述

2、python中list与数组比较

  1. python中的list是python的内置数据类型,list中的数据类不必相同的,而array的中的类型必须全部相同。
  2. 在list中的数据类型保存的是数据的存放的地址,简单的说就是指针,并非数据
  3. 否则这样保存一个list就太麻烦了,例如list1=[1,2,3,‘a’]需要4个指针和四个数据,增加了存储和消耗cpu。
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值