【算法】反转链表

问题描述

            编写带代码实现反转单链表。如 [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\n");
    
    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("\n"); printf("反转后:"); reverse_list(&list); print_list(&list); printf("\n"); delete_list(&list); return 0; }

 

测试的输入输出:

 

 

代码解析

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

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

 

 

执行reverse_list函数的步骤:

 

posted @ 2017-03-31 17:18  lulipro  阅读(649)  评论(0编辑  收藏  举报