简单算法 - 链表逆序思路详解

1.1.1            链表逆序

1.1.1.1           思路

A->B->C->D->E

一般会有以下两种思路,如下

思路一:

先取出链表的最后一个E,然后将E作为新链表的头,

现在状态为

原始链表:A->B->C->D

新链表:E

再取出原来链表的最后一个D,然后将D插入到新链表的最后位置,

现在状态为

原始链表:A->B->C

新链表:E->D

依次类推,最后形成E->D->C->B->A

很显然,这个算法的复杂度为O(n2)

 

思路二:

取出原始链表的第一个节点A,然后将该节点作为新链表的头节点。

现在状态为

原始链表:B->C->D->E

新链表:A

然后同上,变为了下面的状态

原始链表:C->D->E

新链表: B->A

原始链表:D->E

新链表: C->B->A

原始链表:E

新链表: D->C->B->A

原始链表:

新链表: E->D->C->B->A

很显然,对原始链表遍历一次,就完成了这个工作,所以这个算法的复杂度为O(n)

1.1.1.2           程序思路

对思路二进行程序设计。

通过对上面状态的变化分析,只要我们知道原始链表和新链表的头节点,我们就可以从原始链表取出第一个节点,然后将节点插入到新链表的第一个位置,由于两个链表的头结点现在都已经变化,所以我们不能丢失新头节点的地址。所以,我们要设置两个变量分别记录两个链表的头结点。下面程序中的old_head new_head分别表示原始链表的头节点和新链表的头节点。

程序如下,实现了迭代方式和递归方式:

/*
 *
 * Introduction : reverse list
 * Author : Gykimo
 * Date : 20121212
 *
 */
 
#include <stdio.h>
#include <malloc.h>
 
typedef struct Node{
         int data;
         struct Node* next;
}Node;
 
#define LIST_LEN     10     //链表长度
Node * List = NULL;          //链表
 
//迭代方式
void reverse_ite(Node * list){
         Node * old_head = NULL;         //原来链表的头
         Node * new_head = NULL;      //新链表的头
         Node * cur = list;      //获得原来链表的头
        
         //每次将原来链表的头取出,并插入到新链表中,并且是新链表的头
         while(cur != NULL){
                   old_head = cur->next;      //将原来链表的头取出,并将第二个节点作为头节点
                   cur->next = new_head;   //将取出的头设为新链表的头
 
                   new_head = cur;      //新链表的头就是目前新链表的头
                   cur = old_head;        //接着处理
         }
 
         List = new_head;
}
 
//递归方式
void reverse_recursive(Node * old_head, Node * new_head){
         if(old_head == NULL){
                   List = new_head;
                   return;
         }
 
         Node * tmp = old_head->next;        //将原来链表的头取出,并将第二个节点作为原来链表的头节点用于下一层递归
         old_head->next = new_head; //将取出的头设为新链表的头
         reverse_recursive(tmp, old_head);         //接着处理
}
 
//生成链表
void make_list(){
         List = (Node *)malloc(sizeof(Node) * LIST_LEN);
         int i = 0;
         for(i = 0; i < (LIST_LEN - 1); i++){
                   (List + i)->data = i + 1;
                   (List + i)->next = List + i + 1;
         }
         (List + LIST_LEN - 1)->data = LIST_LEN;
         (List + LIST_LEN - 1)->next = NULL;
}
 
//打印俩表的data
void print_list(){
         Node * cur = List;
         while(cur!=NULL){
                   printf("%d ", cur->data);
                   cur = cur->next;
         }
         printf("\n");
}
 
int main(){
         make_list();
         print_list();
         reverse_ite(List);     //迭代方式
         //reverse_recursive(List, NULL);     //递归方式
         print_list();
}



  • 8
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值