不带头结点的单链表反转 三种不同方法实现

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

//头插法创建单链表 不带头结点(1+1 指针数,1个保存头结点+1个遍历指针)
LinkList *creatLinkList(int n) {//创建一个含n个元素的单链表
    LinkList *head = (LinkList *)malloc(sizeof(LinkList));
    head->data = 0;//记录链表中元素个数
    LinkList *q = head;
    for(int i = 1;i < n;i++) {
        q->next = (LinkList *)malloc(sizeof(LinkList));
        q->next->data = i;
        q = q->next;
    }
    return head;
}
//遍历单链表(不带头结点)
void PrintLinkList(LinkList *L){
    while (L != NULL) {
        printf("%d", L->data);
        L = L->next;
    }
    return;
}
//单链表反转方法一: 尾插法(递归实现)(1+1 指针数,1个指针参数+1个结点指针p)
LinkList *ReverseList (LinkList *L){
    LinkList *p = NULL;
    if (L == NULL) return NULL; //判空
    if (L->next == NULL) {
        p = L;
        return p;  // 递归到底,返回第一个结点p
    }
    p = ReverseList(L->next);  //递归,得到第一个结点p
    L->next->next = L;  //设置当前结点在后置结点之后
    L->next = NULL;    //链表尾置空
    return p;
}

//单链表反转方法二: 头插法(循环实现)(1+2 指针数,1个指针参数+2个跟踪指针)
LinkList *ReverseList_Loop(LinkList *L){
    if (L == NULL) return NULL; //判空
    LinkList *q = NULL;
    while (L != NULL) {
        LinkList *p = L;    //创建指针p指向当前结点
        L = L->next;        //当前结点右移
        p->next = q;        //指针p的next域指向q,p一直是逆序的一部分链表
        q = p;              //q换到p的位置,开始下一轮
    }
    return q;
}

//单链表反转方法三:指针反转 (循环实现) (3个指针遍历一次)
LinkList *ReverseList_Pointer(LinkList *L){
    if (L == NULL) return NULL; //判空
    //三个指针 pl用来断开后面的并保存,p和pr用来指针反转
    LinkList *pr = L;
    LinkList *p = pr->next;
    LinkList *pl = p->next;
    pr->next = NULL; //头部置空
    while (p) {
        p->next = pr;  //p和pr指针反转
        //依次往后遍历
        pr = p;
        p = pl;
        if (p!=NULL) pl = pl->next;
    }
    return pr;
}

void Reverse() {
    LinkList *head = creatLinkList(5);//创建一个含5个元素的单链表
    printf("创建后遍历:\n");
    PrintLinkList(head);
    printf("\n单链表递归反转后:\n");
    head = ReverseList(head);
    PrintLinkList(head);
    printf("\n单链表接着循环反转后:\n");
    head = ReverseList_Loop(head);
    PrintLinkList(head);
    printf("\n单链表再指针反转后:\n");
    head = ReverseList_Pointer(head);
    PrintLinkList(head);
    printf("\n");
}

你可能感兴趣的:(数据结构与算法)