数据结构与算法分析学习笔记二-栈的C语言实现

我们都知道,一个C/C++编译的程序中的一些局部变量,函数的参数值等都是放在栈里面的。虽说数据结构中的栈和内存中的栈并不完全相同,但是还是有相似点的。所以今天学习的内容就是数据结构中,如何来创建栈,如何进行数据的压入和压出,如何释放栈等等。本文主要介绍两种实现方法:1. 栈的链表实现;2. 栈的数组实现。直接看代码吧。(本文中所有的程序在anycodes.tk在线编程网站上测试通过)

 

1. 栈的链表实现

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
//struct Node;
//struct Stack;
//typedef struct Node* ptrToNode;
//typedef struct Stack* pStack;

typedef struct node
{
    int element;
    struct node * next;
}Node, *ptrToNode;

typedef struct stack
{
    ptrToNode top;          //栈顶
    ptrToNode bottom;       //栈底
}Stack,*pStack;

//创建链表
void createStack(pStack ptrStack)
{
    ptrStack -> top = (ptrToNode)malloc(sizeof(Node));  //分配空间
    if (ptrStack == NULL)
    {
        printf("Out of space!\n");       //分配空间失败
        exit(1);
    }
    ptrStack -> bottom = ptrStack -> top;         //使栈底元素指向栈顶元素
    ptrStack -> top -> next = NULL;           //使栈顶元素下一个元素指向空
}

void push(pStack ptrStack, int ele)
{
    ptrToNode temp = (ptrToNode)malloc(sizeof(Node));        //创建一个临时的节点
    if (temp == NULL)
    {
        printf("Out of space!\n");          //分配内存空间失败
        exit(1);
    }
    temp -> element = ele;              //先确定新的指针,后修改旧的指针
    temp -> next = ptrStack -> top;      //新指针先指向栈顶
    ptrStack -> top = temp;              //修改栈顶指向新push进来的节点
}

int isEmpty(pStack ptrStack)
{
    return ptrStack->top->next == NULL;
}

int top(pStack ptrStack)
{
    if(isEmpty(ptrStack))
    {
        printf("Sorry, the stack is blank!\n");
        exit(1);
    }
    return ptrStack -> top -> element;
}

void pop(pStack ptrStack)
{
    ptrToNode temp;
    if(!isEmpty(ptrStack))
    {
        printf("Sorry, the stack is blank!\n");
        exit(1);
    }
    temp = ptrStack -> top;
    ptrStack -> top = ptrStack -> top -> next;
    free(temp);
}

void printStack(pStack ptrStack)
{
    ptrToNode temp = ptrStack -> top;
    printf("The element in the stack from top to bottom is : \n");
    while(temp != ptrStack -> bottom)
    {
        printf("%d ",temp -> element);
        temp = temp -> next;
    }
    printf("\n");
}

int main()
{
    int a[3] = {12,4354,657};
    int i = 0;
    int topElement = 0;
    Stack s;
    createStack(&s);             //创建栈
    for (; i < 3; i++)
    {
        push(&s, a[i]);         //进栈
    }
    printStack(&s);
    topElement = top(&s);       //print the top element in the stack
    printf("The top element is %d\n",topElement);        
    pop(&s);               
    printStack(&s);
    return 0;
}


anycodes(anycodes.tk) 在线编程网站上的测试结果:

 

2.栈的数组实现

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

struct Stack;
typedef struct Stack *pStack;
struct Stack
{
    int Capacity;
    int TopofStack;
    int *Array;
};


#define MinStack -1
#define EmptyTOS -1

//创建链表
void createStack(pStack ptrStack, int EleNum)
{
    if(EleNum < MinStack)
    {
        printf("Sorry, the length of the stack is to small!\n");
        exit(1);
    }
//    ptrStack  = malloc(sizeof(struct Stack));  //给栈结构体分配空间
    if (ptrStack == NULL)
    {
        printf("Out of space!\n");       //分配空间失败
        exit(1);
    }
    ptrStack -> Array = malloc(sizeof(int)*EleNum);      //给数组分配空间
    if (ptrStack -> Array == NULL)
    {
        printf("Out of space!\n");       //分配空间失败
        exit(1);
    }
    ptrStack -> Capacity = EleNum;
    ptrStack -> TopofStack = EmptyTOS;
}

int isFull(pStack ptrStack)
{
    return ptrStack -> TopofStack == ptrStack -> Capacity -1;
}

void push(pStack ptrStack, int ele)
{
    if(isFull(ptrStack))
    {
        printf("Sorry, the stack is full!\n");
        exit(1);
    }
    ptrStack -> TopofStack = ptrStack -> TopofStack + 1;
    ptrStack -> Array[ptrStack->TopofStack] = ele;
}

int isEmpty(pStack ptrStack)
{
    return ptrStack -> TopofStack == EmptyTOS;
}

int top(pStack ptrStack)
{
    if(isEmpty(ptrStack))
    {
        printf("Sorry, the stack is blank!\n");
        exit(1);
    }
    return ptrStack -> Array[ptrStack -> TopofStack];
}

void pop(pStack ptrStack)
{
    if(isEmpty(ptrStack))
    {
        printf("Sorry, the stack is blank!\n");
        exit(1);
    }
    ptrStack -> TopofStack--;
}

void printStack(pStack ptrStack)
{
    int i = ptrStack -> TopofStack;
    printf("The element in the stack from top to bottom is : \n");
    while(i >= 0)
    {
        printf("%d ",ptrStack -> Array[i--]);
    }
    printf("\n");
}

void freeStack(pStack ptrStack)
{
	free(ptrStack -> Array);
	free(ptrStack);
}

int main()
{
    int a[3] = {12,4354,657};
    int i = 0;
    int topElement = 0;
    pStack s;
    s = malloc(sizeof(struct Stack));
    createStack(s,3);             //创建栈
    for (; i < 3; i++)
    {
        push(s, a[i]);         //进栈
    }
    printStack(s);
    topElement = top(s);       //print the top element in the stack
    printf("The top element is %d\n",topElement);        
    pop(s);               
    printStack(s);
    freeStack(s);
    return 0;
}

anycodes(anycodes.tk) 在线编程网站上的测试结果:

 

3. 两种实现方法的性能比较

链表的实现方法的所有的操作都花费常数时间,但是这种方法的缺点在于对malloc和free的调用的开销是安规的,特别是与指针操作的例程相比尤其如此。相比而言,数组的实现方法不仅以常数时间运行,而且是以非常快的常数时间运行。在某些极其上,若在带有自增和自减的寻址功能的寄存器上操作,则Push和Pop都可以写成一条机器指令。但是错误检测(如检测栈空下的Pop和栈满下的Push操作的数组越界问题)会影响栈的执行效率。在很多程序编写中,往往会省略错误检查,但是我们应该养成随时编写错误检测代码的好习惯。

 

欢迎大牛留言,进行批评与指正。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值