单链表带头结点不带头结点 -尊龙游戏旗舰厅官网
尊龙游戏旗舰厅官网
收集整理的这篇文章主要介绍了
单链表带头结点不带头结点
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
转自:http://blog.csdn.net/xlf13872135090/article/details/8857632
node *head; //声明头结点 带头结点初始化
void initlist(node **head){
*head=(node *)malloc( sizeof(node)); (*head)->next=null; } 带头结点尾插入,统一操作 方式一: void creatlist(node **head){node *r=*head,*s;
int a;
while(scanf("%d",&a)){
if(a!=0){
s=(node *)malloc(sizeof(node));
s->value=a;
r->next=s;
r=s;
}
else{
r->next=null;
break;
}
}
} 调用creatlist(&head); 方式二: void creatlist(node *head){
node *r=head,*s;
... //下面的都一样
} 调用creatlist(head); ------------------------------------------------------------------------------------------------------ 不带头结点初始化 方式一: void initlist(node **head){ *head=null; } 调用initlist(&head); 方式二: void initlist(node *head){ head=null; } 调用initlist(head); 不带头结点尾插入,第一个节点与其他节点分开操作 void creatlist(node **head){
node *p,*t; /*p工作指针,t临时指针*/
int a,i=1;
while(scanf("%d",&a)){
if(a!=0){
t=(node *)malloc(sizeof(node));
t->value=a;
if(i==1){
*head=t;
}
else{
p->next=t;
}
p=t;
}
else{
p->next=null;
break;
}
i ;
}
} 调用creatlist(&head); 一、两者区别: 1、不带头结点的单链表对于第一个节点的操作与其他节点不一样,需要特殊处理,这增加了程序的复杂性和出现bug的机会,因此,通常 在单链表的开始结点之前附设一个头结点。 2、带头结点的单链表,初始时一定返回的是指向头结点的地址,所以一定要用二维指针,否则将导致内存访问失败或异常。 3、带头结点与不带头结点初始化、插入、删除、输出操作都不样,在遍历输出链表数据时,带头结点的判断条件是while(head->next!=null), 而不带头结点是while(head!=null),虽然头指针可以在初始时设定,但是如1所述,对于特殊情况如只有一个节点会出现问题。 二、为什么不带头结点初始化有2种方式,而带头结点只有1种方式呢? 因为不带头结点声明node *head 时;c编译器将其自动初始化为null,于是根本不需要调用initlist(head);也即不带头结点的初始化 是个伪操作。而带头结点的初始化在堆开辟了一段内存,需要修改head指针变量指向的地址(即head的值),所以要修改head的值,必须传保 存head变量的地址(即二维指针)。而直接调用creatlist(head);相当于传head变量的值,函数修改的是head的副本,无法真正改变head的值。 注:这里可以将head指针看成一个变量(不管它保存的是地址),就比较好理解了。 三(key)、其实本质上还是传值,传址的问题,只不过指针本身保存的地址,让这个过程变得有点纠结。在函数调用需要修改指针变量的指向(value)时, 应该传递指针变量的地址(address)。 另外,对于函数的形参是指针时,只要该参数不在左边(即都是右值操作),二维指针(形参)就可以简化为一维指针。如上面带头结点的尾插 简化版本。 与50位技术专家面对面20年技术见证,附赠技术全景图
总结
以上是尊龙游戏旗舰厅官网为你收集整理的单链表带头结点不带头结点的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: js表单设置值
- 下一篇: