其他分享
首页 > 其他分享> > 《大话数据结构》之栈

《大话数据结构》之栈

作者:互联网

下面会出现一些我在《大话数据结构》之线性表中定义的数据种类,在全部完成之后,我会整理好发到我的github上去。

这个就是在一端进,同一端出的那种。

顺序存储实现栈

栈可以用线性表来存储。比如顺序存储来实现栈:

image-20210504113017163

这里有一个存储头部元素的数组下标在哪里的值:top

数据结构就是:

typedef struct {
    SqlList sqlList;
    int top;
} SqlListStack;

对应的出栈和入栈操作是:

/**
 * 插入元素
 * @param sqlListStack
 * @param data
 * @return
 */
Return PushSqlListStack(SqlListStack* sqlListStack,ElementType data){
    // 栈已满
    if (sqlListStack->top==MAX_LIST_LENGTH){
        return Error;
    }
    if(addSqlListElement(&sqlListStack->sqlList,data,sqlListStack->top+1)==Success){
        sqlListStack->top++;
    }
    return Error;
}
/**
 * 剔除数据
 * @param sqlListStack
 * @return
 */
ElementType PopSqlListStack(SqlListStack* sqlListStack){
    ElementType deleteData=sqlListStack->sqlList.data[sqlListStack->top];
    // 空队列
    if (sqlListStack->top<0){
        exit(0);
    }
    deleteSqlListElement(&sqlListStack->sqlList,sqlListStack->top);
    sqlListStack->top--;
    return deleteData;
}

使用演示:

void SqlListStackIndex(){
    SqlListStack sqlListStack={
            .sqlList={
                    .length=0
            },
            .top=-1
    };
    PushSqlListStack(&sqlListStack,1);
    PushSqlListStack(&sqlListStack,2);
    PushSqlListStack(&sqlListStack,3);
    PrintfSqlList(&sqlListStack.sqlList);
    PopSqlListStack(&sqlListStack);
    PopSqlListStack(&sqlListStack);
    PrintfSqlList(&sqlListStack.sqlList);
}

其实本质就是在操作top这个值,记录栈顶元素的位置。

链表实现栈

这里问一个问题,当使用链表实现栈的时候,如果有元素要入栈,是将元素放在链表的末尾,还是头部呢?

当然是放在头部啊,这样就不用每次入栈和出栈都需要遍历整个链表了。

image-20210504114421025

链表的数据结构是:

typedef struct {
    Node* topNode;
    int top;
} NodeStack;

出栈和入栈的代码:

/**
 * 插入元素
 * @param nodeStack
 * @param data
 * @return
 */
Return PushNodeStack(NodeStack *nodeStack,ElementType data){
    // 因为C语言存储类别的关系,所以如果直接采用变量的形式,会因为内存访问限制而直接报错
    Node *newTop=malloc(sizeof(Node));
    newTop->value=data;
    newTop->next=0;
    // 防止第一个top时,一直指向自己,造成死循环
    if(nodeStack->top>0){
        newTop->next=nodeStack->topNode;
    }
    nodeStack->topNode=newTop;
    nodeStack->top++;
    return Success;
}
/**
 * 删除元素
 * @param nodeStack
 * @return
 */
ElementType PopNodeStack(NodeStack *nodeStack){
    ElementType deleteData=nodeStack->topNode->value;
    Node *topAddress=nodeStack->topNode;
    nodeStack->topNode=nodeStack->topNode->next;
    free(topAddress);
    return deleteData;
}

使用演示:

void NodeStackIndex(){
    NodeStack nodeStack={
            .top=0
    };
    PushNodeStack(&nodeStack,1);
    PushNodeStack(&nodeStack,2);
    PushNodeStack(&nodeStack,3);
    PrintNode(nodeStack.topNode);
    PopNodeStack(&nodeStack);
    PopNodeStack(&nodeStack);
    PrintNode(nodeStack.topNode);
}

顺序存储中使用2个栈

使用两个下标的形式,往中间前进,这样就可以减少闲置的内存资源了。

image-20210504115228727

数据结构是这样的:

typedef struct {
    SqlList sqlList;
    int leftTop;
    int rightTop;
} DoubleSqlListStack;

对应的出栈和入栈的代码:

/**
 * 插入元素
 * @param doubleSqlListStack
 * @param data
 * @param isLeft 插入位置
 * @return
 */
Return PopDoublerSqlListStack(DoubleSqlListStack *doubleSqlListStack,ElementType data,short int isLeft){
    // 栈已满
    if ((doubleSqlListStack->leftTop+1)==doubleSqlListStack->rightTop){
        return Error;
    }
    if (isLeft){
        doubleSqlListStack->sqlList.data[doubleSqlListStack->leftTop]=data;
        doubleSqlListStack->leftTop++;
        return Success;
    }else{
        doubleSqlListStack->sqlList.data[doubleSqlListStack->rightTop]=data;
        doubleSqlListStack->rightTop--;
        return Success;
    }
}
/**
 * 剔除元素
 * @param doubleSqlListStack
 * @param isLeft
 * @return
 */
ElementType PushDoublerSqlListStack(DoubleSqlListStack *doubleSqlListStack,short int isLeft){
    // 空队列
    if (isLeft && doubleSqlListStack->leftTop==0){
        exit(0);
    }else if(doubleSqlListStack->rightTop==(MAX_LIST_LENGTH-1)){
        exit(0);
    }
    if (isLeft){
        doubleSqlListStack->leftTop--;
        return doubleSqlListStack->sqlList.data[doubleSqlListStack->leftTop+1];
    }
    doubleSqlListStack->rightTop++;
    return doubleSqlListStack->sqlList.data[doubleSqlListStack->rightTop-1];
}
/**
 * 辅助函数,打印中间结果
 * @param doubleSqlListStack
 */
void PrintDoublerSqlList(DoubleSqlListStack *doubleSqlListStack){
    for (int i = 0; i < doubleSqlListStack->leftTop; ++i) {
        printf("Position %d's data is ",i);
        printf(ElementPrintType,doubleSqlListStack->sqlList.data[i]);
        BR;
    }
    for (int i = doubleSqlListStack->rightTop+1; i < MAX_LIST_LENGTH; ++i) {
        printf("Position %d's data is ",i);
        printf(ElementPrintType,doubleSqlListStack->sqlList.data[i]);
        BR;
    }
}

使用演示:

void DoubleSqlListStackIndex(){
    DoubleSqlListStack doubleSqlListStack={
            .sqlList={
                    .length=MAX_LIST_LENGTH
                    },
            .leftTop=0,
            .rightTop=MAX_LIST_LENGTH-1
    };
    PopDoublerSqlListStack(&doubleSqlListStack,1,1);
    PopDoublerSqlListStack(&doubleSqlListStack,2,0);
    PrintDoublerSqlList(&doubleSqlListStack);
    PushDoublerSqlListStack(&doubleSqlListStack,1);
    PushDoublerSqlListStack(&doubleSqlListStack,0);
    PrintDoublerSqlList(&doubleSqlListStack);
}

标签:return,nodeStack,sqlListStack,doubleSqlListStack,大话,之栈,数据结构,data,top
来源: https://blog.csdn.net/YQXLLWY/article/details/116399137