python daily algorithm | basis of data structure: stack and queue and classic maze problem

Keywords: Python Algorithm data structure queue stack

  It's not easy to create, my guest, pay attention, collect and subscribe to one button three times ❤😜         


preface

Program = data structure + algorithm. Algorithm is a mixture of mathematical theory and engineering implementation. It is a very interesting and magical knowledge. Understanding the algorithm and looking at programming from another perspective will be a new feeling. If you are also learning the algorithm, you might as well learn with director Mengxin super poor and win the algorithm!

Catalogue of series articles

python daily algorithm | Radix sorting PK quick sorting, hand tearing Radix sorting algorithm!

python daily algorithm | picture and text + vivid example detailed bucket sorting

python daily algorithm | uncover the secret of counting and sorting

summary

This issue will introduce the basic knowledge of data structure (I): stack and queue and the most classic maze problem.

catalogue

preface

Catalogue of series articles

summary

Super python daily algorithm mind map

Basic knowledge of data structure

What is the data structure?

Logical structure of data structure

linear structure

list

Stack

What is the stack

Basic operation of stack

Implementing stack with python

Application of stack: bracket matching problem

queue

What is the queue

Bidirectional queue

Implementation mode of queue: Ring queue

Implementing queue with python

python queue built-in module: deque

Application of queue: using deque to implement Linux tail command

Maze problem

Stack: depth first search

code implementation

Queue: breadth first search

code implementation

Super python daily algorithm mind map

Basic knowledge of data structure

What is the data structure?

Data structure refers to the collection of data elements with one or more relationships and the relationship between data elements in the collection. Simply put, data structure is to design how data is organized and stored in the computer.

For example, lists, sets and dictionaries are all data structures.

N.Wirth said, "program = data structure + algorithm"

Logical structure of data structure

According to its logical structure, data structure can be divided into linear structure, tree structure and graph structure.

linear structure

Linear structure: there is a one-to-one relationship between the elements in the data structure, such as a list.

Tree structure: there is a one to many relationship between the elements in the data structure, such as heap.

Graph structure: the elements in the data structure have many to many relationships

list

List (called list in python and array in other languages) is a basic data type.

Questions about lists:

How are the elements in the list stored?

On a 32-bit machine, an integer occupies 4 bytes, an address occupies 4 bytes, and a 64 bit address occupies 8 bytes.

The existing list is as follows:

1

2

3

4

5

Taking a 32-bit machine as an example, the array is stored as follows:

If the memory address of element 1 is 100, the memory address of element 2 is 104, and so on, then a[2]=100+2*4=108.

For the list, if the address of 1 is 200, 2 -- > 300, 3 -- 88, the list is to find the address, and then find the corresponding element through an address.

200

300

88

The difference between array and list:

1. The element types of the array need to be consistent, and the element types of the list do not need to be consistent;

2. The length of the array is fixed, and the python list can be infinite.

Basic operations of the list: insert elements, delete elements... What is the time complexity of these operations?

Insert: O(n). Each insert will move the front and rear elements

Delete (pop): O(n). The following address will be moved forward after each deletion

Stack

What is the stack

Stack is a data set, which can be understood as a list that can only be inserted or deleted at one end.

Stack features: LIFO (last in, first out)

For example, for a pile of books in the picture, the last one is the most advanced and the first to go out.

The concept of stack: top and bottom of stack

Basic operation of stack

Stack: push, (put another book on a pile of books)

Out of stack: pop (take the top book of a stack of books)

Take the top of the stack: gettop (I only read what the top book is)

Implementing stack with python

Stack implementation: the stack can be realized by using the general list structure.

Stack: lst.append()

Stack out: lst.pop()

Stack top: lst[-1]

class stack:

    def __init__(self):

        self.stack = []

 

    def push(self,element):

        self.stack.append(element)  # Stack operation

 

    def pop(self):

        return self.stack.pop()  # Delete stack top

 

    def get_top(self):

        if len(self.stack) > 0:  # Make sure there are elements in the stack

            return self.stack[-1]  # Take stack top

        else:

            return None

 

stack = stack()

stack.push(1)

stack.push(2)

stack.push(3)

stack.push(4)

print(stack.pop())

print(stack)

print(stack.get_top())

# Output results:

# 4

# <__main__.stack object at 0x000001CC63BBEFD0>

# 3

Application of stack: bracket matching problem

Bracket matching problem: give a string, including parentheses, brackets and braces, and find out whether the brackets in the string match.

For example:

() [] {} -- > match

([{()}]) -- > match

[] (-- > mismatch

[(]) -- > mismatch

#Bracket mismatch problem

"""

For example: () [] [{()}]

1. The "(" at the top of the stack matches the next ")" at the top of the stack, and the stack is pushed out of the stack;

2. Next, the "[" at the top of the stack matches "]" and "[" comes out of the stack

3. Stack top: "[", followed by "{" in the stack, followed by "(" in the stack, ")" in the stack and matched at the top of "C", so the stack is pushed out of the stack

4. Next "}" is matched with "{" at the top of the stack, and the stack is pushed out of the stack

5. "]" enters the stack, matches "[" at the top of the stack, and exits the stack

"""

def brace_match(str1):

    match_dict = {')':'(','}':'{',']':'['}  # Establish matching mechanism

    stack = Stack()

    for i in str1:

        if i in {'(','[','{'}:  # Left part stack

            stack.push(i)

        else:  # i in {')','}',']'}

            if stack.is_empty():

                return False

            elif stack.get_top() == match_dict[i]:

                stack.pop()

            else:  # The stack character does not match the top of the stack

                return False

    if stack.is_empty:

        return True

    else:

        return False



print(brace_match("{{[()]}}"))

# Output:

# True

print(brace_match("{{[()]{()}}}"))

# Output:

# True

print(brace_match("{[)]{()}}"))

# output

# False

queue

What is the queue

Queue: a queue is a data collection. It can only be inserted at one end of the list and deleted at the other end.

The end of the insertion is called the end of the team (rear), and the insertion action is called entering the team or joining the team

The end of the deletion is called the front, and the deletion action is called out of the queue

Nature of queue: first in, first out

Bidirectional queue

Both ends of the two-way queue support incoming and outgoing operations. The basic operations of the two-way queue are as follows:

Team first team

Team first team

Team tail into team

Out of the team at the end of the team

Implementation mode of queue: Ring queue

As shown in the figure, in the out of queue and in queue process of bit ring queue, rear=front is empty.

1.A enters the team, rear -- > + 1

2.BCDEFGH enters the team, and the rear increases by 1 in turn

3.ABCD out of the team, front -- > 5, team head -- > F, team tail -- > H

4.IJKM enters the team -- > near plus 1

5. When P enters the team, the team is full. (why does rear and front not coincide? To ensure whether the team is empty or full.)

Therefore, the team is full -- > rear + 1 = front, air to air: rear = front

Ring queue: when the end of the queue pointer front == Maxsize (queue length) - 1, another position will automatically reach 0

Head of line pointer forward 1: front = (front + 1)% maxsize

End of queue pointer forward 1: rear = (rear + 1)% maxsize

Air condition: rear == front

Full queue condition: (rear + 1)% maxsize = = front

Implementing queue with python

class Queue:

    def __init__(self,size=100):  #Queue length is 100

        self.size = size

        self.queue = [0 for i in range(size)]

        self.rear = 0  # Tail pointer

        self.front = 0  # Header pointer



    def push(self,element):  # Join the team

        if not self.is_filled():  # Ensure team dissatisfaction

            self.rear = (self.rear+1) % self.size

            self.queue[self.rear] = element

        else:

            raise IndexError("Queue is filled")



    def pop(self):  # Out of the team

        if not self.is_empty():  # Make sure the team is not empty

            self.front = (self.front + 1) % self.size

            return self.queue[self.front]

        else:

            raise IndexError("Queue is empty.")



    def is_empty(self):  # Judge team empty

        return self.rear == self.front



    def is_filled(self):  # Judge team full

        return (self.rear + 1) % self.size == self.front



q = Queue(5)

for i in range(4):

    q.push(i)

print(q.pop())

q.push(13)

print(q.pop())

q2 = Queue(5)

for i in range(5):

    q.push(i)

print(q.is_filled())

# Output results

# 0

# 1

# IndexError: Queue is filled

python queue built-in module: deque

Built in module of queue: deque

from collections import deque



q = deque()

q.append(1)  # Team tail into team



print(q.popleft()) # Team first team

# Output results

# 1

# print(q.popleft())  # Team air condition

# Output results

# IndexError: pop from an empty deque



q = deque([1,2,3,4)  # Queue length 4

q.append(5)  # Team tail into team

print(q)

print(q.popleft())  # Team first team

# Output results

# deque([1, 2, 3, 4, 5], maxlen=5)

# 1

# For bidirectional queues

# q.appendleft()  # Team first team

# q.pop()  # Out of the team at the end of the team

Application of queue: using deque to implement Linux tail command

test:

"

cc

1314

hi

I am chaochao

follow chaochao,day day up together

"
def  tail(n):

    with open("test",'r') as f:

        q = deque(f,n)

        return q

# print(tail(1))

# Output results

# deque(['chaochao'], maxlen=1)

for line in tail(3):

    print(line,end="")

# Output results

# hi

# I am chaochao

# follow chaochao,day day up together

Maze problem

Give a two-dimensional list to represent the maze (0 represents the channel and 1 represents the fence). The algorithm is given to find a path out of the maze.

maze = [
    [1,1,1,1,1,1,1,1,1,1],
    [1,0,0,1,0,0,0,1,0,1],
    [1,0,0,1,0,0,0,1,0,1],
    [1,0,0,0,0,1,1,0,0,1],
    [1,0,1,1,1,0,0,0,0,1],
    [1,0,0,0,1,0,0,0,0,1],
    [1,0,1,0,0,0,1,0,0,1],
    [1,0,1,1,1,0,1,1,0,1],
    [1,1,0,0,0,0,0,0,0,1],
    [1,1,1,1,1,1,1,1,1,1]
]

Stack: depth first search

The idea of backtracking method: (one way to the black) start from a node, arbitrarily find the next point that can go. When the point that can go cannot be found, return to the previous point to find whether there are points in other directions. Use the stack to store the current path.

code implementation

maze = [

    [1,1,1,1,1,1,1,1,1,1],

    [1,0,0,1,0,0,0,1,0,1],

    [1,0,0,1,0,0,0,1,0,1],

    [1,0,0,0,0,1,1,0,0,1],

    [1,0,1,1,1,0,0,0,0,1],

    [1,0,0,0,1,0,0,0,0,1],

    [1,0,1,0,0,0,1,0,0,1],

    [1,0,1,1,1,0,1,1,0,1],

    [1,1,0,0,0,0,0,0,0,1],

    [1,1,1,1,1,1,1,1,1,1]

]

# Representation of four directions

dir_lst = [

    lambda x,y:(x+1,y),

    lambda x,y:(x-1,y),

    lambda x,y:(x,y-1),

    lambda x,y:(x,y+1)

]



def maze_path(x1,y1,x2,y2):

    stack = []

    stack.append((x1,y1))  # The initial position is a binary

    while(len(stack)>0):  # When the stack is not empty, the loop has a way to go

        curNode = stack[-1]  # Current coordinates, list form

        # Judge whether we have reached the end

        if curNode[0] == x2 and curNode[1]== y2:

            for i in stack:

                print(i)

            return True

        """

        Four directions indicate:

        Left-->(x-1,y),right-->(x+1,y),upper-->(x,y-1),lower-->(x,y+1)

        """

        for dir in dir_lst:

            nextNode = dir(curNode[0],curNode[1])

            # If the next point can go

            if maze[nextNode[0]][nextNode[1]] == 0:

                stack.append(nextNode)

                # Mark the point passed, so a value of 2 indicates that it has passed

                maze[nextNode[0]][nextNode[1]] = 2

                break  # break when you find a place to go

        else:

            maze[nextNode[0]][nextNode[1]] = 2

            stack.pop()  # Push the stack out of the stack, backtrack, and then cycle to find the point where you can go

    else:

        print("There is no way to go")

        return False



# verification

maze_path(1,1,8,8)

# Output results

# (1, 1)

# (2, 1)

# (3, 1)

# (4, 1)

# (5, 1)

# (5, 2)

# (5, 3)

# (6, 3)

# (6, 4)

# (6, 5)

# (7, 5)

# (8, 5)

# (8, 6)

# (8, 7)

# (8, 8)

Queue: breadth first search

Idea: start from one node, look for all the points that can continue to go next, and continue to look until you find the exit. Use a queue to store the nodes currently under consideration. The queue stores the current point.

Store the following columns:

current location

1

2

3

4

5

6

7

Previous point position

-1 (default)

0

1

2 (3 let it come)

2 (3 let it come)

3 (4 let it come)

4 (5 let him come)

code implementation

from collections import deque

maze2 = [

    [1,1,1,1,1,1,1,1,1,1],

    [1,0,0,1,0,0,0,1,0,1],

    [1,0,0,1,0,0,0,1,0,1],

    [1,0,0,0,0,1,1,0,0,1],

    [1,0,1,1,1,0,0,0,0,1],

    [1,0,0,0,1,0,0,0,0,1],

    [1,0,1,0,0,0,1,0,0,1],

    [1,0,1,1,1,0,1,1,0,1],

    [1,1,0,0,0,0,0,0,0,1],

    [1,1,1,1,1,1,1,1,1,1]

]



dirs = [

    lambda x,y:(x+1,y),

    lambda x,y:(x-1,y),

    lambda x,y:(x,y-1),

    lambda x,y:(x,y+1)

]

# Output path at end point

def print_r(path):

    curNode = path[-1]  # Last node

    realpath = []  # route

    while curNode[2] != -1:  # That is, when the last node is deployed to the destination

        realpath.append(curNode[0:2])

        curNode = path[curNode[2]]

    realpath.append(curNode[0:2])  # starting point

    realpath.reverse()  # Flashback list

    for i in realpath:

        print(i)



def maze_path_queue(x1,y1,x2,y2):

    queue = deque()

    queue.append((x1,y1,-1))

    path = []  # Put the dequeued nodes in the path list

    while len(queue) > 0:  # Queue out of time cycle

        curNode = queue.popleft()

        path.append(curNode)

        if curNode[0] == x2 and curNode[1] == y2:  # Reach the end

            print_r(path)  # Reach the destination and output the path

            return True

        for dir in dirs:

            nextNode = dir(curNode[0],curNode[1])

            if maze2[nextNode[0]][nextNode[1]] == 0:

                queue.append((nextNode[0],nextNode[1],len(path[-1])-1))  # Follow up nodes enter the team and record which node brings her

                maze2[nextNode[0]][nextNode[1]] = 2  # Mark that this point has passed

    else:

        print("There is no way to go")

        return False



maze_path_queue(1,1,6,8)

It's not easy to create. Please give me a compliment and comment! Chao chao, come on with you ❤😜  

Posted by kutte on Sun, 21 Nov 2021 03:31:12 -0800