目录:

  • 前言
  • 一、顺序表(数组)
    • (一)双指针
  • 二、单链表
    • (一)模拟顺序表的双指针(交换的节点的值域)
    • (二)头插法(改变节点的指针域)
    • (三)递归实现(将整体链表反向)
    • 整体代码
  • 总结

前言

打怪升级第一天:
大家好,今天我们来了解一下数组和单链表的原地逆置问题。
那么首先:何为原地逆置?
就是在不创建额外的数组或链表,在空间复杂度为O(1)的情况下完成逆置,
下面我们实际操作起来。


一、顺序表(数组)

(一)双指针

示例:

void Reverse(int arr[], int n)
{int left = 0;//可以使用指针,也可以使用下标int right = n - 1;while (left < right)//左右下标重合表明交换完毕{int con = arr[left];arr[left] = arr[right];arr[right] = con;left++;right--;}
}int main()
{int arr[100] = { 0 };printf("请输入数组元素的个数:");int n = 0;scanf("%d", &n);int  i = 0;for (i = 0; i < n; i++)scanf("%d", arr + i);Reverse(arr, n);printf("逆置结果:");for (i = 0; i < n; i++)printf("%d ", arr[i]);printf("\n");return 0;
}

图解 + 运行实例:


二、单链表

(一)模拟顺序表的双指针(交换的节点的值域)

为了方便阅读,前面只给出主要代码,整体代码会放到文章最后。

示例:

//模拟顺序表双指针
void Reverse(LN* left, int num)
{int con = 0;while (con < num / 2){LN* right = left;int i = 1;while (i < num - 2 * con)//寻找需要交换的右边的节点{right = right->next;i++;}int tmp = left->data;left->data = right->data;right->data = tmp;left = left->next;con++;}
}

图解:

(二)头插法(改变节点的指针域)

示例:

//打断链表,以头插法进行插入
void Reverse(LN* ph)
{LN* paim;//需要插入的节点LN* ptr;//下一个节点paim = ph->next;ph->next = NULL;//先将头结点置空,之后在头结点之后进行插入while (paim){ptr = paim->next;paim->next = ph->next;ph->next = paim;paim = ptr;}
}

图解:

(三)递归实现(将整体链表反向)

示例:

//递归实现,由于无法从后一个节点找到前一个节点,所以从倒数第二个节点开始操作
LN* Reverse(LN* ph)
{if (ph == NULL || ph->next == NULL)//终止递归的条件{return ph;//最后一个节点不在这一步进行操作}LN* pend = Reverse(ph->next);ph->next->next = ph;ph->next = NULL;return pend;//返回最后一个节点的指针
}

图解:

整体代码

#define MALLOC(ty,num) (ty*)malloc(sizeof(ty)*(num))//原地逆序:单链表typedef struct LinkedNode
{int data;struct LinkedNode* next;
}LN;void Init(LN* ph, int num)
{for (int i = 0; i < num; i++){LN* ptr = MALLOC(LN, 1);if (ptr == NULL){perror("Init::MALLOC");exit(1);}printf("请输入第%d个节点值:", i + 1);scanf("%d", &ptr->data);ptr->next = NULL;ph->next = ptr;ph = ptr;}
}void Print(LN* ph)
{LN* p = ph->next;printf("结果:");while (p != NULL){printf("%d ", p->data);ph = p;p = p->next;free(ph);}
}//递归实现,由于无法从后一个节点找到前一个节点,所以从倒数第二个节点开始操作
LN* Reverse(LN* ph)
{if (ph == NULL || ph->next == NULL)//终止递归的条件{return ph;}LN* pend = Reverse(ph->next);ph->next->next = ph;ph->next = NULL;return pend;//返回最后一个节点的指针
}打断链表,以头插法一个一个得插入
//void Reverse(LN* ph)
//{//  LN* paim;//即将插入的节点
//  LN* ptr;//下一个节点
//  paim = ph->next;
//  ph->next = NULL;
//  while (paim)
//  {//      ptr = paim->next;
//      paim->next = ph->next;
//      ph->next = paim;
//      paim = ptr;
//  }
//}在变化过程中链表一直未打断,,但是过于复杂
//void Reverse(LN* ph)
//{//
//  LN* ptr = ph->next;
//  while (ptr->next)
//  {//      LN* p1 = ph->next;
//      LN* p2 = ptr->next;
//      ph->next = ptr->next;
//      ptr->next = ptr->next->next;
//      p2->next = p1;
//  }
//}模拟顺序表双指针
//void Reverse(LN* left, int num)
//{//  int con = 0;
//  while (con < num / 2)
//  {//      LN* right = left;
//      int i = 1;
//      while (i < num - 2 * con)//寻找需要交换的右边的节点
//      {//          right = right->next;
//          i++;
//      }
//      int tmp = left->data;
//      left->data = right->data;
//      right->data = tmp;
//      left = left->next;
//      con++;
//  }
//}//带头单链表:原地逆置
int main()
{LN* head = MALLOC(LN, 1);//头结点if (head == NULL){perror("main::MALLOC");exit(1);}head->next = NULL;printf("请输入与节点个数:");int num = 0;scanf("%d", &num);Init(head, num);//Reverse(head->next, num);//Reverse(head);head->next = Reverse(head->next);//从头结点后一个节点开始逆置Print(head);free(head);return 0;
}

运行实例:


总结

以上就是今天讲解的线性表逆置的全部内容,如果有什么疑问或者建议都可以在评论区留言,感谢大家对的支持。

【线性表的原地逆置】相关推荐

  1. 每日程序C语言43-链表原地逆置

    题目: 反向输出一个链表-原地逆置 程序分析 在我们创建链表的时候使用头插法创建的链表,其顺序就是逆序的,我们可以在该链表的基础上进行逆置 主要代码 main.c typedef struct Nod ...

  2. 借助栈实现单链表的原地逆置

    借助栈实现单链表的原地逆置 [问题描述]首先建立一个单链表,通过栈实现该链表的原地逆置,注意仅使用链表中的原有的结点空间,结点的数据成员为int型.注意这个题需要单链表和栈两个类. [输入形式]输入只 ...

  3. 数据结构:顺序表的就地逆置

    顺序表的就地逆置 前言 用于个人作业记录 题目 Chapter 2, HLOJ 9503,例2.6.1 顺序表的就地逆置 试写一算法,实现顺序表的就地逆置,即利用原表的存储空间将线性表(a1,a2,- ...

  4. 【顺序表】顺序表的就地逆置

    编写算法实现顺序表的就地逆置,即利用原顺序表的存储单位把数据元素顺序反向,例如:1,5,6,9,8逆置为 8,9,6,5,1 题目分析: 就地逆置,就是指借用顺序表自身实现顺序逆置,不借助其他线性表. ...

  5. C++ 头插法建立单链表,单链表原地逆置以及尾插法建立单链表

    #include <iostream> #include <stdlib.h> #include <cstdio> typedef int ElemType; us ...

  6. Java顺序表就地逆置_顺序表的就地逆置问题

    问题描述:编写一个顺序表的成员函数,实现对顺序表就地逆置的操作.所谓逆置,就是把(a1,a2,a3,...,an)变成(an,an-1,..,a2,a1):所谓就地,即逆置后的数据元素仍在原来顺序表的 ...

  7. 顺序表的应用——逆置问题

    顺序表应用--逆置问题 问题描述 给定一个顺序表,将其中的元素逆置 例子 给定一个顺序表,其中有0至10共11个元素从小至大排列,请将这11个元素逆置使其从大到小排列 以下是解题代码 代码 #incl ...

  8. 55-将单链表原地逆置(三种方法)

    方法1:用三个指针实现单链表(有头结点)的逆置 void Reverse(HeadList *head) {if(head==NULL||head->next==NULL||head->n ...

  9. 单链表的应用 就地逆置

    [问题描述]试实现线性表的就地逆置算法,即在原表的存储空间将线性表(a1,a2,a3....an)逆置为(an...a3,a2,a1).    [分析]就地逆置就是不需要额外申请结点空间,只需要利用原 ...

最新文章

  1. TVM如何训练TinyML
  2. 二十二、死锁的处理策略----预防死锁
  3. Python解释器种类以及特点?
  4. Destroying the bus stations
  5. 【Blog.Core重要升级】:封装服务扩展层
  6. java即时编译器_Java即时编译:不仅仅是一个流行词
  7. java提取图片中的文字,深入分析
  8. linux内核ufs设备树,Linux内核初始化流程笔记
  9. endless admin_一次中国之旅如何激发Endless OS并教孩子们黑客
  10. UC为什么一直开发html游戏,为什么很多人都喜欢用UC浏览器?老玩家告诉你原因...
  11. @SessionAttributes
  12. #运行后闪退_王者ios14苹果手机闪退已修复,腾讯痛失百万玩家能否再回来
  13. vc++6.0如何调试
  14. android 线程使用监控思路分享
  15. PGIS 天地图主题颜色背景修改 图片 filter 蓝色 HTML CSS IMG filter 颜色矩阵在线计算 RGBA转换 SVG  feColorMatrix
  16. 迷你迅雷,IE下载加速补丁(转)
  17. Vim简单介绍和使用方法
  18. 字符串与vector和list
  19. 认证模式之Digest模式
  20. 忘记svn密码怎么办

热门文章

  1. 【深度学习】-Imdb数据集情感分析之模型对比(2)- LSTM
  2. 配送中心(Distribution center)
  3. [机缘参悟-27]:鬼谷子-反应篇-反说之术,以毒攻毒,以错推错
  4. win10任务栏点击右键无反应解决方法
  5. Latex插入参考文献的两种方法—自动与手动
  6. 工银e生活开发脱坑日志(4)工行页面及jsAPI交互接口hybrid_app.js登录情况说明
  7. C#游戏《坦克大战》--地图
  8. html大作业网页代码——电竞游戏介绍响应式网页(7页) HTML+CSS+JavaScript
  9. Python实现的深度学习技术在水文水质领域应用
  10. oppo手机如何开启云服务器,oppor7关闭云服务器(oppo云相册怎么关闭)