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

分析
非递归分析:

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

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

代码:

#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. geotrellis使用(十一)实现空间数据库栅格化以及根据属性字段进行赋值

    Geotrellis系列文章链接地址http://www.cnblogs.com/shoufengwei/p/5619419.html 目录 前言 安装空间数据库 空间数据库栅格化 根据属性字段进行赋 ...

  2. ios UIWebView 在开发中加载文件

    UIWebView 在实际应用中加载文件的时候,有两种情况, 1. 实行在线预览 , 2. 下载到本地,再查看 如果是第一种情况: NSURL *url = [NSURL URLWithString: ...

  3. ios多线程-GCD基本用法

    ios中多线程有三种,NSTread, NSOperation,GCD 这篇就讲讲GCD的基本用法 平时比较多使用和看到的是: dispatch_async(dispatch_get_global_q ...

  4. sql 索引 的建立

    (From:http://54laobaixing.blog.163.com/blog/static/57843681200952411133121/) 假设你想找书中的某一个句子.你可以一页一页地逐 ...

  5. C#使用Log4Net记录日志

    当你在开发程序的时候, 调试(debugging)和日志(logging)都是非常重要的工作.在应用中使用日志主要有三个目的 l  监视代码中的变量的变化情况,把数据周期性地记录到文件中供其它应用进行 ...

  6. error when loading the sdk error parsing

    Error Parsing: C:\android-sdk_r24.2-windows\android-sdk-windows\system-images\android-22\android-wea ...

  7. 实用的CSS3属性和使用技巧

    CSS可以改进网站的设计并且开拓网站设计更多的可能性,可以令你的网页更具吸引力.对于前端开发者.网站设计师来说,掌握并熟练应用CSS是一项必不可少的技能. 下面列出了一些非常实用的CSS3属性和使用技 ...

  8. http://www.mysqltutorial.org/python-mysql-query/

    This tutorial shows you how to query data from a MySQL database in Python by using MySQL Connector/P ...

  9. JQuery 快速入门

    1.要学习Jquery @首先要在需要的页面引入 <script type="text/javascript" src="jquery.js">&l ...

  10. Web测试介绍一 UI测试

           随着Web 2.0技术的迅速发展,许多公司都开发了一些基于Web的网站服务,通常在设计开发Web应用系统的时候很难模拟出大量用户同时访问系统的实际情况,因此,当Web网站遇到访问高峰时, ...