C语言单向链表(头插、尾插、遍历、删除、反转)

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#if 1
typedef struct  NODE
{
    
    
    int data;
    struct NODE *next;    
}node;
#if 0
node *createlist_tail(void)
{
    
    
    node * head = (node*)malloc(sizeof(node));
    head = NULL;
    node *p;
    int data;
    while (1){
    
    
        node *s = (node*)malloc(sizeof(node));
        printf("please input int data:");
        scanf("%d", &data);
        if(data == 0) break;
        s->data = data;
        printf("data=%d\n", s->data);
        if(head == NULL){
    
    
            head = s;//第一个节点来时,让头指针指向新节点
        }
        else{
    
    
            p->next = s;//之后的节点来时,让P->next指针指向新节点
        }
        p = s;
    }
    if(head != NULL){
    
    //因为有了新节点,所以head指针就不是指向NULL了
        p->next = NULL;//尾插法P->next永远在尾巴上,最后之向NULL
    }
    return head;
}
#endif

node *createlist_tail(void)
{
    
    
    node *head = (node*)malloc(sizeof(node));
    node *p = head;//必须有,不然会崩,这里指向head,后面对p的操作等同于操作head
    head->next = NULL;//加或不加不影响
    // head = NULL;//这句一定不能加
    int data;
    while (1)
    {
    
    
        node *s = (node*)malloc(sizeof(node));
        printf("please input data:");
        scanf("%d", &data);
        if(data == 0) break;
        s->data = data;
        printf("data=%d\n", s->data);
        p->next = s;
        p = s;
    }
    head = head->next;//不加遍历就会把头结点算进去
    p->next = NULL;//尾插的最后指向NULL
    return head;
}

node *createlist_head(void)
{
    
    
    node *head = (node*)malloc(sizeof(node));
    head->next = NULL;//头插的这一句话至关重要
    // head->data = 0;
    int data;
    while (1)
    {
    
    
        printf("please input data:");
        scanf("%d", &data);
        if(data == 0) break;
        printf("data=%d\n", data);
        node *s = (node*)malloc(sizeof(node));
        s->data = data;
        /*最开始head->next是指向NULL的,因为是头插,所以第一个来的节点就是尾巴,这里让第一个节点保存head->next
        就相当于让第一个节点的next指向NULL,后面再来的节点就不会指向NULL了*/
        s->next = head->next;
        head->next = s;//让头结点更改方向指向新节点,这里为什么不能是head->next=s->next还没想通
        // s = s->next;//加不加无所谓   
    }
    head = head->next;//不加的话,遍历会把头结点算进去
    return head;
}

void print(node *head)
{
    
    
    while (head != NULL)
    {
    
    
        printf("output=%d\n", head->data);
        head = head->next;
    }
}

void print_t(node *head)
{
    
    
    node *p = head->next;
    printf(":%d\n", head->data);
    while (p != NULL)
    {
    
    
        printf("=%d\n", p->data);
        p = p->next;
    }
    // printf("=%d\n", head->data);
    // while (head->next != NULL)
    // {
    
    
    //     printf("out=%d\n", head->data);
    //     head = head->next;
    // }
}

int getlenlist(node *head)
{
    
    
    int len = 0;
    while (head != NULL)
    {
    
    
        head = head->next;
        len++;
    }
    return len;    
}
#if 0 
node *reverselist(node *head)
{
    
    
    if(head == NULL) return NULL;
    node *ptr_pre = head;
    node *ptr_cur = head->next;
    if(ptr_cur == NULL) return head;
    node *ptr_next = ptr_cur->next;
    ptr_pre->next = NULL;
    while (ptr_next != NULL){
    
    
        ptr_cur->next = ptr_pre;
        ptr_pre = ptr_cur;
        ptr_cur = ptr_next;
        ptr_next = ptr_next->next;
    }
    ptr_cur->next = ptr_pre;
    return ptr_cur;
}
#endif
node *reverselist(node *head)
{
    
    
    if(head == NULL || head->next == NULL) return head;
    /*这一步包含了很多信息,reverselist函数返回的是一个指针,指针指向了头结点*/
    node *p = reverselist(head->next);
    /*明白了上面那一步,这一步就好理解了,将尾结点的next指针指向尾结点的前一个结点*/
    head->next->next = head;
    /*将尾结点的前一个结点的next指针指向NULL*/
    head->next = NULL;
    /*开始递归,直到链表的头结点变成尾结点结束*/
    return p;
}
#endif

int main(int argc, char const *argv[])
{
    
    
#if 1
    node * p = createlist_tail();
    // node *p = createlist_head();
    print(p);
    int len = getlenlist(p);
    printf("len=%d\n", len);
    p = reverselist(p);//递归方法需要用指针接收
    print_t(p);
    len = getlenlist(p);
    printf("len=%d\n", len);
#endif
    return 0;
}

头插与尾插的区别已经做了注释,反转有循环与递归,递归的写法简洁了很多。

猜你喜欢

转载自blog.csdn.net/cp_srd/article/details/105497101