从零开始养成算法·篇六:栈和队列·栈

一、栈结构示意图


二、栈的常规操作

1.定义一个栈结构

/* 顺序栈结构 */
typedef struct
{
    SElemType data[MAXSIZE];
    int top; /* 用于栈顶指针 */
}SqStack

2.构建一个空栈

Status InitStack(SqStack *S){
   
    S->top = -1;
    return 1;
}

3.将栈置空

Status ClearStack(SqStack *S){
    
    S->top = -1;
    return 1;
}

4.判断顺序栈是否为空

Status StackEmpty(SqStack S){
    if (S.top == -1)
        return 1;
    else
        return 0;
}

5.求栈的长度

int StackLength(SqStack S){
    return S.top + 1;
}

6.获取栈顶

Status GetTop(SqStack S,SElemType *e){
    if (S.top == -1)
        return 0;
    else
        *e = S.data[S.top];
    return 1;
}

7.插入元素e为新栈顶元素

Status PushData(SqStack *S, SElemType e){

    if (S->top == MAXSIZE -1) {
        return 0;
    }
    S->top ++;
    S->data[S->top] = e;
    return 1;
}

8.删除S栈顶元素,并且打印删除的元素值

Status Pop(SqStack *S,SElemType *e){
   
    if (S->top == -1) {
        return 0;
    }
    
    *e = S->data[S->top];
    printf("%d ",*e);
    S->top--;
    
    return 1;
}

9.遍历栈

Status StackTraverse(SqStack S){
    int i = 0;
    printf("此栈中所有元素");
    while (i<=S.top) {
        printf("%d ",S.data[i++]);
    }
    printf("\n");
    return 1;
}

三、链栈结构示意图

1.链栈结构图


链栈结构.png

2.进栈操作


进栈.png

3.出栈操作
出栈.png

四、链栈的常规操作

1.定义一个链栈结构

/*链栈结构 */
typedef struct StackNode
{
    SElemType data;
    struct StackNode *next;
}StackNode,*LinkStackPtr;

typedef struct
{
    LinkStackPtr top;
    int count;
}LinkStack;

2.构建一个空链栈

Status InitStack(LinkStack *S)
{
    S->top=NULL;
    S->count=0;
    return 1;
}

3.将链栈置空

Status ClearStack(LinkStack *S){
    LinkStackPtr p,q;
    p = S->top;
    while (p) {
        q = p;
        p = p->next;
        free(q);
    }
    S->count = 0;
    return OK;
    
}

4.判断链栈是否为空

Status StackEmpty(LinkStack S){
    if (S.count == 0)
        return 1;
    else
        return 0;
}

5.求链栈的长度

int StackLength(LinkStack S){
    return S.count;
}

6.获取栈顶元素

Status GetTop(LinkStack S,SElemType *e){
    if(S.top == NULL)
        return 0;
    else
        *e = S.top->data;
    return 1;
}

7.插入元素e为新栈顶元素

Status Push(LinkStack *S, SElemType e){
    
    LinkStackPtr temp = (LinkStackPtr)malloc(sizeof(StackNode));
    temp->data = e;
    temp->next = S->top;
    S->top = temp;
    S->count++;
    return 1;
}

8.删除S栈顶元素,并且打印删除的元素值

Status Pop(LinkStack *S,SElemType *e){
    LinkStackPtr p;
    if (StackEmpty(*S)) {
        return 0;
    }
    
    *e = S->top->data;
    printf("%d ",*e);
    p = S->top;
    S->top= S->top->next;
    free(p);
    S->count--;
    
    return 1;
}

9.遍历栈

Status StackTraverse(LinkStack S){
    LinkStackPtr p;
    p = S.top;
    while (p) {
        printf("%d ",p->data);
        p = p->next;
    }
    printf("\n");
    return OK;
}

五、栈与递归的关系

1.什么时候使用递归

• 定义是递归的
• 数据结构是递归的
• 问题的解法是递归的

2.递归函数调用分析


递归函数调用.png

3.递归过程与递归工作栈


1.png
2.png

3.斐波拉契数列

int Fbi(int i){
    if(i<2)
        return i == 0?0:1;
    return Fbi(i-1)+Fbi(i-2);
}

int main(int argc, const char * argv[]) {
    // insert code here...
    printf("斐波拉契数列!\n");
    // 1 1 2 3 5 8 13 21 34 55 89 144
    for (int i =0; i < 10; i++) {
         printf("%d  ",Fbi(i));
    }
    printf("\n");
   
    return 0;
}

4.Hanoi 塔问题

int m = 0;
void moves(char X,int n,char Y){
    m++;
    printf("%d: from %c ——> %c \n",n,X,Y);
}

//n为当前盘子编号. ABC为塔盘
void Hanoi(int n ,char A,char B,char C){
    //目标: 将塔盘A上的圆盘按规则移动到塔盘C上,B作为辅助塔盘;
    //将编号为1的圆盘从A移动到C上
    if(n==1) moves(A, 1, C);
    else
    {
        //将塔盘A上的编号为1至n-1的圆盘移动到塔盘B上,C作为辅助塔;
        Hanoi(n-1, A, C, B);
        //将编号为n的圆盘从A移动到C上;
        moves(A, n, C);
        //将塔盘B上的编号为1至n-1的圆盘移动到塔盘C上,A作为辅助塔;
        Hanoi(n-1, B, A, C);
    }
}

int main(int argc, const char * argv[]) {
    Hanoi(3, 'A', 'B', 'C');
    printf("盘子数量为3:一共实现搬到次数:%d\n",m);
    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容