02-线性结构3 Reversing Linked List
2017-10-19 12:46
483 查看
02-线性结构3 Reversing Linked List(25 分)
Given a constant K and a singly linked list L, you are supposed to reverse the links of every K elements on L. For example, given L being 1→2→3→4→5→6, if K=3, then you must output 3→2→1→6→5→4; if K=4, you must output 4→3→2→1→5→6.Input Specification:
Each input file contains one test case. For each case, the first line contains the address of the first node, a positive N (≤10
5
) which is the total number of nodes, and a positive K (≤N) which is the length of the sublist to be reversed. The address of a node is a 5-digit nonnegative integer, and NULL is represented by -1.
Then N lines follow, each describes a node in the format:
Address Data Next
where Address is the position of the node, Data is an integer, and Next is the position of the next node.
Output Specification:
For each case, output the resulting ordered linked list. Each node occupies a line, and is printed in the same format as in the input.
Sample Input:
00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
Sample Output:
00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1
最初版本代码,建立原始链表采用N次循环导致超时,没有采用格式化输出,用了很傻的方法。。
#include <iostream> #include <cstring> #include <cstdio> #include <malloc.h> using namespace std; struct point { int prev; int data; int next; }; struct node{ int addr; int data; struct node *next; }; struct node *Rverse(struct node *p,int k,int n){ if(k==1) return p; else{ struct node *temp,*b,*c,*d,*first; first=p; temp=p->next; b=temp->next; if(b->next){ while(temp->next){ int cnt=0; while(cnt<k && b->next){ c=b->next; b->next=temp; temp=b; b=c; cnt++; } if(cnt+2<k){ while(cnt>0){ c=temp->next; temp->next=b; b=temp; temp=c; cnt--; } temp->next=b; first->next=temp; break; } else if(cnt==k){ d=first->next; first->next=temp->next; first=d; first->next=temp; } else if(cnt+2==k){ b->next=temp; temp=first->next; temp->next=0; first->next=b; break; } } } else{ first->next=b; b->next=temp; } return p; } } void printAddr(int n){ if(n>9999) cout<<n; else if(n>999) cout<<0<<n; else if(n>99) cout<<0<<0<<n; else if(n>9) cout<<0<<0<<0<<n; else cout<<0<<0<<0<<0<<n; } int main() { int firstAddr,n,k,i,exit=0; cin>>firstAddr>>n>>k; struct point oriList ; for(i=0;i<n;i++){ cin>>oriList[i].prev>>oriList[i].data>>oriList[i].next; } struct node *head,*p; head=(struct node *)malloc(sizeof(struct node)); p=(struct node *)malloc(sizeof(struct node)); head->next=p; p->addr=firstAddr; while(1){ struct node *p1; p1=(struct node *)malloc(sizeof(struct node)); for(int i=0;i<n;i++){ if(oriList[i].prev==p->addr){ p->data=oriList[i].data; if(oriList[i].next==-1){ exit=1; break; } p1->addr=oriList[i].next; p->next=p1; p=p1; break; } } if(exit) break; } p->next=0; p=head; p=Rverse(p,k,n); while(1){ p=p->next; printAddr(p->addr); cout<<' '; cout<<p->data<<' '; if(p->next){ printAddr(p->next->addr); cout<<endl; } else{ cout<<-1<<endl; break; } } return 0; }
建立单链表的时候使用了二分查找和插值查找,还是超时。。代码如下:
#include <iostream> #include <cstring> #include <cstdio> #include<algorithm> #include<fstream> #include <malloc.h> using namespace std; struct point { int prev; int data; int next; }; bool cmp(const point &a,const point &b) { if(a.prev!=a.prev) return a.prev<b.prev; else return a.prev<b.prev; } typedef struct node{ int addr; int data; struct node *next; }node; node *Rverse(node *p,int k,int n){ if(k==1) return p; else{ node *temp,*b,*c,*d,*first; first=p; temp=p->next; b=temp->next; if(b->next){ while(temp->next){ int cnt=0; while(cnt<k && b->next){ c=b->next; b->next=temp; temp=b; b=c; cnt++; } if(cnt+2<k){ while(cnt>0){ c=temp->next; temp->next=b; b=temp; temp=c; cnt--; } temp->next=b; first->next=temp; break; } else if(cnt==k){ d=first->next; first->next=temp->next; first=d; first->next=temp; } else if(cnt+2==k){ b->next=temp; temp=first->next; temp->next=0; first->next=b; break; } } } else{ first->next=b; b->next=temp; } return p; } } void printAddr(int n){ if(n>9999) cout<<n; else if(n>999) cout<<0<<n; else if(n>99) cout<<0<<0<<n; else if(n>9) cout<<0<<0<<0<<n; else cout<<0<<0<<0<<0<<n; } int main() { int firstAddr,n,k,i,exit=0; cin>>firstAddr>>n>>k; struct point oriList ; for(i=0;i<n;i++){ cin>>oriList[i].prev>>oriList[i].data>>oriList[i].next; } sort(oriList, oriList+n,cmp); struct node *head,*p; head=(node *)malloc(sizeof(node)); p=(node *)malloc(sizeof(node)); head->next=p; p->addr=firstAddr; while(1){ int minb=0,maxb=n-1; struct node *p1; p1=(node *)malloc(sizeof(node)); while(minb<=maxb){ int mid; if(maxb-minb>50){ mid=(p->addr-oriList[minb].prev)/(oriList[maxb].prev-oriList[minb].prev)*(maxb-minb); } else{ mid=(minb+maxb)/2; } if(p->addr>oriList[mid].prev){ minb=mid+1; } else if(p->addr<oriList[mid].prev){ maxb=mid-1; } else{ p->data=oriList[mid].data; if(oriList[mid].next==-1){ exit=1; break; } p1->addr=oriList[mid].next; p->next=p1; p=p1; break; } } if(exit) break; } p->next=0; p=head; p=Rverse(p,k,n); while(1){ p=p->next; printAddr(p->addr); cout<<' '; cout<<p->data<<' '; if(p->next){ printAddr(p->next->addr); cout<<endl; } else{ cout<<-1<<endl; break; } } return 0; }
借鉴大神的代码如下:
#include<stdio.h> #define MAX_SIZE 100004 typedef struct tagLNode{ int addr; //节点位置Address int data; //Data值 int nextAddr; //下个节点位置 struct tagLNode *next; //指向下个节点的指针 } LNode; /* LNode *listReverse(LNode *head, int k); 反转单链表函数 参数1:单链表的头节点, 参数2:反转子链表的长度, 返回值:反转后的链表的第一个节点(不是头结点) */ LNode *listReverse(LNode *head, int k); //输出单链表 参数为单链表的头结点 void printList(LNode *a); int main() { int firstAddr; int n = 0; //节点数 N int k = 0; //反转子链表的长度K int num = 0; //链表建好之后的链表节点数 int data[MAX_SIZE]; //存data值 节点位置作为索引值 int next[MAX_SIZE]; //存next值 节点位置为索引 int tmp; //临时变量,输入的时候用 scanf("%d %d %d", &firstAddr, &n, &k); LNode a[n+1]; //能存n+1个几点的数组。 a[0].nextAddr = firstAddr; //a[0] 作为头节点 //读输入的节点 int i = 1; for (; i < n+1; i++){ scanf("%d", &tmp); scanf("%d %d", &data[tmp], &next[tmp]); } //构建单链表 i = 1; while (1){ if (a[i-1].nextAddr == -1){ a[i-1].next = NULL; num = i-1; break; } a[i].addr = a[i-1].nextAddr; a[i].data = data[a[i].addr]; a[i].nextAddr = next[a[i].addr]; a[i-1].next = a+i; i++; } LNode *p = a; //p指向链表头结点 LNode *rp = NULL; //反转链表函数的返回值 if (k <= num ){ for (i = 0; i < (num/k); i++){ rp = listReverse(p, k); // p->next = rp; // 第一次执行,a[0]->next 指向第一段子链表反转的第一个节点 p->nextAddr = rp->addr; // 更改Next值,指向逆转后它的下一个节点的位置 int j = 0; //使p指向下一段需要反转的子链表的头结点(第一个节点的前一个节点) while (j < k){ p = p->next; j++; } } } printList(a); } LNode *listReverse(LNode *head, int k) { int count = 1; LNode *new = head->next; LNode *old = new->next; LNode *tmp = NULL; while (count < k){ tmp = old->next; old->next = new; old->nextAddr = new->addr; new = old; //new向后走一个节点 old = tmp; //tmp向后走一个节点 count++; } //使反转后的最后一个节点指向下一段子链表的第一个节点 head->next->next = old; if (old != NULL){ //修改Next值,使它指向下一个节点的位置 head->next->nextAddr = old->addr; }else{ //如果old为NULL,即没有下一个子链表,那么反转后的最后一个节点即是真个链表的最后一个节点 head->next->nextAddr = -1; } return new; } void prin c4e0 tList(LNode *a) { LNode *p = a; while (p->next != NULL){ p = p->next; if (p->nextAddr != -1 ){ //格式输出,%.5意味着如果一个整数不足5位,输出时前面补0 如:22,输出:00022 printf("%.5d %d %.5d\n", p->addr, p->data, p->nextAddr); }else{ //-1不需要以%.5格式输出 printf("%.5d %d %d\n", p->addr, p->data, p->nextAddr); } } }
相关文章推荐
- PAT 02-线性结构3 Reversing Linked List 【JAVA实现】
- 02-线性结构3 Reversing Linked List
- 逆转链表-pta02-线性结构3 Reversing Linked List
- 02-线性结构2 Reversing Linked List
- 02-线性结构2 Reversing Linked List
- [数据结构]02-线性结构3 Reversing Linked List
- 02-线性结构3 Reversing Linked List(25 分)
- 02-线性结构2 Reversing Linked List
- 02-线性结构2 Reversing Linked List
- C++ 02-线性结构3 Reversing Linked List
- 02-线性结构3 Reversing Linked List(25 分)
- 02-线性结构2 Reversing Linked List
- 数据结构 PAT 02-线性结构2 Reversing Linked List 单链表实现
- 02-线性结构2 Reversing Linked List
- 02-线性结构3 Reversing Linked List(25 分)
- 02-线性结构3 Reversing Linked List(25 分)
- 02-线性结构3 Reversing Linked List (25分)
- 02-线性结构3 Reversing Linked List
- 02-线性结构2 Reversing Linked List
- C语言 02-线性结构3 Reversing Linked List