链表1,2,3...

255 阅读2分钟

三部曲

  • 序号
  • 保护
  • 遍历

算法

定义链表节点

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;的意思是,把头指针的把手,给了pp也就成了把手。他不是L的一部分,只是一个把手。单独这个p是没有意义的,p->nextp->data才有意义。比如,你不能把新节点赋值给p,比如p = node,但是你可以把p->next = node;,你也可以把p赋值给其他,比如p->next = p

有的时候,可能LinkList p = L->next,那么实际上是从首节点,而非头节点开始算起的。无所谓...

问题二:p = p->next;是干嘛的?

答:就是把下一个手提箱的把手给了p,于是我改变了p下手提箱的数据,就是改变了链表节点数据。所以说:单独这个p是没有意义的,p->nextp->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;
}