单链表操作-单链表反转问题?

来源:互联网 发布:手机 济宁网络问政 编辑:程序博客网 时间:2024/05/20 19:48

单链表:
typedef struct node{
      int data;
      struct node* next;
}LNode;

关于但链表的操作很多(增删改查,逆序,子交并补等,以及一些经典的变式),考研题目中,有很多好的算法值得学习。

下面是C语言实现的, 采用一个method,一个test_method,方便逐个学习,这个需要不断的积累,最好用敲几遍,再在纸上多写写,只有能自己完全的写出来,才是完全的掌握。

#include <stdio.h>#include <stdlib.h>typedef struct node{    int data;    struct node* next;}LNode;LNode* newNode(int data){    LNode* tmp = (LNode*)malloc(sizeof(LNode));    if(tmp!= NULL)    {        tmp->data = data;        tmp->next = NULL;    }    return tmp ;}// 头插法LNode* insert1(int a[],int len){    LNode* head = newNode(0);    int i;    for(i = 0 ; i < len ; i ++)    {        int data = a[i];        LNode *tmp = newNode(data);        tmp->next = head->next;        head->next = tmp;    }    return head;}// 尾插法LNode* insert2(int a[],int len){    LNode* head = newNode(0);    LNode* rear = head;    int i;    for(i = 0 ; i < len ; i ++)    {        int data = a[i];        LNode *tmp = newNode(data);        rear->next = tmp ;        rear = tmp ;    }    return head;}void printLink(LNode* head){    if(head == NULL || head->next == NULL)    {        printf("Empty\n");        return ;    }    LNode* t = head->next;    while(t != NULL)    {        printf("%d ",t->data);        t = t->next;    }    printf("\n");}void test_insert1(){    int a[10] = {1,3,2,7,5,4,9,2,0};    int len = 5;    LNode* head = insert1(a,len);    printLink(head);}void test_insert2(){    int a[10] = {1,3,2,7,5,4,9,2,0};    int len = 5;    LNode* head = insert2(a,len);    printLink(head);}// 直接插入排序void sortLink(LNode* head){    if(head == NULL || head->next == NULL)        return ;    LNode* r = head->next->next;//第二个元素 开始    head->next->next = NULL;    while(r != NULL)    {        int nowdata = r->data ;        LNode* pre;        LNode* scan;        for(pre = head,scan = head->next;scan != NULL;pre=pre->next,scan = scan->next)        {            if(scan->data > nowdata)            {                break;            }        }        LNode* tmp = r ;// pre 和 scan 之间插入 tmp 这个节点        r = r->next; // r 取下一个        tmp->next = scan;        pre->next = tmp ;    }}void test_sortLink(){    int a[10] = {1,3,2,7,5,4,9,2,0};    int len = 5;    LNode* head = insert2(a,len);    printLink(head);    sortLink(head);    printLink(head);}// 反转链表,也就是采用头插法void reverseLink(LNode* head){    if(head == NULL || head->next == NULL)        return ;    LNode* r = head->next->next;//第二个元素 开始    head->next->next = NULL;    while(r != NULL)    {        LNode* tmp = r; // tmp是当前要插入的        r = r->next; //  r 取下一个        tmp->next = head->next;        head->next = tmp ;    }}void test_reverseLink(){    int a[10] = {1,3,2,7,5,4,9,2,0};    int len = 5;    LNode* head = insert2(a,len);    printLink(head);    reverseLink(head);    printLink(head);}// 删除指定元素 利用pre  p  找到一个删除一个 , 查找 插入等都差不多做法void delLink(LNode* head,int deldata){    if(head == NULL || head->next == NULL)        return ;    LNode* pre = head;    LNode* scan = head->next;    while(scan!= NULL)    {        if(scan->data == deldata)        {            LNode* tmp = scan;            scan = scan->next ;            pre->next = scan;            free(tmp);        }else{            pre = scan;            scan = scan->next;        }    }}void test_delLink(){    int a[10] = {2,3,2,7,5,4,9,2,0};    int len = 5;    LNode* head = insert2(a,len);    printf("原始序列:");    printLink(head);    delLink(head,2);    printf("删除 data = 2的节点后:");    printLink(head);}/*找到倒数第k个元素(k取1到Len(len为Link长度)) 如果可以 实现需要判断下 取模等操作处理(重要) 比如 1 3 2 7 5 倒数第2个为7 倒数第4个为3*/LNode* searchLastK(LNode* head , int k){    if(head == NULL || head->next == NULL)        return NULL;    LNode* p = head->next;    LNode* q = head->next;    int i;    for(i = 0 ; i < k ; i ++) // q移动到第k个位置 这样 p q 相距为 k    {        q = q->next;    }    // p q 一起移动, q移动到链表尾部 , 则 p 就是倒数第k个节点    while(q != NULL)    {        q = q->next;        p = p->next;    }    return p;}void test_searchLastK(){    int a[10] = {2,3,2,7,5,4,9,2,0};    int len = 5;    LNode* head = insert2(a,len);    printf("原始序列:");    printLink(head);    int k = 2 ;    LNode* ln = searchLastK(head , k);    printf("倒数第%d个:%d\n",k,ln->data);}int main(){    //freopen("in.txt","r",stdin);    //test_insert1();    //test_insert2();    //test_sortLink();    //test_reverseLink();    //test_delLink();    test_searchLastK();    return 0 ;}

无头结点的链表反转

  • debug1
    这里写图片描述

  • debug2
    这里写图片描述

0 0
原创粉丝点击