很久以前学链表的时候写的,想在以前做斑竹的一个论坛发,结果都没发就倒闭了,汗! 本来我想请教的,不过后来我想明白了,写了一些通俗的解释,希望初学链表的看得懂。 老问题了,小弟不才,连最简单的链表都还没understand,希望大家知道什么说什么。 小弟还未弄懂的是其中“can't understand”的两句,我不能想像它们在内存中的工作,
#include<iostream.h> typedef int ElemType; struct LNode { ElemType data; LNode* next; };
void main() { LNode *p, *q, *p1; p1=p=new LNode; for(int i=0; i<3; i++) { q=new LNode; cin>>q->data;
p->next=q; //can't understand p=q; //can't understand
} p->next=NULL; p=p1->next; while(p!=NULL) { cout<<p->data<<" "; p=p->next; } cout<<endl; }
p->next=q; //p的指针指向q p=q; //这句到底是怎么赋值法?把q->data和q->next分别赋给p->data和p->next吗?
但是输入的是q->data,储存的是p->data,why?老师说用先进后出的压栈图形来理解…… 还是不懂,相信很多初学者也和我一样困扰在链表的抽象工作方式上吧, 请高手们不吝指点,也请和我一样初学的人知道多少就说多少,我真的不懂!谢谢!
PS: 上年学C++基础时就没搞懂,现在正学C++数据结构,还是没懂,真不配做版主,不好意思哦^_^
上贴是上个星期想问的问题,不过那天论坛上不了,所以现在才发,但现在我经已想通了。
我觉得,可能很多高手都明白的知识,在像我这样的初学者看来是晦涩难懂的, 所以我写了一些注释,希望和大家切磋一下怎么理解链表的抽象赋值和遍历形式。
#include<iostream.h>
typedef int ElemType;
struct LNode { ElemType data; LNode* next; };
void main() { LNode *p, *q, *p1; //p1是表头指针,p1单链表 //p是遍历指针,q是临时储存结点
p1=p=new LNode; //p1和p指向同一个新申请的结点 //p1不作结点用,也不再变动
for(int i=0; i<3; i++) { q=new LNode; cin>>q->data; //新建一个结点,作临时用
p->next=q; //p指针现在处于表头指针p1的位置 //此句即是把表头指针指向新建的结点
p=q; //这句就是令我费解多时的表达式 //开始以为是把q的结点值data和next指针赋给p //我就傻眼了,怎么把临时值赋回头了 //原来p也作指针用,此句只是把p指针从p1的位置 //移到当前临时结点q的位置罢了 //值得注意的是,下一次循环新建q指向的结点 //令原先建的临时结点不再属于q指针 //所以才会定义一个p指针作移动用途 //只不过此p指针带有data结点罢了,但在 //储存过程不须用到,打印时才用到 }
p->next=NULL; //循环结束后最后一个结点的next指针置空值NULL
p=p1->next; //移动指针p重新指向表头指针所指的第一个结点 //为遍历链表作准备
while(p!=NULL) //当移动指针p没到最后的NULL时执行循环 { cout<<p->data<<" "; p=p->next; //此处也是抽象之极,开始想不通怎么把自己的next指针 //所指向的结点反赋给自己,后来才知道,不是赋值语句 //而p把自己在当前结点的data位置移动到有本身next //所指的下一个结点的data上,这样当cout打印的时候, //p->data就一直往后移,达到遍历效果 } cout<<endl; }