链表逆序输出 ---九度1511

题目描述:

输入一个链表,从尾到头打印链表每个节点的值。

输入:

每个输入文件仅包含一组测试样例。
每一组测试案例包含多行,每行一个大于0的整数,代表一个链表的节点。第一行是链表第一个节点的值,依次类推。当输入到-1时代表链表输入完毕。-1本身不属于链表。

输出:

对应每个测试案例,以从尾到头的顺序输出链表每个节点的值,每个值占一行。

样例输入:
1
2
3
4
5
-1
样例输出:
5
4
3
2
1

解题思路:
方法一:直接用数组存储数据,然后反向输出,不过好像通不过。为什么?
方法二:利用单向链表存储数据,在输出的时候递归输出,先输出根节点的下一个节点,再输出当前节点,类似于树的后序遍历。这种方法由于需要递归调用,运行过程中占用的空间会更大。
方法三:使用双向链表,在输出的时候可以直接从链表的尾部从后向前输出。
以上两种方法,如果采用正常的创建链表和输出链表的方法,会导致运行时间过长。此时,用到的小技巧是,每次传入到链表中的不是根节点的地址,而是链表尾部的非空节点的地址,这样插入的时间复杂度就是O(1)了,不需要每次多从头到尾查找插入位置。输出的时间复杂度就是O(n)。这样,两种方法都能通过,但是方法三所用的空间更少一些。
  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<string.h>
  4 #define N 100
  5
  6 void printArrayList();
  7
  8 /*单向链表节点*/
  9 struct Node{
 10     int value;
 11     Node* next;
 12 };
 13
 14 /*双向链表节点*/
 15 struct BiNode{
 16     int value;
 17     BiNode* next;
 18     BiNode* previous;
 19 };
 20
 21 /* 逆序输出双向链表 */
 22 void rPrintBiList(BiNode* root){
 23     if(root == NULL){
 24         return;
 25     }
 26     BiNode* tmp;
 27     BiNode* parent;
 28     tmp = root;
 29     parent = root;
 30     while(tmp!=NULL){
 31         parent = tmp;
 32         tmp = tmp ->next;
 33     }
 34
 35     while(parent !=NULL){
 36         printf("%d\n",parent->value);
 37         parent = parent ->previous;
 38     }
 39 }
 40
 41
 42 /* 逆序输出链表 */
 43 void rPrintList(Node* root){
 44     if(root ==NULL){
 45         return;
 46     }
 47     rPrintList(root->next);
 48     printf("%d\n",root->value);
 49 }
 50
 51 void rPrintListTail(BiNode* tail){
 52     if( tail == NULL){
 53         return ;
 54     }
 55     while(tail != NULL){
 56         printf("%d\n",tail->value);
 57         tail = tail->previous;
 58     }
 59 }
 60
 61
 62 /* 将数据插入到双向链表的尾部 */
 63 void addToBiList(BiNode** root,int value){
 64     /* 对每一个输入点建立一个链表 */
 65     BiNode* proot = new BiNode();
 66     proot -> value = value;
 67     proot -> next = NULL;
 68     BiNode* tmp;
 69     BiNode* parent;
 70     if(*root ==NULL){
 71         *root = proot;
 72         proot ->previous = NULL;
 73     }else{
 74         tmp = *root;
 75         parent = *root;
 76         while(tmp !=NULL){
 77             parent = tmp;
 78             tmp = tmp ->next;
 79         }
 80         parent ->next= proot;
 81         proot ->previous = parent;
 82     }
 83 }
 84
 85 /* 直接插入链表的尾部 */
 86 void addToBiListTail(BiNode** tail,int value){
 87     BiNode* proot = new BiNode();
 88     proot -> value = value;
 89     proot -> next = NULL;
 90     if(*tail==NULL){
 91         *tail = proot;
 92         proot ->previous = NULL;
 93     }else{
 94         (*tail)->next= proot;
 95         proot ->previous= *tail;
 96         *tail = proot;
 97     }
 98 }
 99
100
101 void addToListTail(Node** tail,int value){ // 此时必须使用Node** 作为参数,因为我们不仅需要tail所只想的内容发生改变,它自身的值也发生改变,所以需要使用指针的指针作为参数。!!!
102     /* 对每一个输入点建立一个链表 */
103     Node* proot = new Node();
104     proot -> value = value;
105     proot -> next = NULL;
106     if(*tail==NULL){
107         *tail = proot;
108     }else{
109         (*tail) ->next= proot;
110         *tail = proot;
111     }
112 }
113 /* 把数据插入到链表的尾部 */
114 void addToList(Node** root,int value){
115
116     /* 对每一个输入点建立一个链表 */
117     Node* proot = new Node();
118     proot -> value = value;
119     proot -> next = NULL;
120     Node* tmp;
121     Node* parent;
122
123     /* 将新的节点插入到链表中去*/
124     if(*root == NULL){
125         *root = proot;
126     }else{
127         tmp = *root;
128         parent = *root; //最后一个不为NULL的节点
129         while(tmp!=NULL){
130             parent = tmp;
131             tmp = tmp->next;
132         }
133         parent->next = proot;
134     }
135
136 }
137
138 /*   使用数组来存放数据 */
139 void printArrayList(){
140     int* intArray = (int *)malloc(sizeof(int)*N);
141     int* tmp;
142     int len = N;
143     int input;
144     int count=0;
145     scanf("%d",&input);
146     while(input!=(-1)){
147         if(input<0){
148             break;
149         }
150         if(count == len){
151             len += N;
152             tmp = (int *)realloc(intArray,len);
153             intArray = tmp;
154         }
155         intArray[count++] = input;
156         scanf("%d",&input);
157     }
158     for(int i = count-1; i>=0 ; i--){
159         printf("%d\n",intArray[i]);
160     }
161 }
162
163 int main(){
164
165     /*printArrayList();*/
166     int n;
167     Node* root=NULL;
168     Node* nodetail=NULL;
169     BiNode* biroot = NULL;
170     BiNode* tail = NULL;
171     bool isFirst = true;
172     scanf("%d",&n);
173     while(n!=(-1)){
174         /*addToList(&root,n);*/
175         addToListTail(&nodetail,n);
176         if(isFirst){
177             root = &(*nodetail);
178             isFirst = false;
179         }
180     /*  addToBiList(&biroot,n);*/
181     /*  addToBiListTail(&tail,n);*/
182         scanf("%d",&n);
183     }
184     /*rPrintList(root);*/
185     rPrintList(root);
186     /*rPrintBiList(biroot);*/
187     /*rPrintListTail(tail);*/
188     return 0;
189 }
190
191
192
193 /**************************************************************
194     Problem: 1511
195     User: jingxmu
196     Language: C++
197     Result: Accepted
198     Time:90 ms
199     Memory:5544 kb
200 ****************************************************************/

链表逆序输出 ---九度1511

时间: 2024-12-20 13:58:53

链表逆序输出 ---九度1511的相关文章

如何实现一个高效的单向链表逆序输出?(详解)

需要考虑因素,高效应权衡多方面因素 数据量是否会很大 空间是否有限制 原始链表的结构是否可以更改 时间复杂度是否有限制 一个链表节点需要输出的元素有多个,例如链表中存的是自定义对象,有多个字段 题目. 01. 先学着实现一个简单的Java版的单项链表构建任意长度的任意数值的链表, 头插法,顺序遍历输出链表 package com.szs.list; /** * 单链表 * @author Administrator * */ public class MyLinkedList { public

java版的单向链表的逆序输出

将单向链表逆序输出,方法有三种: a.遍历链表,将每个节点的内容存入一个数组中,然后逆序输出数组(最简单的做法) b.使用栈来逆序输出 c.直接将链表逆序然后输出(本文采用的方法) 先介绍算法: 1). 若链表为空或只有一个元素,则直接返回: 2). 设置两个前后相邻的指针p,q. 将p所指向的节点作为q指向节点的后继: 3). 重复2),直到q为空 4). 调整链表头和链表尾 示例:以逆序A->B->C->D为例,图示如下 package com.moluo.shujujiegou;

剑指Offer03 逆序输出链表

多写了个逆序链表 1 /************************************************************************* 2 > File Name: 03_Pirnt_LinkList.c 3 > Author: Juntaran 4 > Mail: [email protected] 5 > Created Time: 2016年08月24日 星期三 02时04分25秒 6 ***************************

[华为机试练习题]24.删除链表中的反复节点、剩余节点逆序输出

题目 描写叙述: 题目描写叙述: 输入一个不带头节点的单向链表(链表的节点数小于100),删除链表中内容反复的节点(反复的节点所有删除),剩余的节点逆序倒排. 要求实现函数: void vChanProcess(strNode * pstrIn,strNode * pstrOut); [输入] pstrIn:输入一个不带头节点的单向链表 [输出] pstrOut:删除内容反复的节点(反复的节点所有删除).剩余节点逆序输出(不带头节点,链表第一个节点的内存已经申请). [注意]仅仅须要完毕该函数功

单链表逆序或者逆序输出

分为两种情况,一种是只逆序输出,实际上不逆序:另一种是把链表逆序. ********************逆序输出*********************** 1 #include<iostream> 2 #include<stack> 3 #include<assert.h> 4 using namespace std; 5 6 7 typedef struct node{ 8 int data; 9 node * next; 10 }node; 11 12 //

[华为机试练习题]24.删除链表中的重复节点、剩余节点逆序输出

题目 描述: 题目描述: 输入一个不带头节点的单向链表(链表的节点数小于100),删除链表中内容重复的节点(重复的节点全部删除),剩余的节点逆序倒排. 要求实现函数: void vChanProcess(strNode * pstrIn,strNode * pstrOut); [输入] pstrIn:输入一个不带头节点的单向链表 [输出] pstrOut:删除内容重复的节点(重复的节点全部删除),剩余节点逆序输出(不带头节点,链表第一个节点的内存已经申请). [注意]只需要完成该函数功能算法,中

Swift入门(十二)——利用Extension添加逆序输出字符串方法

Swift好像没有自带逆序输出字符串的方法,于是决定通过拓展(Extension)给String类添加一个逆序输出字符串的reverse方法. 首先新建一个Swift文件,命名规则不太清楚,于是暂且模仿OC叫做String+Operation吧,然后实现我们需要拓展的方法.下面先贴上代码,然后解释一下这段代码. //String+Operation.swifft import Foundation //逆序输出swift中的字符串 extension String{ func Reverse()

[2013] 链表逆序

题目二:逆序链表输出. 题目描述:   将输入的一个单向链表,逆序后输出链表中的值.链表定义如下: typedef struct tagListNode  {        int value;        struct tagListNode *next;  }ListNode;   要求实现函数:   void converse(ListNode **head); [输入]head:    链表头节点,空间已经开辟好 [输出]head:    逆序后的链表头节点 [返回]无 [注意]只需要

网易云课堂_C语言程序设计进阶_第五周:递归与简单算法:递归、搜索、二分搜索、简单排序_1逆序输出的数列

1 逆序输出的数列(10分) 题目内容: 你的程序会读入一系列的正整数,预先不知道正整数的数量,一旦读到-1,就表示输入结束.然后,按照和输入相反的顺序输出所读到的数字,不包括最后标识结束的-1. 输入格式: 一系列正整数,输入-1表示结束,-1不是输入的数据的一部分. 输出格式: 按照与输入相反的顺序输出所有的整数,每个整数后面跟一个空格以与后面的整数区分,最后的整数后面也有空格. 输入样例: 1 2 3 4 -1 输出样例: 4 3 2 1 时间限制:2000ms内存限制:128000kb