单链表的建立,头尾插法建立单链表

typedef struct Node {  
    int data;  
    struct Node* next;  
} Node;


Node* current = head;  // 假设 head 是链表的头节点  
while (current->next != NULL) {    
    current = current->next;    
}    
current->next = newNode;  // 将 newNode 添加到链表的末尾


如果 current 最初指向 Node1,那么执行 current = current->next; 后,current 就会指向 Node2。再次执行这行代码,current 就会指向 Node3。最后,如果 current->next 是 NULL(即链表的末尾),那么 current = current->next; 将不会改变 current 的值,因为 NULL 不是一个有效的地址来指向链表的下一个节点。


Node1 <-+  
       | data  
       | next -> Node2 <-+  
                    | data  
                    | next -> Node3 <-+  
                               | data  
                               | next -> NULL




head 是一个指向链表头节点的指针。
current 被初始化为 head,因此它开始时指向链表的头节点。
在 while 循环中,current 指针被更新为指向当前节点的下一个节点,
直到 current->next 为 NULL(即链表的末尾)。
在循环结束后,current 指向链表的最后一个节点。
最后,current->next 被设置为 newNode,从而将新节点 newNode 添加到链表的末尾。
所以,current 是一个在内存中动态变化的指针变量,它指向链表中的不同节点,
具体取决于链表的遍历过程。在遍历开始时,它指向链表的头节点;在遍历结束时,
它指向链表的最后一个节点。




***********************************************************************************
// 单链表的建立1,头插法建立单链表  

LinkedList headInsertCreateLinkedList() {  
    // 创建一个头结点,它不存储数据,只用来表示链表的开始  
    Node *head = (Node *)malloc(sizeof(Node));  
    if (head == NULL) {  
        // 如果内存分配失败,返回NULL或进行错误处理  
        return NULL;  
    }  
    head->next = NULL; // 初始化头结点的next指针为NULL,表示这是一个空链表  
  
    int data; // 用于存储从输入读取的数据  
    while (scanf("%d", &data) != EOF) { // 读取数据直到文件结束  
        // 创建一个新的结点来存储数据  
        Node *newNode = (Node *)malloc(sizeof(Node));  
        if (newNode == NULL) {  
            // 如果内存分配失败,进行错误处理(这里只是简单返回,
实际情况可能需要释放已分配的内存)  
            return NULL;  
        }  
        newNode->data = data; // 将读取到的数据赋值给新结点的数据域  
  
        // 使用头插法将新结点插入到链表的头部  
        // 先把新结点的next指针指向头结点后面的第一个结点  
        newNode->next = head->next;  
        // 然后把头结点的next指针指向新结点,这样新结点就成了链表的第一个结点  
        head->next = newNode;  
    }  
    // 返回头结点的指针,它指向整个链表  
    return head;  
}


头插法是一种在链表的头部插入新结点的方法。在单链表中,头结点通常不存储数据,
只是作为链表的起始标志,它的next指针指向链表的第一个数据结点。

当你使用头插法插入一个新结点时,你需要做以下两步:

将新结点的next指针指向当前头结点的next所指向的结点:这一步的目的是确保新结点能够正确地链接到现有的链表上。具体来说,就是把新结点插入到当前链表的第一个结点之前。
将头结点的next指针指向新结点:这一步的目的是让新结点成为链表的新的第一个结点。由于头结点的next原本指向链表的第一个数据结点,现在我们将它指向新结点,那么新结点就成为了链表的新头部。
用代码表示就是:

// 假设 newNode 是新创建的结点,head 是链表的头结点  
newNode->next = head->next; // 新结点的 next 指向头结点后面的第一个结点(或 NULL 
如果链表为空)  
head->next = newNode;       // 头结点的 next 指向新结点,使其成为链表的新头部


这样,每次使用头插法插入新结点时,新结点都会成为链表的第一个结点,而原有的结点则依次后移。
这就是头插法的基本原理



***********************************************************************************



// 单链表的建立2,尾插法建立单链表  
  
LinkedList tailInsertCreateLinkedList() {  
    // 创建一个头结点,它不存储数据,仅作为链表的起点  
    Node *head = (Node *)malloc(sizeof(Node));  
    if (head == NULL) {  
        // 如果内存分配失败,返回NULL或进行错误处理  
        return NULL;  
    }  
    head->next = NULL; // 初始化头结点的next指针为NULL,表示链表为空  
  
    Node *tail = head; // tail指针始终指向链表的最后一个结点,开始时指向头结点  
    int data;          // data用于存储从输入读取的数据  
  
    while (scanf("%d", &data) != EOF) { // 读取数据直到文件结束  
        Node *newNode = (Node *)malloc(sizeof(Node)); // 申请新的结点  
        if (newNode == NULL) {  
            // 如果内存分配失败,进行错误处理(这里只是简单返回,实际情况可能需要释放已分配的内存)  
            // ... 错误处理代码  
            return NULL;  
        }  
        newNode->data = data; // 将读取到的数据赋值给新结点的数据域  
        tail->next = newNode; // 将新结点插入到链表的尾部  
        tail = newNode;       // 更新tail指针,使其指向新的尾部结点  
    }  
  
    // 链表构建完成后,尾结点的next指针应该指向NULL  
    tail->next = NULL; // 这一步其实是多余的,因为在循环中最后一个结点的next已经默认为NULL  
  
    // 返回头结点的指针,它指向整个链表  
    return head;  
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值