1133. Splitting A Linked List (25)
来源:互联网 发布:手机淘宝卖东西怎么弄 编辑:程序博客网 时间:2024/05/18 23:28
网上看到一道不错的题目,做了一下感觉对链表的理解有很大的帮助。题目的意思是给定一个正数K和一个链表 ,把链表的节点分成3类输出,先输出负数,再输出小于K的非负数,最后输出大于K的数,每一类输出保持原来的相对顺序不变。
比如给定链表18→7→-4→0→5→-6→10→11→-2和K=10,输出-4→-6→-2→7→0→5→10→18→11。正式输入时第一行为首节点地址,节点数和K值,后面每行分别输输入节点的首地址,节点数值,下一节点的地址,输入的时候节点顺序是打乱了的。输出的时候按排好的顺序输出,并且本节点输出的下一节点地址与下一节点输出的地址是相同的,地址按5位数输出,不足5位的前面补0,NULL用-1表示,格式如下:
Sample Input:
00100 9 10
23333 10 27777
00000 0 99999
00100 18 12309
68237 -6 23333
33218 -4 00000
48652 -2 -1
99999 5 68237
27777 11 48652
12309 7 33218
Sample Output:
33218 -4 68237
68237 -6 48652
48652 -2 12309
12309 7 00000
00000 0 99999
99999 5 23333
23333 10 00100
00100 18 27777
27777 11 -1
一般的做法都是定义一个很大的数组list[100000],用数组的下标来定位下一个节点,在输入节点数量很多的时候,这种做法可以有效提高排序的速度,又不会浪费太多内存。当输入节点比较少的时候,就会有大量内存浪费,本文主要针对这种情况,在节点输入比较少的情况下,直接对链表排序,牺牲一点cpu效率来节省内存空间。具体的选择还要根据实际情况做出折中。
首先输入的链表是无序的,但是可以根据节点的前后地址进行2层轮询最后得到链表的正确顺序,这里比较费时间,时间复杂度O(n^2),得到正确顺序的链表后就可以直接输出了,分3次遍历链表,将已经输出的节点删除可以减少下一次遍历的时间。
#include <stdio.h>#include <assert.h>struct NODE { int addr; int data; int next_addr; struct NODE *next_node;};typedef struct NODE NODE;void output_print(NODE* link_node,NODE* pre_node){ static int flag=0; if(!flag) { printf("%05d %d ", link_node->addr,link_node->data); flag=1; } else { printf("%05d\n%05d %d ", link_node->addr,link_node->addr,link_node->data); } pre_node->next_node = link_node->next_node;//删除输出的节点}void Splitting_A_Linked_List(void){ int nodes_num,first_addr,k; int first_node_index=0,end_flag=0; NODE *link_node,*pre_node; scanf("%d %d %d",&first_addr,&nodes_num,&k); assert((nodes_num>0) && (nodes_num<=100000)); assert((k>0) && (nodes_num<=1000)); NODE input_node[nodes_num];//变长数组,gcc支持 for(int i=0;i<nodes_num;i++)//输入所有节点 { scanf("%d %d %d",&input_node[i].addr,&input_node[i].data,&input_node[i].next_addr); input_node[i].next_node = NULL; if(input_node[i].addr == first_addr) { first_node_index = i;//定位头节点 } end_flag=0; for(int j=0;j<i;j++) { if(input_node[i].next_addr == input_node[j].addr)//存在之前输入节点的地址等于当前下一节点地址 { end_flag++; input_node[i].next_node = &input_node[j] ;//将该节点插入当前节点之后 if(end_flag == 2) break; } if(input_node[i].addr == input_node[j].next_addr)//存在之前输入节点的下一节点地址与当前节点地址相同 { end_flag++; input_node[j].next_node = &input_node[i] ;//将当前节点插入该节点之后 if(end_flag == 2) break; //前后地址的节点都找到后就可以跳出循环了 } } } for(int i=0;i<3;i++)//分3次轮询链表 { link_node = &input_node[first_node_index]; pre_node = link_node; while(link_node!= NULL) { switch (i) { case 0: if(link_node->data<0) { output_print(link_node,pre_node); } break; case 1: if(link_node->data>=0 && link_node->data <= k ) { output_print(link_node,pre_node); } break; case 2: if(link_node->data > k ) { output_print(link_node,pre_node); } break; default: break; } pre_node=link_node; //保存前一个节点,当删除节点时会用到 link_node=link_node->next_node;//遍历下一个节点 } } printf("-1\n");}
- 1133. Splitting A Linked List (25)
- 1133. Splitting A Linked List (25)
- 1133. Splitting A Linked List (25)
- 1133. Splitting A Linked List (25)
- 1133. Splitting A Linked List (25)
- 1133. Splitting A Linked List (25)
- 1133. Splitting A Linked List (25)
- PAT甲级 1133. Splitting A Linked List (25)
- 1133. Splitting A Linked List (25)-PAT甲级真题
- 1133. Splitting A Linked List (25)(结构体)
- PAT 甲级 1133. Splitting A Linked List (25)
- 1133. Splitting A Linked List (25)[链表处理]
- PAT-1133 Splitting A Linked List(链表分解)
- PAT A 1052. Linked List Sorting (25)
- PAT A 1074. Reversing Linked List (25)
- 1097. Deduplication on a Linked List (25)
- 1097. Deduplication on a Linked List (25)
- 1097. Deduplication on a Linked List (25)
- 1027. 打印沙漏(20)
- mysql5.7解压版安装
- 状态机跑飞的例子
- HDU 6231 K-th Number CCPC2017 Harbin(二分答案)
- win7系统休眠功能的关闭与启用
- 1133. Splitting A Linked List (25)
- 看了毁你三观的PCB设计理论 高速PCB外层还要不要覆铜了
- 【我的Java笔记】数据结构
- 1028. 人口普查(20)
- Log4J使用笔记
- C++——初始化列表
- 1029. 旧键盘(20)
- 6.13
- 2D 动画调整 position 产生的位移问题