C语言实现链栈总结
最近用C语言实现链栈时遇到了问题,经过上网收索资料以及师兄的讲解顺利地解决了该问题,现就将所遇到的问题以及解决方法总结如下:
1. 带有空余头结点的链栈代码实现如下:
/**************************************************/
//函数功能:实现链栈的进栈和出栈功能
//说明:带有空余头结点,利用空余头结点将入栈的结点串接起来,
//通过出栈是对数据逆序输出
/**************************************************/
#include<stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define FALSE 0
#define TRUE 1
typedef struct node{
int data;
struct node *next;
}Stack;
void StackInit(Stack *top)
{
top->next=NULL;
}
int Push(Stack *top,int data)
{
Stack *p;
p=(Stack *)malloc(sizeof(Stack));
if(p==NULL)
{
return FALSE;
}
p->data=data;
p->next=top->next;
top->next=p;
return TRUE;
}
int IsEmpty(Stack *top)
{
if(top->next==NULL)
{
return TRUE;
}
return FALSE;
}
int Pop(Stack *top,int *x)
{
Stack *p;
if(IsEmpty(top))
{
return FALSE;
}
p=top->next;
*x=p->data;
top->next=p->next;
free(p);
return TRUE;
}
int main()
{
int x;
Stack *top=(Stack *)malloc(sizeof(Stack));//带有头结点的链栈
StackInit(top);
printf("Input some positive integers:\n");
scanf("%d",&x);
while(x>0)
{
Push(top,x);
scanf("%d",&x);
}
while(Pop(top,&x))
{
printf("%d\t",x);
}
printf("\n");
return 0;
}
自己尝试了不带头结点的情况,其代码如下:
/*******************************************************/
//错误版本:不带空余都结点的链栈实现
/*******************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define FALSE 0
#define TRUE 1
typedef struct node{
int data;
struct node *next;
}Stack;
int Push(Stack *top,int data)
{
Stack *p;
p=(Stack *)malloc(sizeof(Stack));
if(p==NULL)
{
return FALSE;
}
p->data=data;
p->next=top;
top=p;
return TRUE;
}
int IsEmpty(Stack *top)
{
if(top==NULL)
{
return TRUE;
}
return FALSE;
}
int Pop(Stack *top,int *x)
{
Stack *p;
if(IsEmpty(top))
{
return FALSE;
}
p=top;
*x=p->data;
top=p->next;
free(p);
return TRUE;
}
int main()
{
int x;
Stack *top=NULL;//不带有头结点的链栈
printf("Input some positive integers:\n");
scanf("%d",&x);
while(x>0)
{
Push(top,x);
scanf("%d",&x);
}
while(Pop(top,&x))
{
printf("%d\t",x);
}
printf("\n");
return 0;
}
在编译运行后出不来预期的结果,通过编译调试后发现每次在出栈时遇到问题,因为上述代码在入栈和出栈子函数中传递的都是指针,在主函数中再来调用入栈和出栈子函数后,就如同值传递一样不改变结果,所以每次top=NULL,因而也就不执行出栈操作,我们采用如下测试看看效果:
测试如下:
1. #include <stdio.h>
void f(int **p)
{
int k=10;
*p=&k;//修改指针修改值
}
int main()
{
int i=1;
int *q=&i;
printf("%d\n",long(q));
f(&q);
printf("%d\n",*q);//值修改了
printf("%d\n",long(q));//指针修改了
return 0;
}
//为说明问题,特做如下对比
//这是指针操作必须要搞清楚的问题
//写入栈操作时指针是要移动的,要修改的
2. #include <stdio.h>
void f(int *p)
{
int k=10;
*p=k;
}
int main()
{
int i=1;
int *q=&i;
printf("%d\n",long(q));
f(q);
printf("%d\n",*q);//值修改了
printf("%d\n",long(q));//指针没有修改
return 0;
}
可以发现问题出在在子函数中修改后,返回时并没有对实参指针进行修改,也就是每次返回后top始终指向NULL,究其原因用指针作为参数,也只是拷贝指针,修改也只是修改指针对象,不能修改指针,解决方法如下:用二级指针作为参数,可以修改指针也可以修改指针对象。
代码修改如下:
*#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define FALSE 0
#define TRUE 1
typedef struct node{
int data;
struct node *next;
}Stack;
int Push(Stack **top,int data)
{
Stack *p;
p=(Stack *)malloc(sizeof(Stack));
if(p==NULL)
{
return FALSE;
}
p->data=data;
p->next=*top;
*top=p;
return TRUE;
}
int IsEmpty(Stack *top)
{
if(top==NULL)
{
return TRUE;
}
return FALSE;
}
int Pop(Stack **top,int *x)
{
Stack *p;
if(IsEmpty(*top))
{
return FALSE;
}
p=*top;
*x=p->data;
*top=p->next;
free(p);
return TRUE;
}
int main()
{
int x;
Stack *top=NULL;//不带有头结点的链栈
printf("Input some positive integers:\n");
scanf("%d",&x);
while(x>0)
{
Push(&top,x);
scanf("%d",&x);
}
while(Pop(&top,&x))
{
printf("%d\t",x);
}
printf("\n");
return 0;
}