zoukankan      html  css  js  c++  java
  • 链表的逆置将一个单链表逆置一下头元素不变

    void reverse(struct list *ls)//链表逆置
    {
    if (ls->next == NULL)
    return;//只有一个首节点,不需要逆置

    if (ls->next->next == NULL)
    return;//也不需要逆置

    struct list *last = ls->next;//逆置后ls->next就成了最后一个节点了

    struct list *pre = ls;//上一个节点的指针
    struct list *cur = ls->next;//当前节点的指针这个就是last节点
    struct list *next = NULL;//下一个节点的指针
    while(cur)
    {
    next = cur->next;
    cur->next = pre;
    pre = cur;
    cur = next;
    }

    ls->next = pre;
    last->next = NULL;//这个其实就是ls->next->next=null只不过这样写更加方便些
    }

    ----------------------------------------------------

    如上就是将一个单向链表的元素逆置一下,主要思想是不停的当前元素节点之前前驱节点,然后将后继节点赋值给当前节点,把当前节点当成前驱节点,把后继节点当作当前节点

    相当于把前驱节点,当前节点,后继节点整体向后移动一个节点单位,只不过后继节点在下一轮的循环中指定的,然后再把当前节点指向前驱节点,就是上一轮的后继节点指向当前节点,然后依次类推不停的循环知道最后一轮中cur等于最后一个节点,然后next=cur->next=null然后将后继节点赋值给当前节点,那么当前节点在下一轮的循环中成了空的

    就跳出循环了!

    --------------------------------------------------------------------

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

    struct list
    {
    int data;//数据域
    struct list *next;//指针域
    };

    struct list *create_list()//建立一个节点
    {
    return calloc(sizeof(struct list), 1);
    }

    struct list *insert_list(struct list *ls, int n, int data)//在指定位置插入元素
    {
    struct list *p = ls;
    while(p && n--)
    {
    p = p->next;
    }

    if (p == NULL)
    {
    return NULL;//n的位置大于链表节点数
    }

    struct list *node = create_list();//新建立一个节点
    node->data = data;
    node->next = p->next;
    p->next = node;
    return node;
    }

    int delete_list(struct list *ls, int n)//删除指定位置元素
    {
    struct list *p = ls;
    while(p && n--)
    {
    p = p->next;
    }

    if (p == NULL)
    {
    return -1;//n的位置不合适
    }

    struct list *tmp = p->next;
    p->next = p->next->next;
    free(tmp);
    return 0;//删除成功
    }

    int count_list(struct list *ls)//返回链表元素个数
    {
    struct list *p = ls;
    int count = 0;
    while(p)
    {
    count++;
    p = p->next;
    }
    return count;
    }

    void clear_list(struct list *ls)//清空链表,只保留首节点
    {
    struct list *p = ls->next;
    while(p)
    {
    struct list *tmp = p->next;
    free(p);
    p = tmp;
    }
    ls->next = NULL;//只有首节点,那么首节点的next也应该设置为NULL
    }

    int empty_list(struct list *ls)//返回链表是否为空
    {
    if (ls->next)
    return 0;
    else
    return -1;
    }

    struct list *locale_list(struct list *ls, int n)//返回链表指定位置的节点
    {
    struct list *p = ls;
    while(p && n--)
    {
    p = p->next;
    }

    if (p == NULL)
    return NULL;

    return p;
    }

    struct list *elem_locale(struct list *ls, int data)//返回数据域等于data的节点
    {
    struct list *p = ls;
    while(p)
    {
    if (p->data == data)
    return p;
    p = p->next;
    }

    return NULL;//没有找到数据域等于data的节点
    }

    int elem_pos(struct list *ls, int data)//返回数据域等于data的节点位置
    {
    int index = 0;
    struct list *p = ls;
    while(p)
    {
    index++;
    if (p->data == data)
    return index;
    p = p->next;
    }

    return -1;//没有找到数据域等于data的节点
    }

    struct list *last_list(struct list *ls)//得到链表最后一个节点
    {
    struct list *p = ls;
    while(p->next)
    {
    p = p->next;
    }
    return p;
    }

    void merge_list(struct list *ls1, struct list *ls2)//合并两个链表,结果放入ls1中
    {
    //只合并链表的节点,不合并链条头
    last_list(ls1)->next = ls2->next;
    free(ls2);//链表头不要了
    }

    void reverse(struct list *ls)//链表逆置
    {
    if (ls->next == NULL)
    return;//只有一个首节点,不需要逆置

    if (ls->next->next == NULL)
    return;//也不需要逆置

    struct list *last = ls->next;//逆置后ls->next就成了最后一个节点了

    struct list *pre = ls;//上一个节点的指针
    struct list *cur = ls->next;//当前节点的指针这个就是last节点
    struct list *next = NULL;//下一个节点的指针
    while(cur)
    {
    next = cur->next;
    cur->next = pre;
    pre = cur;
    cur = next;
    }

    ls->next = pre;
    last->next = NULL;//这个其实就是ls->next->next=null只不过这样写更加方便些
    }

    void traverse(struct list *ls)//循环遍历链表
    {
    struct list *p = ls;
    while(p)
    {
    printf("%d ", p->data);
    p = p->next;//p指向他对应的下一个节点
    }
    }

    int main(void)
    {
    struct list *first = create_list();//在堆中间创建一个节点
    struct list *second = create_list();//在堆中间创建一个节点
    struct list *third = create_list();//在堆中间创建一个节点
    first->next = second;
    second->next = third;
    third->next = NULL;//对于链表的最后一个节点,next域一定为NULL
    first->data = 1;
    second->data = 2;
    third->data = 3;

    insert_list(first, 1, 10);
    insert_list(first, 1, 20);
    insert_list(first, 1, 30);

    //delete_list(first, 2);
    //clear_list(first);

    traverse(first);
    printf("---------------- ");
    printf("count = %d ", count_list(first));
    printf("%d ", locale_list(first, 3)->data);
    printf("data = %d ", last_list(first)->data);

    printf("----------------------- ");
    struct list *first1 = create_list();
    int i;
    for(i = 0; i < 10; i++)
    {
    insert_list(first1, 0, i);
    }

    printf("---------------- ");

    merge_list(first, first1);

    printf("--------------------- ");
    traverse(first);
    printf("--------------------- ");
    reverse(first);
    traverse(first);
    return 0;
    }

  • 相关阅读:
    软件测试流程
    Python2 RF(3.0.4)与Python3 RF(3.1.2)区别
    Ubuntu Install RobotFramework with Python3
    Beta测试与Alpha测试有什么区别
    网络协议,如TCP/UDP的区别?
    缺陷相关知识
    linux_machine-id
    monkey自定义脚本实践
    Monkey事件
    Linux虚拟机fdisk分区
  • 原文地址:https://www.cnblogs.com/sengling/p/5244849.html
Copyright © 2011-2022 走看看