栈的概念及实现

       栈是一种先入后出(后入先出)的数据结构,栈的这种性质被用于很多场景,如代码编译、代码语法检查、函数调用等。

栈的实现方式有两种:用链表实现、用数组实现

一.链表实现

    看过几本数据结构的书如《Data Structures and Algorithm Analysis in C》与《C Primer Plus》,也可能是由于写惯了Java代码,总是感觉书中的代码抽象的力度不够,所以自己实现了一下,与他们的实现相比略显拖沓,不过我认为抽象与封装的重要性比简洁性更重要。

    以链表的形式实现,Stack持有一个header指针,每次push都将header的next指针指向新创建的节点,所以栈顶节点就是header->next,代码如下:

头文件:

  

#ifndef _Stack_H
#define _Stack_H
/*
 *以链表的方式实现栈
 */
/*栈节点结构体*/
struct NodeStruct;
/*栈结构体*/
struct StackStruct;
/*栈节点结构体存储的元素数据类型*/
typedef int ElementType;
/*栈节点结构体指针*/
typedef struct NodeStruct *PtrToNode;
/*栈结构体指针*/
typedef struct StackStruct *PtrToStack;
/*栈节点*/
typedef PtrToNode Node;
/*栈*/
typedef PtrToStack Stack;
/*初始化一个栈*/
Stack initStack();
/*push元素*/
void push(Stack stack,ElementType element);
/*返回栈顶元素,栈为空时返回NULL*/
Node top(Stack stack);
/*栈顶元素出栈*/
void pop(Stack stack);
/*销毁栈*/
void destoryStack(Stack stack);
/*打印栈结构*/
void printStack(Stack stack);
/**/
struct NodeStruct{
  ElementType element;
  Node next;
};
/**/
struct StackStruct{
  Node header;
  int size;
};

#endif

实现文件:

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

Stack initStack(){
     Stack stack;
     Node header;
     header = malloc(sizeof(struct NodeStruct));
     header->next = NULL;
     stack = malloc(sizeof(struct StackStruct));
     stack->header = header;
     stack->size = 0;
}

void push(Stack stack,ElementType element){
   Node header,topNode,newNode; 
   header= stack->header;
   topNode = header->next;
   newNode = malloc(sizeof(struct NodeStruct));
   newNode->element = element;
   newNode->next = topNode;
   header->next = newNode;
   stack->size++;
}


Node top(Stack stack){
   Node header, topNode;
   header = stack->header;
   topNode = header->next;
   return topNode;
}

void pop(Stack stack){
   Node header,topNode;
   header = stack->header;
   topNode = top(stack);
   if(topNode != NULL){
      header->next = topNode->next;
      stack->size--;
      free(topNode);
      topNode = NULL;
   }   
}

void destoryStack(Stack stack){
  Node header,topNode,temp;
  header = stack->header;
  topNode = header->next;
  while(topNode != NULL){
     temp = topNode->next;
     free(topNode);
     topNode = temp;
  }
  free(header);
  header = NULL;
  free(stack);
  stack = NULL;
}

void printStack(Stack stack){
  Node header,topNode;
  header = stack->header;
  topNode = header->next;
  printf("[");
  while(topNode != NULL){
     printf("%d,",topNode->element);
     topNode = topNode->next; 
  }
  if(stack->size > 0){
    printf("\b]\n");
  }else{
    printf("]\n");
  }
}

以上代码在以下环境中编译并测试通过:

线程模型:posix
gcc 版本 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) 

二.以数组实现

   以数组实现也很简单,我们之需要初始化一个固定大小的数组,并以一个变量topOfStack记录栈顶元素在数组中的下标即可,push元素时需要check一下栈是否满了,当然我们可以实现栈可扩展;pop时需要将topOfStack递减,以保证该值可以从数组中索引某个元素作为栈顶元素。

 头文件

#ifndef _Array_Stack
 /*声明栈结构体*/
 struct StackStruct;
 /*定义栈存储元素的类型*/
 typedef int ElementType;
 /*定义栈结构体指针*/
 typedef struct StackStruct *PtrToStack;
 /*定义栈*/
 typedef PtrToStack Stack;
 /*初始化一个栈,capacity为栈初始大小*/
 Stack initStack(int capacity);
 /*push元素*/
 void push(Stack stack,ElementType element);
 /*返回栈顶元素*/
 ElementType top(Stack stack);
 /*栈顶元素出栈*/
 ElementType pop(Stack stack);
 /*销毁栈*/
 void destoryStack(Stack stack);
 /*打印栈结构*/
 void printStack(Stack stack);

#endif

实现

#include <stdio.h>
#include <stdlib.h>
#include "arraystack.h"
//定义栈默认大小
#define DefaultCapacity ( 100 )
//定义栈结构体
struct StackStruct{
   int size;
   int capacity;
   int topOfStack;
   ElementType *array;
};

Stack initStack(int capacity){
  Stack stack;
  if(capacity > DefaultCapacity)
      capacity = DefaultCapacity;
  stack = malloc(sizeof(struct StackStruct));
  if(stack == NULL){
    fprintf(stderr,"%s\n","OutOfMemory!");
    exit(1);
  }
  stack->size = 0;
  stack->capacity = capacity;
  stack->array = malloc(sizeof(ElementType)*capacity);
  stack->topOfStack = -1;
  if(stack->array == NULL){
    fprintf(stderr,"%s\n","OutOfMemory!");
    exit(1);
  }
  return stack;
}

void push(Stack stack,ElementType element){
  //stack is full
  if(stack->size == stack->capacity){
      return;
  }
  stack->array[++stack->topOfStack] = element;
  stack->size++;
}

ElementType top(Stack stack){
  ElementType result;
  result =  stack->array[stack->topOfStack];
  return result;
}

ElementType pop(Stack stack){
  ElementType result;
  result = top(stack);
  stack->topOfStack--;
  return result;
}

void destoryStack(Stack stack){
  if(stack == NULL)
     return;
  free(stack->array);
  stack->array = NULL;
  free(stack);
  stack = NULL;
}

void printStack(Stack stack){
  if(stack == NULL || stack->size ==0)
     return;  
  int index;
  for(index = stack->topOfStack;index >= 0;index--){
     printf("|_%d_|\n",stack->array[index]);
  }
  printf("stack info >>{[capacity:%d],[size:%d],[topOfStack:%d]}\n",
           stack->capacity,stack->size,stack->topOfStack);
}

          


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值