栈的链式存储结构

来源:互联网 发布:python split去掉空格 编辑:程序博客网 时间:2024/05/15 23:50

栈的链式存储简称链栈。

在链栈中将链表的头指针和栈顶指针合二为一。

 

对于链栈来说基本不存在栈满的情况,除非内存以及没有可用空间。对于空栈来说链表原定义是头指针指向空,那么链栈的空其实就是top==NULL的时候。

一、结构

typedef int SElemType;//此处可能是个结构体,练习使用int型足够了

 

typedef struct stacknode{         SElemTypedata;         structstacknode * next;}StackNode,* LinkStack;

二、栈的链式存储进栈操作

进栈操作,假设元素值为e新结点是s,top为栈顶指针则进栈操作如下:


算法思路:

1.      分配一个节点s;

2.      将结点值赋值给s->data;

3.      把当前栈顶元素赋值给新结点的直接后继;

4.      将新结点p赋值给栈顶。

三、栈的链式存储出栈操作


出栈操作,假设变量p用来存储要删除的栈顶结点,将栈顶指针下移一位,最后释放p即可。

算法思路:

1.      检查是否是空栈,空栈则返回;

2.      获取栈顶元素,将栈顶赋值给p;

3.      使得栈顶指针下移一位;

4.      释放p

四、时间复杂度

没有任何循环,时间复杂度都是O(1)。

对比一下顺序栈与链栈的时间复杂度均为O(1);空间复杂度上顺序栈需要提前分配一个固定的长度,可能会造成空间的浪费,但是它的优势是存取时候方便,并且链栈要求每个元素都有指针域,这同时也增加了一些内存开销,但是对于栈的长度无限制。所以链栈和顺序栈的区别和线性表中的讨论是一样的:如果栈的使用过程中元素变化不可预料,有时候很小,有时候非常大,那么最好使用链栈,反之,如果它的变化在可控范围内,建议使用顺序栈会更好一些。

五、代码示例

#include <stdio.h>#include <string.h>#include <malloc.h>#define ERROR -1#define OK 0typedef int SElemType;//此处可能是个结构体,练习使用int型足够了typedef struct stacknode{SElemType data;struct stacknode * next;}StackNode,* LinkStack;//判栈空int StackEmpty(LinkStack top){if(top->next==NULL){return 1;}else{return 0;}}//入栈函数LinkStack Push(LinkStack top,SElemType e){    StackNode * p = (StackNode *)malloc(sizeof(StackNode));    if(p != NULL)    {        p->data=e;        p->next=top->next;//把当前栈顶元素赋值给新结点的直接后继        top->next=p;//将新结点p赋值给栈顶    }    else    {        printf("分配结点失败\n");    }    return top;}//出栈函数int Pop(LinkStack top){StackNode * p;SElemType t;if(StackEmpty(top)){printf("空栈\n");}else{p = top->next;//将栈顶赋值给pt = p->data;top->next = p->next;//使得栈顶指针下移一位free(p);}return t;}//打印函数void PrintStack(LinkStack top){    if(top->next==NULL)    {printf("空栈\n");    }    else    {        while(top->next!=NULL)        {printf("元素:%d\n",top->next->data);            top=top->next;        }    }}//取栈顶元素int StackTop(LinkStack top){if(StackEmpty(top)){printf("空栈\n");}return top->next->data;}//栈的长度int StackLen(LinkStack top){    int len=0;while(top->next!=NULL){len++;top=top->next;}    return len;}//销毁栈void DestroyStack(LinkStack top){LinkStack q;while(top){q=top->next;free(top);top=q;}printf("销毁成功");}//栈初始化void InitStack(LinkStack top){    top->next=NULL;}int main(){int i = 0;    LinkStack top;    top = (LinkStack)malloc(sizeof(StackNode));    //注意printf("\n=======初始化操作=========\n");InitStack(top);    printf("\n=======入栈操作=========\n");    for(i = 0;i<10;i++)    {        Push(top,i);    //入栈    }printf("栈大小:%d\n",StackLen(top));printf("\n=======打印栈信息=========\n");    PrintStack(top);    //打印栈printf("\n=======出栈操作=========\n");    if(top->next!=NULL)//出栈    {printf("出栈元素::%d\n",Pop(top));}else{printf("空栈\n");}printf("\n=======取栈顶元素=========\n");if(StackEmpty(top)==1)//取栈顶元素    {printf("空栈\n");}else    {printf("栈顶元素:%d\n",StackTop(top));}printf("\n=======判断栈是否为空=========\n");if(StackEmpty(top)==1)//判断栈是否为空    {printf("空栈\n");}else    {printf("不是空栈\n");}printf("\n=======返回栈的元素个数=========\n");if(StackEmpty(top)==1)//返回栈的元素个数    {printf("空栈\n");}else{printf("栈大小:%d\n",StackLen(top));}printf("\n=======销毁栈=========\n");DestroyStack(top);    return 0;}


原创粉丝点击