栈的链式实现(C语言描述)
2015-08-28 20:01
567 查看
原文地址:/article/1331748.html /article/1337345.html
栈本质上是一个线性表,只不过对线性表的操作进行了限制,只可以在表的一端进行操作(插入、删除元素)。栈是一种是一种实现数据“先进后出”的存储结构,分为静态栈和动态栈,静态栈就是以数组的方式存储数据,动态栈是以链表的方式存储数据;对栈的操作算法,常用的就是压栈和出;下面将以链式的方式创建栈,并对用c语言实现栈的压栈和出栈的算法:
[cpp] view
plaincopy
![](https://code.csdn.net/assets/CODE_ico.png)
![](https://code.csdn.net/assets/ico_fork.svg)
typedef int elementype;
//定义一个节点
typedef struct Node
{
elementype data;
struct Node *pNext;
}NODE,*PNODE;//
//构造一个栈
typedef struct stack
{
PNODE pTop; //栈顶指针
PNODE pBottom;//栈底指针
}STACK,*PSTACK;
其中,使用了typedef关键词,typedef只是给一个数据类型提供一个别名;因此这里的NODE=struct Node ,PNODE=struct Node *;同样,STACK=struct stack ,PSTACK=struct Node *;
此时,数据类型构造出来了,接下来要创建一个空栈,这样我们才能进行栈的操作,创建栈,无非就是分配内存,内存分配有三种方式,静态存储区,栈,堆;
[cpp] view
plaincopy
![](https://code.csdn.net/assets/CODE_ico.png)
![](https://code.csdn.net/assets/ico_fork.svg)
//创建一个空栈,里面没有任何有效数据;
void Create_Stack(PSTACK S)
{
S->pBottom=(struct Node *)malloc(sizeof(struct Node));
if(NULL==S->pBottom)
{
printf("Memory allocation failure");
exit(-1);
}
S->pTop=S->pBottom;
S->pTop->data=0;
S->pTop->pNext=NULL; //防止出现野指针
}
![](http://img.blog.csdn.net/20140307094002218?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbHBwMDkwMDMyMDEyMw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图1 空栈示意图
![](http://img.blog.csdn.net/20140307094207750?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbHBwMDkwMDMyMDEyMw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图2 压栈算法示意图
压栈的伪算法:
(1).创建一个节点p,并修改节点的指针域使其指向栈顶数据元素;p->pNext=pTop;
(2)修改栈顶指针,使其指向栈顶元素,pTop=p;
程序代码:
[cpp] view
plaincopy
![](https://code.csdn.net/assets/CODE_ico.png)
![](https://code.csdn.net/assets/ico_fork.svg)
//进栈
void Push_Stack(PSTACK S,int val)
{
PNODE p=(struct Node *)malloc(sizeof(struct Node));
if(NULL==p)
{
printf("Memory allocation failure");
exit(-1);
}
p->data=val;
p->pNext=S->pTop; //让p的指针域指向上一个节点
S->pTop=p; //让pTop指针指向栈顶元素
}
![](http://img.blog.csdn.net/20140307094642187?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbHBwMDkwMDMyMDEyMw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图3.出栈算法示意图
出栈伪算法:
(1).先用P指针保存要删除数据的地址,用于便于释放此节点的内存,即p=pTop;
(2).修改栈顶指针的指向,使其指向栈顶元素;pTop=pTop->pNext;
plaincopy
![](https://code.csdn.net/assets/CODE_ico.png)
![](https://code.csdn.net/assets/ico_fork.svg)
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
typedef struct Node
{
int data;
struct Node *pNext;
}NODE,*PNODE;
typedef struct Stack
{
PNODE pTop;
PNODE pBottom;
}STACK,*PSTACK;
PSTACK create_stack();
void push_stack(PSTACK,int);
void traverse_stack(PSTACK);
bool pop_stack(PSTACK,int *);
bool is_empty(PSTACK);
void clear_stack(PSTACK);
int main()
{
int data_pop;
//创建一个空的栈,pS指针指向该栈
PSTACK pS = create_stack();
//向该栈中压入数据,遍历该栈并输出栈中的数据
push_stack(pS,2);
push_stack(pS,6);
push_stack(pS,28);
traverse_stack(pS);
//从该栈中推出数据,遍历该栈并输出栈中的数据
if(pop_stack(pS,&data_pop))
printf("pop succeed,the data poped out is:%d\n",data_pop);
else
printf("pop failed\n");
traverse_stack(pS);
//清空栈,遍历该栈并输出栈中的数据
clear_stack(pS);
printf("data cleared!\n");
traverse_stack(pS);
return 0;
}
//创建一个空栈,并返回指向该栈的指针
PSTACK create_stack()
{
PSTACK pS = (PSTACK)malloc(sizeof(STACK));
pS->pTop = (PNODE)malloc(sizeof(NODE));
if(NULL==pS || NULL==pS->pTop)
{
printf("malloc failed");
exit(-1);
}
else
{
pS->pBottom = pS->pTop;
pS->pBottom->pNext = NULL;
}
return pS;
}
//判断该栈是否为空
bool is_empty(PSTACK pS)
{
if(pS->pTop == pS->pBottom)
return true;
else
return false;
}
//向pS指针指向的栈中压入数据val
void push_stack(PSTACK pS,int val)
{
PNODE pNew = (PNODE)malloc(sizeof(NODE));
if(NULL==pNew)
{
printf("malloc failed");
exit(-1);
}
else
{
pNew->data = val;
pNew->pNext = pS->pTop;
pS->pTop = pNew;
}
return ;
}
//从栈中推出数据,并将推出的数据保存在pData指针所指向的位置
bool pop_stack(PSTACK pS,int *pData)
{
if(is_empty(pS))
return false;
else
{
PNODE p = pS->pTop;
*pData = p->data;
pS->pTop = p->pNext;
free(p);
p = NULL;
return true;
}
}
//遍历栈,并自栈顶向栈底输出栈中的数据
void traverse_stack(PSTACK pS)
{
PNODE pCurrent = pS->pTop;
printf("Now datas int the stack are:\n");
while(pCurrent != pS->pBottom)
{
printf("%d ",pCurrent->data);
pCurrent = pCurrent->pNext;
}
printf("\n");
return ;
}
//清空栈,即将其还原为空栈
void clear_stack(PSTACK pS)
{
if(is_empty(pS))
return ;
PNODE p = NULL;
while(pS->pTop
!= pS->pBottom)
{
p = pS->pTop;
pS->pTop = p->pNext;
free(p);
p = NULL;
}
}
栈本质上是一个线性表,只不过对线性表的操作进行了限制,只可以在表的一端进行操作(插入、删除元素)。栈是一种是一种实现数据“先进后出”的存储结构,分为静态栈和动态栈,静态栈就是以数组的方式存储数据,动态栈是以链表的方式存储数据;对栈的操作算法,常用的就是压栈和出;下面将以链式的方式创建栈,并对用c语言实现栈的压栈和出栈的算法:
1.栈的创建
在创建一个数据结构之前,必须知道这种数据结构由哪些参数组成,栈的本质既然是个链表,它必然由很多节点组成;为了实现“先进后出”这种数据结构,我们需要引进两个参数,一个是栈顶指针(pTop),始终指向栈顶元素。一个参数是栈底指针(pBottom),始终指向栈底元素。我们知道为了方便描述链表的各种操作,引进了头节点的概念,即为每个链表前面加一个头节点,但并存放有效数据;同样,为了实现栈的操作,我们同样需要一个不存放任何有效数据的节点,并且栈底指针始终指向该节点;[cpp] view
plaincopy
![](https://code.csdn.net/assets/CODE_ico.png)
typedef int elementype;
//定义一个节点
typedef struct Node
{
elementype data;
struct Node *pNext;
}NODE,*PNODE;//
//构造一个栈
typedef struct stack
{
PNODE pTop; //栈顶指针
PNODE pBottom;//栈底指针
}STACK,*PSTACK;
其中,使用了typedef关键词,typedef只是给一个数据类型提供一个别名;因此这里的NODE=struct Node ,PNODE=struct Node *;同样,STACK=struct stack ,PSTACK=struct Node *;
此时,数据类型构造出来了,接下来要创建一个空栈,这样我们才能进行栈的操作,创建栈,无非就是分配内存,内存分配有三种方式,静态存储区,栈,堆;
[cpp] view
plaincopy
![](https://code.csdn.net/assets/CODE_ico.png)
//创建一个空栈,里面没有任何有效数据;
void Create_Stack(PSTACK S)
{
S->pBottom=(struct Node *)malloc(sizeof(struct Node));
if(NULL==S->pBottom)
{
printf("Memory allocation failure");
exit(-1);
}
S->pTop=S->pBottom;
S->pTop->data=0;
S->pTop->pNext=NULL; //防止出现野指针
}
图1 空栈示意图
2.压栈算法
图2 压栈算法示意图
压栈的伪算法:
(1).创建一个节点p,并修改节点的指针域使其指向栈顶数据元素;p->pNext=pTop;
(2)修改栈顶指针,使其指向栈顶元素,pTop=p;
程序代码:
[cpp] view
plaincopy
![](https://code.csdn.net/assets/CODE_ico.png)
//进栈
void Push_Stack(PSTACK S,int val)
{
PNODE p=(struct Node *)malloc(sizeof(struct Node));
if(NULL==p)
{
printf("Memory allocation failure");
exit(-1);
}
p->data=val;
p->pNext=S->pTop; //让p的指针域指向上一个节点
S->pTop=p; //让pTop指针指向栈顶元素
}
3.出栈算法
图3.出栈算法示意图
出栈伪算法:
(1).先用P指针保存要删除数据的地址,用于便于释放此节点的内存,即p=pTop;
(2).修改栈顶指针的指向,使其指向栈顶元素;pTop=pTop->pNext;
附录:程序代码
[cpp] viewplaincopy
![](https://code.csdn.net/assets/CODE_ico.png)
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
typedef struct Node
{
int data;
struct Node *pNext;
}NODE,*PNODE;
typedef struct Stack
{
PNODE pTop;
PNODE pBottom;
}STACK,*PSTACK;
PSTACK create_stack();
void push_stack(PSTACK,int);
void traverse_stack(PSTACK);
bool pop_stack(PSTACK,int *);
bool is_empty(PSTACK);
void clear_stack(PSTACK);
int main()
{
int data_pop;
//创建一个空的栈,pS指针指向该栈
PSTACK pS = create_stack();
//向该栈中压入数据,遍历该栈并输出栈中的数据
push_stack(pS,2);
push_stack(pS,6);
push_stack(pS,28);
traverse_stack(pS);
//从该栈中推出数据,遍历该栈并输出栈中的数据
if(pop_stack(pS,&data_pop))
printf("pop succeed,the data poped out is:%d\n",data_pop);
else
printf("pop failed\n");
traverse_stack(pS);
//清空栈,遍历该栈并输出栈中的数据
clear_stack(pS);
printf("data cleared!\n");
traverse_stack(pS);
return 0;
}
//创建一个空栈,并返回指向该栈的指针
PSTACK create_stack()
{
PSTACK pS = (PSTACK)malloc(sizeof(STACK));
pS->pTop = (PNODE)malloc(sizeof(NODE));
if(NULL==pS || NULL==pS->pTop)
{
printf("malloc failed");
exit(-1);
}
else
{
pS->pBottom = pS->pTop;
pS->pBottom->pNext = NULL;
}
return pS;
}
//判断该栈是否为空
bool is_empty(PSTACK pS)
{
if(pS->pTop == pS->pBottom)
return true;
else
return false;
}
//向pS指针指向的栈中压入数据val
void push_stack(PSTACK pS,int val)
{
PNODE pNew = (PNODE)malloc(sizeof(NODE));
if(NULL==pNew)
{
printf("malloc failed");
exit(-1);
}
else
{
pNew->data = val;
pNew->pNext = pS->pTop;
pS->pTop = pNew;
}
return ;
}
//从栈中推出数据,并将推出的数据保存在pData指针所指向的位置
bool pop_stack(PSTACK pS,int *pData)
{
if(is_empty(pS))
return false;
else
{
PNODE p = pS->pTop;
*pData = p->data;
pS->pTop = p->pNext;
free(p);
p = NULL;
return true;
}
}
//遍历栈,并自栈顶向栈底输出栈中的数据
void traverse_stack(PSTACK pS)
{
PNODE pCurrent = pS->pTop;
printf("Now datas int the stack are:\n");
while(pCurrent != pS->pBottom)
{
printf("%d ",pCurrent->data);
pCurrent = pCurrent->pNext;
}
printf("\n");
return ;
}
//清空栈,即将其还原为空栈
void clear_stack(PSTACK pS)
{
if(is_empty(pS))
return ;
PNODE p = NULL;
while(pS->pTop
!= pS->pBottom)
{
p = pS->pTop;
pS->pTop = p->pNext;
free(p);
p = NULL;
}
}
相关文章推荐
- 【C语言连载六】--------变量、修饰词、结构体、枚举、typedef
- 【C语言连载五】--------指针
- C++静态成员函数小结(转)
- Prototype 模式示例代码 (C++)
- C语言中的内部名和外部名
- LeetCode-Single Number-解题报告
- 转:C++字符串系列
- C++进阶学习指引
- 学习心得:链表的操作(C语言实现)
- 作业《IOS_C语言》进制,C数据类型,常量类型,运算符,表达式,格式化输入输出
- 通俗易懂学C语言-02-C语言程序长啥样以及运行流程
- 关于C++中的友元函数的总结
- c++设计模式15 --组合模式
- C++ Builder 将数据库数据导出到Excel中总结2
- C++插件管理器
- 对比C语言中getc()函数和ungetc()函数的使用
- 指针与引用(C++)
- 指针与引用(C++)
- LeetCode:Power of Two
- c语言之无符号/有符号数加减法运算