Data Structure Series Learning (7) - Chain Stack (Chain_Stack)

Table of contents

introduction:

study:

Code:

Header file (Chain_Stack.h):

Set the element type in the chain stack:

The structure design of the chain stack:

Declaration of all functional functions:

The specific implementation of the function function in the source file (Chain_Stack.cpp):

Initialization function (Init_Stack):

Clear function (Clear);

Destroy function (Destroy):

Print function (Show):

Search function (Search):

Push function (Push):

Stack function (Pop):

Function to return the top element of the stack (Top):

Empty judgment function (IsEmpty):

Get the number of valid data function (Get_Length):

test:

Test initialization function, print function:

Test clear function: 

Test destroy function:

​Edit test lookup function:

​Edit test push function:

Test the stack function:

 Test the function that returns the top element of the stack:

Summarize:

References:


introduction:

Data structure learning directory:

Data Structure Series Learning (1) - An Introduction to Data Structure

Data structure series learning (2) - sequence table (Contiguous_List)

Data Structure Series Learning (3) - Singly Linked List (Linked_List)

Data Structure Series Learning (4) - Circular Linked List

Data Structure Series Learning (5) - Doubly Linked List (Double_Linked_List)

Data structure series learning (6) - sequential stack (Stack)

In the last article, we learned about the sequential stack and implemented it using code. In this article, we will learn about another expression form of the stack - Chain_Stack (Chain_Stack) and implement it with code.

study:

Chain stack, that is, the chain storage structure of the stack. The chain stack is a data storage structure that can be realized by a single linked list. The advantage of using the chain stack is that it can overcome the low utilization rate of the sequential stack space implemented by the array. features, but it is necessary to allocate additional pointer space for each stack element to store the pointer field.

Here we need to think, how should we use a singly linked list to implement the stack as a storage method? The figure shows a singly linked list without a head node:

As we said before, a stack (Stack) is a linear table that is limited to insert or delete operations only at the end of the table.

Therefore, according to the characteristics of the stack, we set the throughput port between the head node of the single-linked list and the first valid node. In fact, it is the head insertion and head deletion functions in the single-linked list that we have implemented before.

There is nothing difficult about this thing. To put it bluntly, it is a castrated version of a single linked list.

Code:

Functions to be implemented in the chain stack:

initialization function (Init_Stack);

Clear function (Clear);

Destroy function (Destroy);

print function(Show);

Find function (Search);

Push function (Push);

Pop function (Pop);

return stack top element function (Top);

Empty judgment function (IsEmpty);

Get valid data number function (Get_Length);

Header file (Chain_Stack.h):

Set the element type in the chain stack:

typedef int Elem_type;

The structure design of the chain stack:

Because we implement the abstract data type of the stack through a single linked list, we design the structure of the linked stack directly using the structure of the linked list.

typedef struct CStack
{
    Elem_type data;
    struct CStack* next;
}Stack,*PStack;

Declaration of all functional functions:

//初始化
void Init_Stack(PStack cstack);
//清空
void Clear(PStack cstack);
//销毁
void Destroy(PStack cstack);
//打印
void Show(PStack cstack);
//查找
PStack Search(PStack cstack,Elem_type val);
//入栈
bool Push(PStack cstack,Elem_type val);
//出栈
bool Pop(PStack cstack);
//返回栈顶元素
Elem_type top(PStack cstack);
//判空函数
bool IsEmpty(PStack cstack);
//返回有效元素个数
int Get_Length(PStack cstack);

The specific implementation of the function function in the source file (Chain_Stack.cpp):

Initialization function (Init_Stack):

Directly discard the data field of the U-turn node, and set the next field of the head node to be empty.

void Init_Stack(PStack cstack)
{
    assert(cstack != nullptr);
    cstack->next = nullptr;
}

Clear function (Clear);

Empty and destroy in the linked list have the same meaning, just call the destroy function directly in the clear function.

void Clear(PStack cstack)
{
    Destroy(cstack);
}

Destroy function (Destroy):

When our link stack is not empty, the header delete function is called infinitely until the linked list is empty.

void Destroy(PStack cstack)
{
    assert(cstack != nullptr);
    while (!IsEmpty(cstack)){
        Pop(cstack);
    }
}

Print function (Show):

Define the structure type pointer p to point to the first valid node after the head node, define a loop, and the loop condition is that the point of p is not an empty address, p can traverse to the end node, and the data field of the node pointed to by p The data can be printed out one by one.

void Show(PStack cstack)
{
    assert(cstack != nullptr);
    PStack p = cstack->next;
    for(;p != nullptr;p = p->next){
        printf("%3d", p->data);
    }
}

Search function (Search):

The search function is a structure pointer type, define the structure type pointer p to point to the first valid node after the head node, define a loop, and the loop condition is that p does not point to an empty address, when the value in the data field of the node pointed to by the p pointer is equal to When we want to find the value, return the address of this node, if not found, return the empty address.

PStack Search(PStack cstack,Elem_type val)
{
    assert(cstack != nullptr);
    PStack p = cstack->next;
    assert(p != nullptr);
    for(;p != nullptr;p = p->next){
        if(val == p->data){
            return p;
        }
    }
    return nullptr;
}

Push function (Push):

At this time, the push function is simpler than the head insertion function in the singly linked list. First, the malloc function is used to apply for memory for the new node in the heap area, and the value we want to insert is assigned to the data field of the new node, and the original head node The next field (that is, the address of the first valid node) is assigned to the next field of pnewnode, and then the address of pnewnode is assigned to the next field of the head node, as shown in the figure:

 

bool Push(PStack cstack,Elem_type val)
{
    assert(cstack != nullptr);
    PStack pnewnode = (PStack)malloc(1 * sizeof(Stack));
    assert(pnewnode != nullptr);
    pnewnode->data = val;
    pnewnode->next = cstack->next;
    cstack->next = pnewnode;
    return true;
}

Stack function (Pop):

The pop function at this time is equivalent to the head delete function in the singly linked list. First, the linked list is judged to be empty. If the linked list is empty, it returns false directly. Define the structure type pointer p to point to the first valid node after the head node, so at this time the next field of p stores the address of the second valid node, and then we perform a cross-pointing operation to set the address of the second valid node Just assign it to the next field of the head node, as shown in the figure:

 

bool Pop(PStack cstack)
{
    assert(cstack != nullptr);
    if(IsEmpty(cstack)){
        return false;
    }
    PStack p = cstack->next;
    assert(p != nullptr);
    cstack->next = p->next;
    return true;
}

Function to return the top element of the stack (Top):

The type of the returned element is the chain stack element paradigm we set before, define the structure type pointer p to point to the first valid node after the head node, define the loop, and the loop condition is that p is equal to the empty address, at this time p can traverse to The end node, and then we just return the value in the data field of the end node.

Elem_type top(PStack cstack)
{
    assert(cstack != nullptr);
    PStack p = cstack->next;
    for(;p != nullptr;p = p->next);
    printf("%3d",p->data);
}

Empty judgment function (IsEmpty):

When the next field of the head node is empty, it means that the entire chain stack is empty.

bool IsEmpty(PStack cstack)
{
    assert(cstack != nullptr);
    return cstack->next == nullptr;
}

Get the number of valid data function (Get_Length):

Define the integer value of count, define the structure type pointer p to point to the first valid node after the head node, and add 1 to the value of count every time p goes backwards, and finally return the value of count.

int Get_Length(PStack cstack)
{
    assert(cstack != nullptr);
    int count = 0;
    PStack p = cstack->next;
    for(;p != nullptr;p = p->next){
        count++;
    }
    return count;
}

test:

Test initialization function, print function:

Initialize the chain stack, fill it with 10 elements through the push function, and print out the elements in the chain stack.

#include "Chain_Stack.h"
#include<cstdio>
int main()
{
    Stack chain;
    Init_Stack(&chain);
    for(int i = 0;i < 10;i++){
        Push(&chain,i + 1);
    }
    printf("原始数据为:\n");
    Show(&chain);
    return 0;
/*
    此处添加其他测试代码...
*/
}

operation result:

Test clear function: 

    Clear(&chain);
    printf("\n经过清空操作之后的数据为:\n");
    Show(&chain);

operation result: 

Test destroy function:

    Destroy(&chain);
    printf("\n经过销毁操作之后的数据为:\n");
    Show(&chain);

operation result: 

Test lookup function:

The element we are looking for in the chain stack is 2:

    PStack p = Search(&chain,2);
    printf("\n元素2在链栈中的地址为:%p\n",p);

operation result:

Test push function:

After the initialization of the chain stack is completed, push 11 into the stack:

    Push(&chain,11);
    printf("\n经过入栈操作之后的数据为:\n");
    Show(&chain);

operation result:

Test the stack function:

    Pop(&chain);
    printf("\n经过一个出栈后的数据为:\n");
    Show(&chain);

 operation result:

 Test the function that returns the top element of the stack:

    printf("\n栈顶元素为:%3d",top(&chain));

operation result:

Summarize:

The realization of the sequential stack lies in the use of the basic data structure of the array. The storage locations of the elements in the array are continuous in the memory, and the compiler requires us to determine the size of the array at compile time, which is not efficient for memory usage. High, because the memory is always in one block, and the overflow problem caused by the exhaustion of the array space cannot be avoided. Second, after the system allocates the memory to the array, the memory is unavailable for other tasks; and for the chain stack , using a linked list to implement the stack. The elements in the linked list are stored in discontinuous addresses. Because the memory is dynamically allocated, we can start with a very small memory space. In addition, when an item is not used, the memory can also be returned to system.

Linked stack is the second manifestation of the abstract data type of stack. The overall difficulty is relatively low. Of course, this is based on the premise that you are quite familiar with the structure and code of the single linked list. Writing a linked stack is also equivalent to us once again. I have practiced the relevant code of the singly linked list. At the same time, it is also important to master the linked stack.

References:

Yan Weimin, Wu Weimin - "Data Structure (C Language Edition)"

Chained stack - Wikipedia

Guess you like

Origin blog.csdn.net/weixin_45571585/article/details/127818125