翻转链表作为,链表的常用操作,也是面试常遇到的。

分析
非递归分析:

非递归用的小技巧比较多,很容易出错。

递归分析比较简单,在代码里面

代码:

#include<stdio.h>
#include<stdlib.h>
typedef int elemtype;
typedef struct node{
elemtype element;
struct node*next;//写成node* next;node * next;node *next;也是可以的,为了方便阅读,以后统一写成elemtype* element。'*',';',',''=','->'等等这些特殊意义的关键字符语法规则差不多,本身具有分割意义,两旁加空格与不加空格的意义是一致的,也就是说空格对这些特殊字符是不起作用的,而解析编译器,运行器也不是利用空格来分割的;标志符是不能用这些字符,为了方便阅读,不会看的一驼屎,最好在这些特殊的字符两旁加空格。
}node;//这个类型名与其的结构体名可以一样,不矛盾。 /*Function:将链表所有结点从头结点顺序打印,遍历链表。traverse_linkedList
*遍历一种数据机构,进去看一看,给人说一说,一般遍历打印里面的数据,知道是进去,可以拿到里面的数据。
*这种数据结构有很多数据元素,但每次遍历只能访问一个元素,因此要循环,而且要访问所有的结点,必须有一种机制从一个结点跳到另一个结点。
*@paramb:node* phead :链表首地址,首结点地址。
*/
void traverse_linkedList(node* phead){
node *p=phead ;//定义一个跳转控制指针
if (NULL == p){
printf("亲,链表为空\n");
return ;
}
else{
while(NULL != p){ printf("%d\n",p -> element);//访问结构体的数据,可以用: 其结构体变量.成员变量;还可以:指向这个结构体的指针 -> 成员变量
p = p -> next ;
}
} }
/*Function:翻转链表(非递归) reverse_linkedList
*param:node** phead //参数意义:保存链表指针变量的地址
*return: void
*
*知识点:node** p;p代表链表指针变量的地址。*p才是链表。**p 代表结点(可以认为"*"具有解析功能)
*整体的思路:重整结点的关系,原来从左指向右,翻转后从右指向左;原来指向头结点,翻转后指向尾结点
*
*时间复杂度:O(n)
*
*
* */
void reverse_linkedList(node** phead){//存链表头的指针变量的地址传过来,旨在能改变这个变量,指针本质上是存地址的变量。
node *pLeft,*pRight,*pMiddle;//定义三个指针: 左中右,pRight:作移动。
pLeft=pRight=*phead;
//空链表或者只有一个结点
if(NULL == pLeft || NULL == ( pLeft -> next)){
return ; }else{
//头的结点的处理
pLeft = *phead ;
pRight = (*phead) -> next ; //' ->'优先级最高
pLeft -> next = NULL ; //循环控制条件
node *ctl=pRight;
while(NULL != ctl){
pMiddle = pRight ;// 在移动前,先保存
pRight = pRight -> next ;// pRight移动到下一个结点
ctl = pMiddle -> next; //在变换关系前,先把控制的信息存起来
pMiddle -> next = pLeft ; //变换关系
pLeft = pMiddle ; // p变换
} *phead = pLeft ; //指向链表头指针变量,指向新的头。
}
}
/*
*Function:翻转链表(递归) reverse_recursive_linkedList
*param:node* head
*return: node*
*
*知识点:
*递归:自身调用自身;出口。
*思考:
*
*如果链表是空链表或者只有一个结点,就可以直接的返回表头;如果是两个结点以上链表,调用自身,拿到子结点的表头,再重建他们的关系。
*
* */
node* reverse_recursive_linkedList(node * head){
if(head == NULL || head -> next == NULL){
return head ;
}
else{
node* second = head -> next ;
node* new_head = reverse_recursive_linkedList(second);
second -> next = head ;
head -> next = NULL ;
return new_head ;
}
}
int main()
{
node *p , *q , *head;//仅仅定义了几个指针变量,系统做了哪些工作呢?开辟这些指针变量类型所需的空间。若没有初始值一般由系统随机分配值,还没有指向真正的结点,也就是说 p -> 成员变量是没有意义的。会报""; node 类型的声明,告诉系统作对应的语法检查,该怎么处理指针指向的内容。
// insert 10 nodes
//创建结点,结点本质上是数据块,这些数据是占用空间的,有了储存空间,就有了数据载体。所以开辟空间是创建数据的关键,然后告诉系统你怎么来处理这块空间,最后空间开辟成功。
p = q = (node* )malloc(sizeof(node)) ;//与” 数据类型 标识符“ 创建的差别,无标识符,要手动开空间,并提取信息。标识符功能:解析+地址。
head = p ;
p -> element = ;
int i=;
for ( i = ;i < ; i++){ q = (node* )malloc(sizeof(node)) ;
q -> element = i + ;
p -> next = q ;
p = q ; } traverse_linkedList(head);
reverse_linkedList(&head);//&只能作取址用,没有解析功能。
traverse_linkedList(head);
traverse_linkedList(reverse_recursive_linkedList(head));
}

本人在重拾C,很多东西看是熟悉而又陌生,所以注释比较多一点,仅供参考,不爽直接忽略,

C语言递归,非递归实现翻转链表的更多相关文章

  1. Reverse Linked List 递归非递归实现

    单链表反转--递归非递归实现 Java接口: ListNode reverseList(ListNode head) 非递归的实现 有2种,参考 头结点插入法 就地反转 递归的实现 1) Divide ...

  2. 【数据结构】——搜索二叉树的插入,查找和删除(递归&非递归)

    一.搜索二叉树的插入,查找,删除 简单说说搜索二叉树概念: 二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右 ...

  3. java:合并两个排序的链表(递归+非递归)

    //采用不带头结点的链表 非递归实现 public static ListNode merge(ListNode list1,ListNode list2){ if(list1==null) retu ...

  4. Java实现二叉树的创建、递归/非递归遍历

    近期复习数据结构中的二叉树的相关问题,在这里整理一下 这里包含: 1.二叉树的先序创建 2.二叉树的递归先序遍历 3.二叉树的非递归先序遍历 4.二叉树的递归中序遍历 5.二叉树的非递归中序遍历 6. ...

  5. 二叉树的先序、中序以及后序遍历(递归 && 非递归)

    树节点定义: class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } } 递归建立二 ...

  6. 二叉树——遍历篇(递归/非递归,C++)

    二叉树--遍历篇 二叉树很多算法题都与其遍历相关,笔者经过大量学习.思考,整理总结写下二叉树的遍历篇,涵盖递归和非递归实现. 1.二叉树数据结构及访问函数 #include <stdio.h&g ...

  7. 树的广度优先遍历和深度优先遍历(递归非递归、Java实现)

    在编程生活中,我们总会遇见树性结构,这几天刚好需要对树形结构操作,就记录下自己的操作方式以及过程.现在假设有一颗这样树,(是不是二叉树都没关系,原理都是一样的) 1.广度优先遍历 英文缩写为BFS即B ...

  8. 全排列问题(递归&非递归&STL函数)

    问题描述: 打印输出1-9的所有全排序列,或者打印输出a-d的全排列. 思路分析: 将每个元素放到余下n-1个元素组成的队列最前方,然后对剩余元素进行全排列,依次递归下去. 比如:1 2 3 为例首先 ...

  9. 二叉树的递归,非递归遍历(java)

    import java.util.Stack; import java.util.HashMap; public class BinTree { private char date; private ...

  10. 二叉树的递归,非递归遍历(C++)

    二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的.对于二叉树,有前序.中序以及后序三种遍历方法.因为树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易 ...

随机推荐

  1. 一个简易的MysQL性能查询脚本

    如下: #!/bin/sh mysqladmin -P3306 -uroot -p ext |\ awk -F"|" \ "BEGIN{ count=0; }" ...

  2. Windows 使用 Yeoman generators 创建 ASP.NET 应用程序

    上一篇:<Windows 搭建 .NET 跨平台环境并运行应用程序> 阅读目录: Install Node.js Install yeoman-generators Create ASP. ...

  3. lamp 环境搭建

    LAMP指的Linux(操作系统).ApacheHTTP 服务器,MySQL(数据库软件)和PHP语言 使用wampserver软件,搭建环境.如下图: 双击程序包,安装最后一步随便选择一个浏览器打开 ...

  4. APP接口自动化测试JAVA+TestNG(一)之框架环境搭建

    前言 好久不曾写点啥,去年换到新公司组测试团队与培养建设花费大量时间与精力,终于架构成型与稳定有时间可以打打酱油了.很久没有总结点啥,提笔想写的内容太多,先放APP接口自动化的内容吧,这个估计大家比较 ...

  5. SQL Server基础之《视图的概述和基本操作》

     数据库中的视图是一个虚拟表.同真实的表一样,视图包含一系列带有名称的列和行数据,行和列数据用来自由定义视图和查询所引用的表,并且在引用视图时动态产生.本篇将通过一些实例来介绍视图的概念,视图的作用, ...

  6. SQL Server基础之游标

    查询语句可能返回多条记录,如果数据量非常大,需要使用游标来逐条读取查询结果集中的记录.应用程序可以根据需要滚动或浏览其中的数据.本篇介绍游标的概念.分类.以及基本操作等内容. 一:认识游标   游标是 ...

  7. jQuery-1.9.1源码分析系列(十) 事件系统——事件绑定

    事件绑定的方式有很多种.使用了jQuery那么原来那种绑定方式(elem.click = function(){...})就不推荐了,原因? 最主要的一个原因是elem.click = fn这种方式只 ...

  8. 十大经典排序算法总结(JavaScript描述)

    前言 读者自行尝试可以想看源码戳这,博主在github建了个库,读者可以Clone下来本地尝试.此博文配合源码体验更棒哦~~~ 个人博客:Damonare的个人博客 原文地址:十大经典算法总结 这世界 ...

  9. LaTeX

    毕业论文用LaTeX编辑,方便使用,专注于内容.无须分心于格式. 字符 - Char 希腊符号 加粗 \usepackage{amsmath} \boldsymbol{\sigma} \usepack ...

  10. 关于Spring/Hibernate 3.x升级4.x的小问题

    情景:   之前版本 现在版本 JDK 1.7 1.8 Tomcat v7.0 v8.0 Spring 3.x 4.x Hibernate 3.x 4.x MySQL 忘了 5.1.53 分析: 如果 ...