数据结构(复习)链表完结篇

关于链表我们其实有很多要学的东西,书上的东西其实都是皮毛,,只是引领我们而已,但是算法是一个积累的过程!!!

先把基础的东西学好吧!!

Coding-------------------------------------------------------------------------------------------------------------------

思路一:

取出原始链表的第一个节点A,然后将该节点作为新链表的头节点。

现在状态为

原始链表:B->C->D->E

新链表:A

然后同上,变为了下面的状态

原始链表:C->D->E

新链表: B->A

原始链表:D->E

新链表: C->B->A

原始链表:E

新链表: D->C->B->A

原始链表:

新链表: E->D->C->B->A

很显然,对原始链表遍历一次,就完成了这个工作,所以这个算法的复杂度为O(n)。

1.这个思想很简单就是把链表遍历一遍采用逆序插入法插入到一个新的链表中去------------------在这儿不多说了!!!!!!!!!!!!!!!!!!!!

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

思路二:

2、 单链表逆序

第二个题目是很经典的“单链表逆序”问题。很多公司的面试题库中都有这道题,有的公司明确题目要求不能使用额外的节点存储空间,有的没有明确说明,但是如果面试者使用了额外的节点存储空间做中转,会得到一个比较低的分数。如何在不使用额外存储节点的情况下使一个单链表的所有节点逆序?我们先用迭代循环的思想来分析这个问题,链表的初始状态如图(1)所示:

图(1)初始状态

初始状态,prev是NULL,head指向当前的头节点A,next指向A节点的下一个节点B。首先从A节点开始逆序,将A节点的next指针指向prev,因为prev的当前值是NULL,所以A节点就从链表中脱离出来了,然后移动head和next指针,使它们分别指向B节点和B的下一个节点C(因为当前的next已经指向B节点了,因此修改A节点的next指针不会导致链表丢失)。逆向节点A之后,链表的状态如图(2)所示:

图(2)经过第一次迭代后的状态

从图(1)的初始状态到图(2)状态共做了四个操作,这四个操作的伪代码如下:

head->next = prev;

prev = head;

head = next;

next = head->next;

这四行伪代码就是循环算法的迭代体了,现在用这个迭代体对图(2)的状态再进行一轮迭代,就得到了图(3)的状态:

图(3)经过第二次迭代后的状态

那么循环终止条件呢?现在对图(3)的状态再迭代一次得到图(4)的状态:

图(4)经过第三次迭代后的状态

此时可以看出,在图(4)的基础上再进行一次迭代就可以完成链表的逆序,因此循环迭代的终止条件就是当前的head指针是NULL。

现在来总结一下,循环的初始条件是:

prev = NULL;

循环迭代体是:

next = head->next;

head->next = prev;

prev = head;

head = next;

循环终止条件是:

head == NUll

代码贴出如下:

// 关于数据结构的总结与复习  Coding
1.// 关于单链表逆序问题
#include <cstdio>
#include <cstdlib>
//#define _OJ_

typedef struct Lnode
{
    int data;
    struct Lnode *next;
} Lnode, *Linklist;

Linklist
Init_List(void)//建立链表
{
    int i, n;
    Linklist L, p, head;
    L = (Linklist) malloc (sizeof(Lnode));
    head = L;

    scanf("%d", &n);
    for (i = 0; i < n; i++) {
    p = (Linklist) malloc (sizeof(Lnode));    scanf("%d", &p->data);
    L->next = p;
    L = p;
    }
    L->next = NULL;
    return head;
}
//----------------------------------------------------------------------------------------------------------
Linklist
trverser(Linklist L)
{
    Linklist head, p, t, pre = NULL; //pre原始值为NULL
    head = L;
    L = L->next;                     //L跳过头结点从第一个元素开始

    while (L != NULL) {
        t = L->next;
        L->next = pre;
        pre = L;
        L = t;
    }
    head->next = pre;                //头结点下一个元素是最后一个节点
    return head;
}
//--------------------------------------------------------------------------------------------------------------

void
print(Linklist L)
{
    Linklist p;
    p = L;
    printf("打印输出链表:\n");
    while (p->next != NULL) {
        printf("%d ", p->next->data);
        p = p->next;
    }
}

int main(int argc, char const *argv[]) {
#ifndef _OJ_ //ONLINE JUDGE
       freopen("input.txt", "r", stdin);
       //freopen("output.txt", "w", stdout);
#endif

    Linklist L;
    L = Init_List();
    print(L);
    L = trverser(L);
    print(L);

    return 0;
}

  -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

二:关于单链表的排序问题

时间: 2024-08-24 11:25:41

数据结构(复习)链表完结篇的相关文章

数据结构复习之开题篇(必要时持续更新...)

在复习数据结构之前有必要复习一下C语言的指针 1.指针 int* p; 一个指针类型,名为p,代表的是一个整形所存放的地址编号 1.1一个使用的实例 [注]对变量使用&操作符,意为取它所在的地址 1 #include <stdio.h> 2 3 int main() 4 { 5 int var = 20; /* 实际变量的声明 */ 6 int* ip; /* 指针变量的声明 */ 7 8 ip = &var; /* 在指针变量中存储 var 的地址 */ 9 10 print

Java工程师学习指南(完结篇)

Java工程师学习指南 完结篇 先声明一点,文章里面不会详细到每一步怎么操作,只会提供大致的思路和方向,给大家以启发,如果真的要一步一步指导操作的话,那至少需要一本书的厚度啦. 因为笔者还只是一名在校生,所以写的内容主要还是针对Java初学者或者接触Java后端不久的朋友,不适用于已经工作多年的Java大佬们.所以本文中的方法不一定适合所有人,如有错误还请谅解. 本期的内容是系列文章的最后一部分内容了.这个系列可能还有很多东西没有说清楚,也有很多内容被忽略了.但是这些内容也确实是笔者结合自己经验

DTRACE简介之完结篇3

https://blogs.oracle.com/swan/entry/dtrace%E7%AE%80%E4%BB%8B_3 DTRACE简介之完结篇 By samwan on 四月 13, 2007 已经有好长一段时间没有更新blog了,不是我懒,确实是这段时间太忙.工作加上生活,算了,不找借口了,还是来把DTRACE简介作个完结吧.本来开始写的时候只准备用一篇文章来描述,等真正写出来就发现,不行了,Dtrace实在是太强大了,即便是加上今天的,也没有完全讲到,遗漏的地方就只有请各位看官自己去

AT&amp;T汇编语言与GCC内嵌汇编,Linux内核数据结构之链表

最近在看<Linux内核源代码情景分析>,作者毛德操.书中刚开始介绍了AT&T汇编语言与GCC内嵌汇编,以及Linux内核数据结构之链表.可惜书中介绍的不够全面.因为推荐大家阅读下面两篇文章.很不错. AT&T汇编语言与GCC内嵌汇编:http://grid.hust.edu.cn/zyshao/Teaching_Material/OSEngineering/Chapter2.pdf. Linux内核数据结构之链表:http://www.cnblogs.com/Anker/p/

安卓自定义View进阶 - Path之完结篇(伪)

Path之完结篇(伪) 作者微博: @GcsSloop [本系列相关文章] 经历过前两篇 Path之基本操作 和 Path之贝塞尔曲线 的讲解,本篇终于进入Path的收尾篇,本篇结束后Path的大部分相关方法都已经讲解完了,但Path还有一些更有意思的玩法,应该会在后续的文章中出现吧,嗯,应该会的ˊ_>ˋ 一.Path常用方法表 为了兼容性(偷懒) 本表格中去除了在API21(即安卓版本5.0)以上才添加的方法.忍不住吐槽一下,为啥看起来有些顺手就能写的重载方法要等到API21才添加上啊.宝宝此

数据结构--单向链表

C语言中,我们在使用数组时,会需要对数组进行插入和删除的操作,这时就需要移动大量的数组元素,但在C语言中,数组属于静态内存分配,数组在定义时就必须指定数组的长度或者初始化.这样程序一旦运行,数组的长度就不能再改变,若想改变,就只能修改源代码.实际使用中数组元素的个数也不能超过数组元素的最大长度,否则就会发生下标越界的错误(这是新手在初学C语言时肯定会遇到的问题,相信老师也会反复强调!!!但这种问题肯定会遇到,找半天找不到错误在哪,怪我咯???).另外如果数组元素的使用低于最大长度,又会造成系统资

从无到有写一个运维APP(三)完结篇

前言:自己的挖的坑还得填,此篇为完结篇,环境的搭建参考第一篇从无到有写一个运维APP(一),至于第二篇就跳过吧,写个APP没那么复杂.由于自己现在无业游民,所以没有什么现成的环境,环境就随便找个公网的..再者当下的完成度应该算不上一个完整的APP,但是作为参考,依瓢画葫芦绝对足够了,如果等完整产品,可能得等一段时间了,下面的是该项目的地址. 项目地址: https://github.com/youerning/MyApp(star一下呗) 效果图如下 文章目录: 准备工作 代理 页面框架 获取数

SpringMVC学习系列(12) 完结篇 之 基于Hibernate+Spring+Spring MVC+Bootstrap的管理系统实现

到这里已经写到第12篇了,前11篇基本上把Spring MVC主要的内容都讲了,现在就直接上一个项目吧,希望能对有需要的朋友有一些帮助. 一.首先看一下项目结构: InfrastructureProjects:是抽取出的基础项目,主要封装了一些通用的操作. SpringMVC3Demo:就是管理系统所在的项目. WeiXinAPI:是之前做微信管理平台测试时封装一些操作,如果不需要把该项目移除即可. 注:项目的前端UI框架用的是国外的一个基于Bootstrap框架的开发的Demo,如不需要替换为

第18完结篇-JAVA XML

第18完结篇-JAVA XML 每篇一句 :我们不缺方法,缺的是一往无前的决心和魄力 初学心得: 我们应该从中吸取教训,而不是累积伤痛 (笔者:JEEP/711)[JAVA笔记 | 时间:2017-05-21| JAVA XML ] 1.什么是XML Extensible Markup Language:翻译过来为可扩展标记语言 Xml技术是w3c组织发布的,目前推荐遵循的是W3C组织于2000发布的XML1.0规范 在XML语言中,它允许用户自定义标签 一个标签用于描述一段数据:一个标签可分为