zoukankan      html  css  js  c++  java
  • 【算法】反转链表

    问题描述

                编写带代码实现反转单链表。如 [1,2,3,4,5] 变为 [ 5,4,3,2,1 ] 

                要求空间复杂度为O(1)

    先直接给出一份完整的代码,可以直接运行。

    C:

    #include<stdio.h>
    #include<assert.h>
    #include<stdlib.h>
    
    typedef int datatype;      //链表持有的数据的类型 
    
    typedef struct node        //结点的定义 
    {
        datatype element;
        struct node*next;    
    
    }_link_node_;
     
    typedef struct             //链表的定义 
    {
        _link_node_*head;
        
        size_t size;
        
    }linkedlist;
    
    
    /**
    初始化一个带头结点的链表 
    */ 
    void init_list(linkedlist*plist)
    {
        plist->head = (_link_node_*)malloc(sizeof(_link_node_));
        assert(plist->head!=NULL);
        plist->head->next = NULL;
        
        plist->size = 0;
    }
    
    /**
    输入链表元素创建链表。 
    */
    void creat_list(linkedlist*plist)
    {
        _link_node_*p1 , *p2 ;
        
        datatype temp;
        
        
        printf("input elemments , enter '#' to stop
    ");
        
        while(1==scanf("%d",&temp))
        {
            
            
            p1 = (_link_node_*)malloc(sizeof(_link_node_));
            p1->element = temp;
            p1->next = NULL;
            
            if(plist->head->next == NULL)
                plist->head->next = p1;
        
            else 
                p2->next = p1;
            
            p2 = p1;
            
            plist->size++;
            
        }
    }
    
    /**
    打印链表 
    */
    void print_list(linkedlist* plist)
    {
        _link_node_*p = plist->head->next;
        printf("[");
        
        if(p!=NULL)
        {
            
            printf("%d",p->element);
            p = p->next;
            
            while(p!=NULL)
            {
                printf(",%d",p->element);
                p = p->next;
            }
            
        }
        printf("]");
    }
    
    /**
    求链表的长度 
    */
    size_t size_list(linkedlist* plist)
    {
        return plist->size;    
    }
    
    /**
    销毁链表 
    */ 
    void delete_list(linkedlist*plist)
    {
        _link_node_*p =  plist->head;
        _link_node_*t;
        
        
        while(p!=NULL)
        {
            t = p;
            p = p->next;
            free(t);
        }
        
    }
    /************************反转单链表********************************/
    void reverse_list(linkedlist*plist) { _link_node_* pre; //3个游标结点指针 _link_node_* cur; _link_node_* nxt; if (1<size_list(plist)) //链表数据多余1个,才有反转操作的必要 { pre = NULL; //初始状态 cur = plist->head->next; nxt = cur->next; //循环 while(NULL != nxt) { cur->next = pre; pre = cur; cur = nxt; nxt = nxt->next; } //退出循环 cur->next = pre; plist->head->next = cur; } // end if } int main(void) { linkedlist list; init_list(&list); creat_list(&list); printf("反转前:"); print_list(&list); printf(" "); printf("反转后:"); reverse_list(&list); print_list(&list); printf(" "); delete_list(&list); return 0; }

    测试的输入输出:

    代码解析

    思想是使用3个游标结点指针,一边修改结点的指针域,一边往后挪动。最后使得整个链表被反转。

    构造的初始链表结构如下:

    执行reverse_list函数的步骤:

  • 相关阅读:
    浅谈RPC和RESTFUL
    HTTP协议
    为博客园文章添加目录的方法
    Https的介绍
    【Locust】Locust学习总结
    从零开发接口自动化框架
    VMware VCSA 6.7创建和管理Clusters
    VMware ESXi 6.7主机防火墙
    VMware VCSA 6.7分布式交换机
    VMware VCSA 6.7标准交换机
  • 原文地址:https://www.cnblogs.com/lulipro/p/6652366.html
Copyright © 2011-2022 走看看