C 语言 栈的循序存储结构

/*
  栈的循序存储结构
  声明一段连续的地址
  地址的 top - base 就是当前栈中数据的个数
*/

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

#define STACK_INIT_SIZE 20
#define STACKINCREAMENT 10

typedef char DataType;

typedef struct {
  DataType *base;
  DataType *top;
  int stackSize;
}strStack;

void initStack(strStack *stack){
  stack->base = (DataType *)malloc(STACK_INIT_SIZE * sizeof(DataType));
  if(!stack->base){
    exit(0);
  }

  stack->top = stack->base;
  stack->stackSize = STACK_INIT_SIZE;
}

//
void printStrack(strStack *stack){
  DataType *newBase;
  newBase = stack->base;

  while(newBase != stack->top){
    printf("%c ->", *newBase);
    newBase++;
  }
  printf("\n");
}

// 压栈
strStack *Push(strStack *stack, DataType data){
  if(stack->top - stack->base >= STACK_INIT_SIZE){
    int baseLength = stack->top - stack->base;

    stack->base = (DataType *)realloc(stack->base, (stack->stackSize + STACKINCREAMENT) * sizeof(DataType));
    if(!stack->base){
      exit(0);
    }
    stack->stackSize = stack->stackSize + STACKINCREAMENT;
    stack->top = stack->base + baseLength;
  }

  *(stack->top) = data; //当前Top地址指向的数据
  stack->top++; // 当前的Top执行的地址 + 1

  return stack;
}

// 出栈
strStack *Pop(strStack *stack, DataType *data){
  int popStart, incrRate;
  if(stack->top == stack->base){
    return stack;
  }

  // 开始需要额外增加
  if (stack->top - stack->base <= STACK_INIT_SIZE){
    popStart = 0;
  }else{
    popStart = (stack->top - stack->base - STACK_INIT_SIZE) / STACKINCREAMENT + 1;
  }

  *data = *--(stack->top);

  // 结束需要额外增加
  if (stack->top - stack->base <= STACK_INIT_SIZE){
    incrRate = 0;
  }else{
    incrRate = (stack->top - stack->base - STACK_INIT_SIZE) / STACKINCREAMENT + 1;
  }

  // 重新去计算栈的大小,这样会节约空间吧,不会因为一个栈声明的空间很大,但是存储的数据很小
  if(popStart != incrRate){
    int baseLength = stack->top - stack->base;

    stack->base = (DataType *)realloc(stack->base, (STACK_INIT_SIZE + STACKINCREAMENT * incrRate) * sizeof(DataType));
    if(!stack->base){
      exit(0);
    }
    stack->stackSize = STACK_INIT_SIZE + STACKINCREAMENT * incrRate;
    stack->top = stack->base + baseLength;
  }

  printStrack(stack);
  return stack;
}

int stackLength(strStack *stack){
  return (stack->top - stack->base);
}

// 初始化栈
void reintStack(strStack *stack){
  stack->top = stack->base;
  stack->stackSize = STACK_INIT_SIZE;
}

// 键盘输入
strStack *screenPop(strStack *stack){
  char data;

  printf("输入字符,回车结束: ");
  while(1){
    scanf("%c", &data);

    if(data == '\n'){
      fflush(stdin);
      return stack;
    }
    printf("正在Push--%c\n", data);
    stack = Push(stack, data);
  }
  fflush(stdin);

  return stack;
}

int main(int argc, char const *argv[])
{
  DataType c;
  strStack *stack;
  char oprator, *popData;

  stack = (strStack *)malloc(sizeof(strStack));
  initStack(stack);

  printf("A: 入栈\n");
  printf("B: 出栈\n");
  printf("C: 计算栈大小\n");
  printf("D: 清空栈\n");
  printf("E: 打印栈数据\n");
  printf("Q: 退出\n");
  while(1){
    printf("-----------------输入操作: ");
    scanf("%c", &oprator);
    getchar();

    switch(oprator){
      case 'A':
        stack = screenPop(stack);
        break;
      case 'B':
        stack = Pop(stack, popData);
        break;
      case 'C':
        printf("当前栈容量是: %d\n", stack->stackSize);
        printf("当前栈的大小是: %d\n", stackLength(stack));
        break;
      case 'D':
        reintStack(stack);
        break;
      case 'E':
        printStrack(stack);
        break;
      case 'Q': exit(0);
    }
    fflush(stdin);
  }

  printf("\n");
  return 0;
}

 

上一篇:ajax 跳入error的一些原因


下一篇:MySQL DataType--浮点数(Floating-Point Types)学习