最近开始复习了一下数据结构的内容,这才发现,以前的半懂不懂,今天终于有机会可以好好的研究下来。下面这段代码是我自己写的链式栈的实现,其中总结了很多我所碰到的问题,比如结构多重指针参数的操作,malloc函数使用,typedef使用等等。
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
链式栈实现/*
** 链表堆栈的实现
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// 定义堆栈类型
typedef int STACK_TYPE;
/*
** 定义链表堆栈结构数据结构
**
*/
typedef struct STACK_NODE
{
STACK_TYPE value;
//unsigned int top, base; 也可以定义带额外标志的栈结构
struct STACK_NODE *next;
}StackNode, *LStack;
// 创建堆栈带有n个节点
void Create_Stack(LStack *L, int n)
{
LStack p = (LStack)malloc(sizeof(StackNode));
if(p == NULL)
{
return false;
}
scanf("%d", &p->value);
p->next = NULL;
int i;
for(i = 1; i < n; i++)
{
LStack p1 = (LStack)malloc(sizeof(StackNode));
if(p1 == NULL)
return false;
scanf("%d", &p1->value);
p1->next = p;
p = p1;
}
*L = p;
}
// 销毁堆栈
void Destory_Stack(LStack *L)
{
LStack p1 = (LStack)malloc(sizeof(StackNode));
if(p1 == NULL)
return false;
p1 = *L;
while(p1->next != NULL)
{
*L = p1->next;
free(p1);
p1 = *L;
}
free(*L); //释放×L节点
*L = NULL; //释放后将×L指向NULL 不然成为野指针
}
// 压栈
bool Push(LStack *L, STACK_TYPE value)
{
LStack p = (LStack)malloc(sizeof(StackNode));
if(p == NULL)
{
return false;
}
else
{
p->value = value;
p->next = *L;
*L = p;
}
}
// 出栈
void Pop(LStack *L)
{
LStack p1 = (LStack)malloc(sizeof(StackNode));
if(p1 == NULL)
return false;
p1 = *L;
*L = p1->next;
free(p1);
p1= NULL;
}
// 读栈头结点
STACK_TYPE Top(LStack L)
{
if(L == NULL)
return false;
return L->value;
}
// 判断栈是否为空
bool Is_Empty(LStack L)
{
if(L == NULL)
return true;
else
return false;
}
// 判断栈是否已满
bool Is_Full(LStack L)
{
//
}
//打印栈
void Print_Stack(LStack L)
{
while(L != NULL)
{
printf("%d\n", L->value);
L = L->next;
}
}
int main()
{
int n;
int npush;
bool empty;
STACK_TYPE top;
LStack L;
printf("-----------Create a stack list-----------\n");
printf("Input the number of the nodes:\n");
scanf("%d",&n);
printf("------------------------------------------\n");
Create_Stack(&L, n);
printf("-----------The stack list-----------\n");
Print_Stack(L);
printf("------------------------------------------\n");
printf("-----------Add a node Push()----------------------\n");
printf("Input a number to push:");
scanf("%d", &npush);
Push(&L, npush);
printf("-----------The stack list-----------\n");
Print_Stack(L);
printf("-----------The top value-----------\n");
top = Top(L);
printf("%d\n",top);
printf("-----------Pop a node Pop()-----------\n");
Pop(&L);
printf("-----------The top value after pop.-----------\n");
top = Top(L);
printf("%d\n",top);
printf("-----------Destory list-----------\n");
Destory_Stack(&L);
printf("-----------Is the list empty?(1,true; 0 false)-----------\n");
empty = Is_Empty(L);
printf("%d\n", empty);
return 0;
}
总结几点:
1. 要是想改变传入参数的地址,就必须使用地址传递。在C语言里现在是不支持&作为参数的,都使用指针参数。 在里面*parameter就代表它所代表的结构。
2. 释放指针后,最好将指针指向NULL。
从这个程序还是可以看出有些地方还是不灵活的。
1. 虽然可以使用typedef定义栈的数据类型,但是并不能通过这个参数真正控制栈的数据类型。这个关系到scanf这个函数对于不同的数据的存入格式。
2,对于栈额外的数据,比如定义栈顶,栈底这个可以自行扩展。这个并不是必须的。
3. 这个程序可以作为一般数据结构链式栈的通用模式。