02-线性结构3 Reversing Linked List

来源:互联网 发布:匿名领航者飞控源码 编辑:程序博客网 时间:2024/06/06 02:36

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[n];    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[n];    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 100004typedef 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 printList(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);        }        }}
原创粉丝点击