特殊线性表——栈(顺序表与链表形式)(C语言)

#include <stdio.h>
#include <stdlib.h>

typedef int E;

/**
 * 顺序表实现栈
 */

struct ArrayStack{
    E * array;  //指向栈底层的数组
    int capacity;  //数组容量
    int top; //top表示栈顶的位置,记录数组的的下标
};

typedef struct ArrayStack * Stack;  //将结构体的指针起别名,Stack

//初始化栈
_Bool initStack(Stack stack){
    stack -> array = malloc(sizeof(E) * 10);  //使用malloc申请10个int大小的内存空间,作为底层数组使用
    if(stack -> array == NULL) return 0;  //处理申请失败
    stack -> capacity = 10;//容量设为10
    stack -> top = -1;  //因为元素是0个,所以top设为-1
    return 1;
}

//入栈
_Bool pushStack(Stack stack,E e){

    //如果增加的元素超过了容量
    if(stack -> top == stack -> capacity - 1){
        //扩容
        int newCapacity = stack -> capacity + (stack -> capacity >> 1);//将容量扩大至其1.5倍
        E * newArray = realloc(stack -> array,sizeof (E) * newCapacity);
        if(stack -> array == NULL) return 0;  //处理申请失败
        stack -> capacity = newCapacity;
        stack -> array = newArray;
    }

    stack -> array[stack -> top + 1] = e;
    stack -> top++;

    return 1;
}

//判断栈是否为空
_Bool isEmptyStack(Stack stack){
    return stack -> top == -1;
}

//出栈
E popStack(Stack stack){
    return stack -> array[stack -> top--];  //直接返回栈顶元素,这里先top,后top--
}


//打印栈(从栈顶开始打印)
void printStackTop(Stack stack){
    int top = stack->top; // 保存栈顶指针的值,设置临时变量!!!切记,如果不设置临时变量,会执行出栈操作
    while(top >= 0){
        printf("%d(%d)\t",stack -> array[top],top);
        top--;
    }
    printf("|");  //表示已打到栈底
    printf("\n");
}

//打印栈(从栈底开始打印)
void printStackBottom(Stack stack){
    printf("|");  //该符号表示栈底
    for(int i = 0;i < stack -> top + 1;i++){
        printf("%d(%d)\t",stack -> array[i],i);
    }
    printf("\n");
}

int main(){
    struct ArrayStack stack;
    int n,m;
    if(initStack(&stack)){
        printf("栈初始化成功!\n");

        //入栈n个元素
        scanf("%d",&n);
        for(int i = 0;i < n;i++){
            pushStack(&stack,(i+1)*10);
        }

        //打印栈
        printStackTop(&stack);
        printStackBottom(&stack);

        //出栈m个元素
        scanf("%d",&m);
        if(m <= n){  //要出栈的元素比总元素个数少或等于
            for(int i = 0; i < m;i++){
                printf("%d ", popStack(&stack));
            }
        }else{  //要出栈的元素大于元素总个数
            while(!isEmptyStack(&stack)){
                printf("%d ", popStack(&stack));
            }
        }

        printf("\n");

        //,出栈之后,打印剩余的栈
        printStackTop(&stack);
        printStackBottom(&stack);

    }
}
# include <stdio.h>
# include <stdlib.h>
typedef int E;

/**
 * 链表实现栈
 */

struct StackNode{
    E e;
    struct StackNode * next;
};

typedef struct StackNode * Stack;

//初始化
_Bool initStack(Stack head){
    head -> next = NULL;
}

//入栈操作
_Bool pushStack(Stack head,E e){

    Stack stack = malloc(sizeof(struct StackNode));
    if(stack == NULL) return 0;   //处理申请失败
     stack -> e = e;
     stack -> next = head -> next;
     head -> next = stack;
     return 1;
}

//判断栈是否为空
_Bool isEmpty(Stack head){
    return head -> next == NULL;  //判断头节点下一个是否为空
}

//出栈操作
E popStack(Stack head){
    Stack top = head -> next;
    head -> next = head -> next -> next;
    E e = top -> e;
    free(top);
    return e;
}

//打印栈(从栈顶开始)
void printStack(Stack head){
     while(head -> next){
         head = head -> next;
         printf("%d ",head -> e);
     }
     printf("|");
     printf("\n");
}

//那么问题来了,如何从栈底开始打印栈呢?
void printStackBottom(Stack head,int n){
    int arr[n],i = 0;
    //将栈中元素存放在数组中
    head = head -> next;  //指向第一个节点
    while(head){
        arr[i] = head -> e;
        head = head -> next;
        i++;
    }
    //此时的i是元素的个数,从i-1下标开始倒序打印
    // 从栈底开始打印栈元素
    printf("|");
    for (int j = i - 1; j >= 0; j--) {
        printf("%d ", arr[j]);
    }
    printf("\n");
}

int main(){
    int n,m;
    struct StackNode head;
    if(initStack(&head)){
        printf("初始化成功!\n");

        //n个元素入栈
        scanf("%d",&n);
        for(int i = 0;i < n;i++){
            pushStack(&head,(i+1)*10);
        }
        //打印栈
        printStack(&head);
        //打印栈(从栈底)
        printStackBottom(&head,n);
        //m个元素出栈
        scanf("%d",&m);
        if(m <= n){  //要出栈的元素比总元素个数少或等于
            for(int i = 0;i < m;i++){
                printf("%d ",popStack(&head));
            }
        }else{  //要出栈的元素大于元素总个数,则全部出栈
            while(!isEmpty(&head)){
                printf("%d ",popStack(&head));
            }
        }
        printf("\n");
        //打印出栈之后,栈的剩余元素
        printStack(&head);
        //打印栈(从栈底)
        printStackBottom(&head,n-m);
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 16
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值