举个例子:带头结点的头插法
typedef struct LNode
{
int data;
struct LNode *next;
}LNOde,*LinkList;//typedef重命名,第一个问题点
//带头结点的头插法
LinkList List_HeadInsert(LinkList &L)
{
LNode *s;//LinkList s;这两个声明都是一样的,下面会做详细解读,第二个容易出问题的点
int x;
L = (LinkList)malloc(sizeof(LNode));//这里理解容易出误区,不知道会不会有人,会跟我一样纠结
//半天,下面有详细解读,第三个容易出问题的点
L->next = NULL;
cin>>x;//我用的c++
while(x!=9999)
{
s = (LNode*)malloc(sizeof(LNode));
s->data = x;
s->next = L->next;
L->next = s;
cin>>x;
}
return L;
}
//第四点带头结点和不带头结点都头插法的区别
LinkList List_WithoutHeadInsert(LinkList &L)
{
int x;
LNode *s;
L = (LinkList)malloc(sizeof(LNode));
L->next;
cin>>x;
L->data = x;
while(x!=9999)
{
s = (LNode *)malloc(sizeof(LNode));
s->data = x;
s->next = L;
L = s ;//为啥把L=s如果出现第五个问题,就是第三个问题没理解清楚
cin>>x;
}
return L;
}
//下面全是上面提出问题的详细解答
第一个问题:
typedef struct LNode{ //定义单链表结点类型
int data; //每个结点存放一个数据元素
struct Lnode *next; //指针指向下一个结点
}LNode,*LinkList;
struct LNode *p 和 LNode *p 和LinkList p效果等价,
加了typedef就是给这个struct LNode 换了个名字
第二个问题:
struct LNode *p 和 LNode *p 和LinkList p效果等价,
只是LinkList p;可读性更强。
LNode *p强调这是一个结点。
LinkList p强调这是一个单链表。
没必要特别纠结,都是一样的。
第三个问题:
L = (LinkList)malloc(sizeof(LNode)); //这里是申请了一块内存,然后地址给指针L,指针L指向了这个地址而已,这个L是头指针,但它指向的值地址里存的就是头结点。理解这句话第五个问题也就解决了。
第四个问题:
第一个区别
带头结点
int x;
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL;
cin>>x;//我用的c++
不带头结点
int x;
L = (LinkList)malloc(sizeof(LNode));
L->next;
cin>>x;
L->data = x;
可以直观的看出当不带头结点时,L一开始就指向的申请的那块地址里面赋了值。
因为没有头结点,所以L指向的地址一直会变,指向最新插入的那个地址 L = s ;,第五个问题就解决了
第五个问题,结合三四个问题理解就没问题了。
附上尾插法,带头结点和不带头结点的写法
LinkList with_tail(LinkList &L)
{
LNode *s,*r;
int x;
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL;
r = L;
cin >> x;
while (x != 9999)
{
s = (LNode *)malloc(sizeof(LNode));
s->data = x;
r->next = s;
r = s;
cin >> x;
}
r->next = NULL;
return L;
}
LinkList without_tail(LinkList &L)
{
LNode *s, *r;
int x;
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL;
cin >> x;
L->data = x;
r = L;
while (x != 9999)
{
s = (LNode*)malloc(sizeof(LNode));
s->data = x;
r->next = s;
r = s;
cin >> x;
}
r->next = NULL;//这里也可以放到上面去写如下
return L;
}
//尾插法尾指针后继赋为空第二种写法,上面是第一种
LinkList without_tail(LinkList &L)
{
LNode *s, *r;
int x;
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL;
cin >> x;
L->data = x;
r = L;
while (x != 9999)
{
s = (LNode*)malloc(sizeof(LNode));
s->data = x;
s->next = NULL;
r->next = s;
r = s;
cin >> x;
}
return L;
}