带头指针的链表;
带头指针的链表和带头节点的链表
一般情况下:我们对带头指针的链表进行操作需要ifelse来判断这个要操作的节点的前一个是否是头指针;采用转换的方法可以有效的避免这个ifelse的问题;
- 区别:就是一个是以指针当中链表表头一个是以节点当中链表表头;
- 如何转换:添加一个临时的节点作为链表的表头;(这个临时的节点是放在栈上的)
- 很多操作和带头节点的链表基本相同;
两个重要的点:
- 1 如何添加临时节点作为头节点;
- 2 对函数进行一定的优化;
要用到的英文 intiChainList;初始化表头; destroyChainList;销毁链表; insertChainListHeard;头插头; insertChainListPos;任意位置插入; deleteChainListElement;任意位置删除节点; showChainList;展示节点;
对函数的优化
其实就是把
while(p->next){
if(p->next->val == val){
break;
}
p = p->next;
}
while(p->next && p->next->val == val){
p = p->next;
}
这两个东西其实是等价的,都是在p->next != NULL的条件下,当p->next == val 的时候我们就退出这个循环; 我们可以根据第一个改写出第二个;并且前后的顺序不能改变;
我对于一个指针传入一个函数的见解,
Frist
void text(int *p){
*p = 30;
}
int main(){
int a = 10;
int *p = &a;
text(p);
printf("%d",a);
return 0;
}
Second
void text(int **p1, int *a2){
//使p1指向a2;
*p1 = a2;
}
int main(){
int a1 = 10;
int a2 = 30;
int *p1 = &a1;
int *p2 = &a2;
text(&p1,&a2);
printf("p1 = %d\n",*p1);
return 0;
}
Third
其实我们这个代码就用到了大量的关于指针的函数;
核心:只能修改这个地址空间里面的东西,但是不能修改这块地址空间;
单向循环链表;
思考:这两段代码有什么不同
while(p->next){
p = p->next;
}
while(p){
p = p->next;
}
代码1 一般用于寻找你要修改的节点的前一个节点,通常用于(节点插入/删除)等操作;
代码2 就是节点的遍历工作,它一般不依靠于当前节点的前一个节点,可用于查找等操作;
单向循环链表;
1带头节点的单向循环链表;
2 带头指针的单向循环链表;
两者有细微的差别 就是在尾节点的指向不一样,尾节点的指向必须是一个节点;所以带头指针的尾节点和带头节点的尾节点它们的节点next指向不一样;
要用到的英文;
list 表; link 链; loop 循环;
LookNode;
LookLinkList;
intiLookLinkList;
insertLookLinkListHeard;
insertLookLinkListRear;
showLookLinkList;