翻转链表


一、原地翻转

时间复杂度O(n);

void reverse(List *l) {
    if (l == NULL) return ;//链表不存在,退出函数
    Node *p = l->head.next, *q;
    l->head.next = NULL;
    while (p != NULL) {
        q = p->next;
        p->next = l->head.next;
        l->head.next = p;
        p = q;
    }
    return ;
}

测试

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h> 
#include <time.h>

//结构定义
typedef struct Node { //节点 
    int data;
    struct Node *next;
} Node;

typedef struct List { //链表
    Node head; //定义虚拟头节点
    int length; //当前链表的长度
} List;

//结构操作
Node *getnewNode(int val) { //节点初始化 
    //将待插入的val封装为节点 
    Node *node = (Node *)malloc(sizeof(Node));
    node->data = val;
    node->next = NULL; 
    return node;
}

List *init_List() { //链表初始化 
    List *l = (List *)malloc(sizeof(List));
    l->head.next = NULL;
    l->length = 0;
    return l;
} 

int insert(List *l, int ind, int val) {
    if (l == NULL) return 0;
    if (l->length < ind || ind < 0) return 0;
    Node *p = &(l->head), *node = getnewNode(val);
    while (ind--) p = p->next;
    node->next = p->next;
    p->next = node;
    l->length += 1;
    return 1;
}


void clear_node(Node *node) { //节点销毁 
    if (node == NULL) return ;
    free(node);
}

int erase(List *l, int ind) {
    if (l ==NULL) return 0;
    if (ind < 0 || ind >= l->length) return 0;
    Node *p = &(l->head), *q;
    while (ind--) p = p->next;
    q = p->next;
    p->next = q->next;
    clear_node(q);
    l->length -= 1;
    return 1;
    
}

void clear_list(List *l) { //链表销毁 
    if (l == NULL) return ;
    Node *p = l->head.next, *q;
    while (p != NULL) {
        q = p->next;
        clear_node(p);
        p = q;
    }
    free(l);
    return ;
}

void output(List *l) {
    if (l == NULL) return ;
    printf("链表长度%d\n", l->length);
    for (Node *p = l->head.next; p != NULL; p = p->next) {
        printf("%d->", p->data);
    }
    printf("NULL\n");
    return ;
} 

void reverse(List *l) { //原地翻转 
    if (l == NULL) return ;
    Node *p = l->head.next, *q;
    l->head.next = NULL;
    while (p != NULL) {
        q = p->next;
        p->next = l->head.next;
        l->head.next = p;
        p = q;
    }
    return ;
} 

int main() {
    srand(time(0));
    List *l = init_List();
    #define MAX_N 30
    for (int i = 0; i < MAX_N; i++) {
        int val = rand() % 100;
        int ind = rand() % (l->length + 3) - 1;
        int op = rand() % 4;
        switch(op) {
            case 1 :
            case 2 : {
                printf("插入位置 %d, 插入元素 %d, %s\n", ind, val, insert(l, ind, val) ? "插入成功" : "插入失败");
            } break;
//            case 3 : {
//                printf("删除位置 %d, %s\n", ind, erase(l, ind) ? "删除成功": "删除失败");
//            } break;
            case 0 : {
                printf("翻转链表\n");
                reverse(l);
            } break;
        }
        output(l), printf("\n"); //输出链表 
    }
    #undef MAX_N
    clear_list(l);
    return 0; 
}

二、头插法

建立新的链表


文章作者: Axieyun
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Axieyun !
评论
评论
  目录