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

分析
非递归分析:

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

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

代码:

#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. jquery自定义滚动条 鼠标移入或滚轮时显示 鼠标离开或悬停超时时隐藏

    一.需求: 我需要做一个多媒体播放页面,左侧为播放列表,右侧为播放器.为了避免系统滚动条把列表和播放器隔断开,左侧列表的滚动条需要自定义,并且滚动停止和鼠标离开时要隐藏掉. 二.他山之石: 案例来自h ...

  2. Tomcat创建HTTPS访问,java访问https

    一 https和ssL HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的 ...

  3. Rafy 领域实体框架设计 - 重构 ORM 中的 Sql 生成

    前言 Rafy 领域实体框架作为一个使用领域驱动设计作为指导思想的开发框架,必然要处理领域实体到数据库表之间的映射,即包含了 ORM 的功能.由于在 09 年最初设计时,ORM 部分的设计并不是最重要 ...

  4. 轻量级ORM

    不知道可能称的上是ORM,其实就是一个DBHelper.看到网上不少人写自己的ORM,但我觉得都不太好. 我这个ORM,学习成本非常低,常用的方法仅有几个,在使用的过程中,你不需要有太多要注意的地方, ...

  5. ASP.NET多种不同页面间数据传递的方法

    1. Get(即使用QueryString显式传递)     方式:在url后面跟参数.     特点:简单.方便.     缺点:字符串长度最长为255个字符:数据泄漏在url中.     适用数据 ...

  6. php中return的用法实例分析

    本文实例讲述了php中return的用法.分享给大家供大家参考.具体分析如下: 首先,它的意思就是返回;return()是语言结构而不是函数,仅在参数包含表达式时才需要用括号将其括起来.当返回一个变量 ...

  7. 关于前期在云服务器上部署TOMCAT服务器的问题

    如果你要将你的项目放在服务器上(针对云服务器),首先你必须要学会前期部署Tomcat的准备, 第一步:安装jdk,配置环境变量 这个比较简单,配置java环境变量最为简单的方法是将java的 (../ ...

  8. entityframework学习笔记--002-database first

    1.实体框架紧紧地和Visual Studio集成在一起,为了在你的应用程序中使用实体框架,我们增加一个ADO.NET实体数据框架到你的项目.方法如下: 右键你的项目,然后选择 ➤New Item(新 ...

  9. MVC基础

    一.简介 MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑.数据.界面显示分离的方 ...

  10. line-height行高与图片的隐匿文本间隙消除方法

    (标注 文章来源 http://www.zhangxinxu.com/wordpress/2015/08/css-deep-understand-vertical-align-and-line-hei ...