链表 单链表反转

思路1:O(n^2).

“狸猫换太子”,不进行改动链表结构,只首尾交换len/2次。但是在本函数中用到了定位函数,定位函数实际上是遍历了一遍整个链表,所以综合效率很低,达到O(n^2).

//单链表反转(O(n^2))
void reverseList(Node* Head)
{
   int count = numOfNodes(Head);
   //首尾交换
   for(int i=1; i<=count/2; i++)
   {
      Node* p1 = locateNodeI(Head, i);
      Node* p2 = locateNodeI(Head, count+1-i);
      swap(p1->value, p2->value);
   }
}

思路2:O(n).

就最一般的情况而言(没有之前写的辅助函数,即条件单纯为只有Head指向一个单链表)。可以实现O(n)效率。

做法是用三个相邻的指针进行遍历,在遍历的途中,更改指针方向。当然要注意链表数目分情况,和拆链的处理。

//单链表反转(O(n))
Node* reverseList2(Node* Head)
{
   if(Head==NULL || Head->next==NULL) //空链和单节点
   {
      return Head;
   }
   Node* p1 = Head;
   Node* p2 = Head->next;
   Node* p3 = Head->next->next;

   if(p3==NULL) //只有两个节点
   {
      p1->next = NULL;
      p2->next = p1;
      Head = p2;
      return Head;
   }
   else //至少三个节点
   {
      p1->next = NULL;
      while(p3!=NULL)
      {
         p2->next = p1;
         //三个指针依次向后移一位
         p1=p2;
         p2=p3;
         p3=p3->next;
      }
      p2->next = p1;
      Head = p2;
      return Head;
  }
}
时间: 2024-12-22 15:32:36

链表 单链表反转的相关文章

链表-单链表的各种操作

单链表的结构体的定义 typedef struct LNode { ElemType data; struct LNode *next; }LinkList; 基本的单链表的操作 /* 功能:构建一个空的带头节点的单链表*/ Status InitList (struct LNode **L) { (*L) = (struct LNode *)malloc(sizeof(struct LNode)); //产生头节点 if(!*L) exit(OVERFLOW); (*L)->next = NU

链表 - 单链表逆序

单链表逆序是经典的链表操作算法,单链表逆序的算法思想是将链表箭头反指(假设next指针是一个箭头),即所谓的改链,改链过程如下. 逆序前: head-->......prev-->cur-->next-->......->NULL 逆序后: NULL<--......prev<--cur<--next<--......head 算法逻辑: 1.空链表或只有一个元素,返回原链表head. 2.定义3个指针prev.cur.next,初始化时,prev指向

链表——单链表的排序

题目要求: 对单链表进行从小到大排序,要求时间复杂度O(N*logN),空间复杂度O(1): 思路: 因时间复杂度要求为O(N*logN),简单排序(时间复杂度为O(N*N))均不可用, 故可以考虑归并排序的思想,归并排序对数组操作空间复杂度为O(n),但对链表为O(1),因为每次只在merge函数中创建了一个辅助的链表头结点ListNode temp=new ListNode(0); 归并排序的一般步骤为: 1)将待排序数组(链表)取中点并一分为二: 2)递归地对左半部分进行归并排序: 3)递

链表—单链表

代码实现: 首先定义一个Node类: public class Node { protected Node next; //指针域 public int data;//数据域 public Node( int data) { this. data = data; } //显示此节点 public void display() { System. out.print( data + " "); } } 接下来定义一个单链表,并实现相关方法: public class LinkList {

【数据结构】线性链表(单链表)

// // main.cpp // LinkList // // Created by T.P on 2019/1/31. // Copyright ? 2019 T.P. All rights reserved. // #include <stdio.h> #include <stdlib.h>//malloc free #define TRUE 1 #define FALSE 0 #define OK 0 #define ERROR -1 #define INFEASIBLE

数据结构 线性结构(数组[列表] ,链表 单链表的增删改查**, 线性结构的应用 队列 栈[函数的调用**]),非线性结构 树

数据结构 参考:http://lupython.gitee.io/ 线性结构 就是能够用一根线串起来的数据结构 数组 (列表) 问:申请数组的前提条件是啥? a[12]?内存需要满足的条件? 答:内存必须有一块连续的内存空间 int a[7] : 声明一个数组,这个数组的数组名是 a, 数组的大小是 7, 数组元素的类型是整型. int a[7] = array(1,2,3,4,5,6,7) 问:如何申请内存? 答:C,C++语言,申请:mallco (28).释放:free(28) 问:int

leetcode之链表-单链表反转-C++

ReverseLinked List A linked list can be reversed eitheriteratively or recursively. Could you implement both? 迭代版本: 1. /** 2. * Definition for singly-linked list. 3. * struct ListNode { 4. * int val; 5. * ListNode *next; 6. * ListNode(int x) : val(x),

数据结构之链表---单链表的实现

public class Link { /** * 链结点 */ private int iData; private double dData; public Link next; public Link(int iData,double dData) { this.dData = dData; this.iData = iData; } //打印节点 public void displayLink() { System.out.println("{"+iData+",&q

使用OC实现单链表:创建、删除、插入、查询、遍历、反转、合并、判断相交、求成环入口

一.概念 链表和数组都是一种线性结构,数组有序存储的,链表是无序存储的. 数组中的每一个元素地址是递增或者递减的关系,链表的每一个节点的地址没有此规律,它们是通过指针的指向连接起来. 链表种类:单链表.双向链表.循环链表.双向循环链表 单链表:一个数据域data.一个后继指针域next.也即:上一个节点指向下一个节点,尾节点指向空. 双向链表:一个数据域data.一个前驱指针域previous.一个后继指针域next.也即:上一个节点和下一个节点互相指向,尾节点指向空. 循环链表:一个数据域da