【求助】用链表实现堆栈和队列时的迷惑

guocai_yao 2009-04-10 09:30:15
先看一个程序:有问题的地方的是pop函数:

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <malloc.h>

#define ELEM_TYPE int

typedef struct NODE{
ELEM_TYPE data;
struct NODE *next;
}linked_stack;

#define LEN (sizeof(linked_stack))

linked_stack *linked_stack_init(void)
{
linked_stack *top ;
top = NULL;
return top;
}

int linked_stack_is_empty(linked_stack *top)
{
return (top == NULL);
}

linked_stack *linked_stack_push(linked_stack *top, ELEM_TYPE x)
{
linked_stack *new = (linked_stack *)malloc(LEN);
if(new == NULL){
printf("Allocate memory error!\n");
exit(EXIT_FAILURE);
}
new->data = x;
new->next = top;
top = new;

return top;
}

int linked_stack_pop(linked_stack *top)
{
ELEM_TYPE x;
linked_stack *tmp = top;

if(linked_stack_is_empty(top)){
printf("Empty!\n");
exit(EXIT_FAILURE);
}
x = top->data;
top = top->next;
free(tmp);
return x;
}

ELEM_TYPE linked_stack_get_top(linked_stack *top)
{
if(linked_stack_is_empty(top)){
printf("Empty!\n");
exit(EXIT_FAILURE);
}
return top->data;
}

int main()
{
int x;
linked_stack *s = linked_stack_init();

s = linked_stack_push(s, -23);
s = linked_stack_push(s, 44);
s = linked_stack_push(s, 1);
x = linked_stack_pop(s);
printf("%d ", x);
x = linked_stack_pop(s);
printf("%d ", x);
x = linked_stack_pop(s);
printf("%d ", x);

return 0;
}

再看一个程序,注意linked_queue_out函数

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <malloc.h>
#include <assert.h>

#define ELEM_TYPE int

typedef struct NODE{
ELEM_TYPE data;
struct NODE *next;
}linked_queue_node;

typedef struct HEAD_TAIL{
linked_queue_node *front;
linked_queue_node *rear;
}linked_queue;

#define LEN_NODE (sizeof(linked_queue_node))
#define LEN_HEAD_TAIL (sizeof(linked_queue))

linked_queue *linked_queue_init(void)
{
linked_queue_node *p = NULL;
/*申请头尾指针节点*/
linked_queue *Q = (linked_queue *)malloc(LEN_HEAD_TAIL);
if(NULL == Q){
printf("Allocate memory error!\n");
exit(EXIT_FAILURE);
}
/*申请链队头节点*/
p = (linked_queue_node *)malloc(LEN_NODE);
if(NULL == p){
printf("Allocate memory error!\n");
exit(EXIT_FAILURE);
}
p->next = NULL;/*头结点的指针域为空*/
Q->rear = Q->front = p;
return Q;
}

int linked_queue_is_empty(linked_queue *Q)
{
return (Q->front->next == NULL);
}

void linked_queue_in(linked_queue *Q, ELEM_TYPE x)
{
linked_queue_node *new = (linked_queue_node *)malloc(LEN_NODE);
if(new == NULL){
printf("Allocate memory error!\n");
exit(EXIT_FAILURE);
}
assert(x != -1);/*-1只作为队列为空时的标志*/
new->data = x;
/*FIFO,插入链表的尾部*/
new->next = NULL;
Q->rear->next = new;
Q->rear = new;
}

ELEM_TYPE linked_queue_out(linked_queue *Q)
{
ELEM_TYPE x;
linked_queue_node *tmp;
if(linked_queue_is_empty(Q)){
printf("Empty\n");
return -1; /*空队列返回数值-1*/
}
tmp = Q->front->next;/*保存第一个节点*/
x = tmp->data;
Q->front->next = tmp->next;
free(tmp);
/*出队后链表若为空,调整队列尾指针*/
if(linked_queue_is_empty(Q))
Q->rear = Q->front;
return x;
}

void linked_queue_print(const linked_queue *Q)
{
linked_queue_node *p = Q->front->next;/*头结点Q->front->next不打印*/
if(p == NULL){
printf("Empty\n");
return;
}
while(p != NULL){
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}

int main()
{
ELEM_TYPE x;
linked_queue *q = linked_queue_init();
linked_queue_in(q, 30);
linked_queue_in(q, 10);
printf("After in, the queue is: ");
linked_queue_print(q);

x = linked_queue_out(q);
printf("the value come out the queue is %d \n", x);
printf("After out, the queue is: ");
linked_queue_print(q);

x = linked_queue_out(q);
printf("the value come out the queue is %d \n", x);
printf("After out, the queue is: ");
linked_queue_print(q);

return 0;
}

linked_stack_pop函数和linked_queue_out函数同样是对传过来的指针的副本进行修改,为什么一个成功一个失败?
感觉自己对指针的理解还是不透彻啊!
...全文
126 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
linked_stack_pop函数和linked_queue_out函数同样是对传过来的指针的副本进行修改,为什么一个成功一个失败?


你都知道是传指针的副本,那如果你的函数需要修改的是指针本题,就会出问题撒.
ylywyn136 2009-04-10
  • 打赏
  • 举报
回复
top = top->next;你的这个有问题
zhanghuayi_xiyou 2009-04-10
  • 打赏
  • 举报
回复
当然不对了,linked_queue_out只是改变了头指针的副本,而没有改变主函数变量s 。
而linked_queue_out参数是linked_queue *Q,没有改变Q的副本,但改变主函数(*q).front的值,


给你的建议,linked_queue_out的参数使用二级指针。这样主函数变量s 就能改变。
zhanghuayi_xiyou 2009-04-10
  • 打赏
  • 举报
回复
当然不对了,linked_queue_out只是改变了头指针的副本,而没有改变主函数变量s 。
而linked_queue_out参数是linked_queue *Q,没有改变Q的副本,但改变主函数(*q).front的值,


给你的建议,linked_queue_out的参数使用二级指针。这样主函数变量s 就能改变。
guocai_yao 2009-04-10
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 zhanghuayi_xiyou 的回复:]
当然不对了,linked_queue_out只是改变了头指针的副本,而没有改变主函数变量s 。
而linked_queue_out参数是linked_queue *Q,没有改变Q的副本,但改变主函数(*q).front的值,


给你的建议,linked_queue_out的参数使用二级指针。这样主函数变量s 就能改变。
[/Quote]
linked_queue_out可以实现功能 linked_stack_pop出问题; 但是两个函数都是修改的是指针的的副本 所以都不可以这样用的 想知道linked_queue_out是否是碰巧成功的?
guocai_yao 2009-04-10
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 hairetz 的回复:]
linked_stack_pop函数和linked_queue_out函数同样是对传过来的指针的副本进行修改,为什么一个成功一个失败?


你都知道是传指针的副本,那如果你的函数需要修改的是指针本题,就会出问题撒.
[/Quote]
其实想知道 linked_queue_out是怎么成功的?
guocai_yao 2009-04-10
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 ylywyn136 的回复:]
top = top->next;你的这个有问题
[/Quote]
什么问题?

69,370

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧