链表,队,栈在程序结束前都要注意有无释放表头结点。
这个是带表头结点的,即head指针指向表头,表头中不存放数据,表头下一个指针指向第一个数据
包括
- is_malloc_ok
- create_node
- create_stack
- push_stack
- pop_stack
- is_empty
- gettop_stack
- empty_stack
- release_stack
#include <stdio.h>
#include <stdlib.h>
enum return_val {EMPTY_OK, EMPTY_NO, FULL_OK, FULL_NO, PUSH_OK, PUSH_NO, POP_OK, POP_NO, GET_OK, GET_NO};
//没有size大小限制(因为是链表可以无限延伸),所以不用管is_full
struct stack_data
{
int num;
struct stack_data * next;
};
typedef struct stack_data Stack;
int is_malloc_ok(Stack *node)
{
if(node == NULL)
{
return 0;
}
else
{
return 1;
}
}
int create_node(Stack ** node)
{
int count = 10;
do
{
*node = (Stack*)malloc(sizeof(Stack));
count--;
if(count == 0)
{
printf("malloc error!\n");
return 0;
}
}while(!is_malloc_ok(*node));
return 1;
}
void create_stack(Stack ** head)
{
if(create_node(head) == 0)
{
printf("创建失败!\n");
exit(-1);
}
(*head)->next = NULL;
}
int push_stack(Stack * head,int num)
{
Stack * node;
create_node(&node);
if(node == NULL)
{
return PUSH_NO;
}
else
{
node->num = num;
node->next = head->next;
head->next = node;
return PUSH_OK;
}
}
int pop_stack(Stack *head,int * num)
{
Stack *p;
if(is_empty(head) == EMPTY_OK)
{
printf("stack is empty!\n");
return POP_NO;
}
else
{
*num = head->next->num;
p = head->next;
head->next = head->next->next;
free(p);
return POP_OK;
}
}
int is_empty(Stack *head)
{
if(head->next == NULL)
{
return EMPTY_OK;
}
else
{
return EMPTY_NO;
}
}
int gettop_stack(Stack *head, int *num)
{
if(is_empty(head) == EMPTY_OK)
{
printf("stack is empty!\n");
return GET_NO;
}
else
{
*num = head->next->num;
return GET_OK;
}
}
void empty_stack(Stack *head)
{
Stack * p = head;
while(head->next != NULL)
{
p = head->next;
head->next = p->next;
free(p);
}
}
void release_stack(Stack **head)
{
Stack *p;
empty_stack(*head);
p = *head;
*head = NULL;
free(p);
}
int main()
{
Stack * head;
int i;
int num;
create_stack(&head);
for(i = 0; i < 10; i++)
{
if(push_stack(head,i + 1) == PUSH_NO)
{
printf("push no!\n");
}
else
{
printf("push ok! num is %d\n",i + 1);
}
}
for(i = 0; i < 7; i++)
{
if(pop_stack(head,&num) == POP_NO)
{
printf("pop no!\n");
}
else
{
printf("stack is %d\n",num);
}
}
empty_stack(head);
for(i = 0; i < 5; i++)
{
if(gettop_stack(head,&num) == GET_NO)
{
printf("gettop no!\n");
}
else
{
printf("top is %d\n",num);
pop_stack(head,&num);
}
}
release_stack(&head);
return 0;
}
小练:
改进要点:
- 要学会用老师的enum系列
- 没写is_malloc_ok系列
- empty没写,只写了release stack函数
- 缺少一些提示,比如栈空了要说“栈已空”之类
- GetTop最好按老师的写,int GetTop(Stack *head,int *num);这样比较好,不然return谁知道你返回的是不是top值还是错误(我返回的是NULL不太好)
#include <stdio.h>
#include <stdlib.h>
struct stack_data
{
int num;
struct stack_data *next;
};
typedef struct stack_data Stack;
int CreateNode(Stack **s)
{
*s = (Stack *)malloc(sizeof(Stack));
if(*s == NULL)
{
return 0;
}
return 1;
}
int CreateStack(Stack **s)
{
if(!CreateNode(s))
return 0;
(*s)->next = NULL;
return 1;
}
int IsEmpty(Stack *s)
{
if(s->next == NULL)
return 1;
return 0;
}
int Pop(Stack *s,int *num)
{
Stack *p;
if(IsEmpty(s))
return 0;
*num = s->next->num;
p = s->next;
s->next = s->next->next;
free(p);
return 1;
}
int Push(Stack *s,const int num)
{
Stack *p;
if(!CreateNode(&p))
return 0;
p->num = num;
p->next = s->next;
s->next = p;
return 1;
}
//改进!
int GetTop(Stack *s)
{
if(IsEmpty(s))
{
printf("Link is empty\n");
return NULL;
}
return s->next->num;
}
//我写的相当于release版本
void MakeEmpty(Stack **s)
{
int num;
while(!IsEmpty(*s))
Pop(*s,num);
free(*s);
*s = NULL;
}
int main()
{
Stack *head;
int i, num;
CreateStack(&head);
i = 0;
num = 1;
while(i < 10 && Push(head,num))
{
i++;
num++;
printf("%d\n",GetTop(head));
}
printf("----------------------\n");
while(Pop(head,&num))
{
printf("%d\n",num);
}
MakeEmpty(&head);
return 0;
}