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

来源:互联网 发布:好看的男士手套知乎 编辑:程序博客网 时间:2024/05/17 04:19

我们都知道,一个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操作的数组越界问题)会影响栈的执行效率。在很多程序编写中,往往会省略错误检查,但是我们应该养成随时编写错误检测代码的好习惯。

 

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

原创粉丝点击