三部曲
- 序号
- 保护
- 遍历
算法
定义链表节点
typedef struct LNode{
int data;
struct LNode *next;
}LNode,*LinkList;
实例化一个头节点
/**
* 初始化头节点,也就是链表的老大
* 描述:手提箱把手为地址,手提箱里边为值和下一个把手
*/
int initList()
{
LinkList L = (LinkList)malloc(sizeof(LinkList));
L->next = NULL;
return L;
}
插入节点
/**
* 插入节点
*/
void insertList(LinkList L, int index, int value) {
int i = 0;// 如果为1,则头结点为0
LinkList p = L;
while(p) {
if(i == index) {
LinkList node = (LinkList)malloc(sizeof(LinkList));
node->data = value;
node->next = p->next;
p->next = node;
break;
}
p = p->next;
i++;
}
}
问题一:我们看到LinkList p = L;是干嘛的?他是把什么赋值给了p?
答:我们把链的每个节点都看成一个手提箱,手提箱的有把手,这个把手放的是地址,拿到了把手就能抬起整个手提箱;所以LinkList p = L;的意思是,把头指针的把手,给了p,p也就成了把手。他不是L的一部分,只是一个把手。单独这个p是没有意义的,p->next及p->data才有意义。比如,你不能把新节点赋值给p,比如p = node,但是你可以把p->next = node;,你也可以把p赋值给其他,比如p->next = p。
有的时候,可能LinkList p = L->next,那么实际上是从首节点,而非头节点开始算起的。无所谓...
问题二:p = p->next;是干嘛的?
答:就是把下一个手提箱的把手给了p,于是我改变了p下手提箱的数据,就是改变了链表节点数据。所以说:单独这个p是没有意义的,p->next及p->data才有意义。
问题三:为什么说p保护了L?
答:因为L始终是老大,是头节点,你不能对他进行更改。
删除节点
void deleteList(LinkList L, int index) {
int i = 0; // 如果为1,则头结点为0
LinkList p = L;
while(p) {
if(i == index) {
p->next = p->next->next;
break;
}
p = p->next;
i++;
}
}
遍历节点
/**
* 遍历
*/
int getList(LinkList L, int index) {
int i = 0; // 如果为1,则头结点为0
LinkList p = L->next;
while(p) {
if(i == index) {
return p->data;
}
p = p->next;
i++;
}
}
验证
int main() {
LinkList L = initList();
insertList(L, 0, 189);
insertList(L, 0, 256);
insertList(L, 1, 444);
deleteList(L, 0);
deleteList(L, 1);
int value = getList(L, 0);
printf("data:%d \n", value);
return 0;
}