• PAT 1025 反转链表


    PAT (Basic Level) Practise 1025


    1、 问题概述


    2、 解题思路

    • 课上听了栋哥说可以把需要反转的部分从原位置拆了,再重新插入链表最尾部。感觉这样的想法很棒!
    • 大概是这样的意思
    • 然后就按这样的想法写了一下~(单向链表感觉不好操作...后来改用了双向的...)

    3、 代码

    #include<stdio.h>
    #include<iostream>
    #include<string>
    using namespace std;
    struct link {
    	int address;
    	int next;
    	int data;
    	struct link *nxt;//指向下一个
    	struct link *last;//指向上一个
    };
    struct link l[100100],Lk[100100];
    struct link *head;
    
    int main() {
    	head = (struct link*)malloc(sizeof(struct link));
    	int n, k;
    	int i, j;
    	scanf_s("%d%d%d", &l[0].address, &n, &k);
    
    	l[0].nxt = &l[n + 1];
    	l[n + 1].nxt = NULL;
    	
    	for (i = 1; i <= n; i++) {
    		scanf_s("%d%d%d", &l[i].address, &l[i].data, &l[i].next);
    		//找出第一个节点
    		if (l[i].address == l[0].address) {
    			l[i].nxt = l[0].nxt;
    			l[0].nxt = &l[i];
    			head = &l[i];
    		}
    	}
    
    	//整理链表
    	while (head->next != -1) {
    		for (i = 1; i <= n; i++) {
    			if (l[i].address == head->next) {
    				l[i].nxt = head->nxt;
    				head->nxt = &l[i];
    				head = &l[i];
    				break;
    			}
    		}
    	}
    
    	//重新排列链表
    	head = &l[0];
    	for (i = 0; head->nxt != NULL; i++) {
    
    		//连接新链表
    		if (i != 0) {
    			Lk[i].last = &Lk[i - 1];
    			Lk[i - 1].nxt = &Lk[i];
    		}
    		
    		//新链表数据转移
    		Lk[i].address = head->address;
    		Lk[i].data = head->data; 
    		
    		head = head->nxt;
    	}
    
    	int length = i - 1;
    	Lk[length].nxt = &Lk[i];
    	Lk[i].last = &Lk[length];
    	Lk[i].data = i;
    
    	//链表不需要反转
    	if (k == 1 || k > length) {
    		
    		head = Lk[0].nxt;
    		printf("%05d %d", head->address, head->data);
    		head = head->nxt;
    		while (head->nxt != NULL) {
    			printf(" %05d
    %05d %d", head->address, head->address, head->data);
    			head = head->nxt;
    		}
    		printf(" -1
    ");
    
    		return 0;
    	}
    
    	bool islength = false;
    	//反转
    	head = &Lk[length];	
    	for (j = 1; j*k <= length; j++) {
    		for (i = k*j; i > k*(j - 1); i--) {
    
    			//全反转
    			if (k == length&&!islength) {
    				head = head->last;
    				islength = true;
    			}
    
    			//从原序列移除
    			Lk[i].nxt->last = Lk[i].last;
    			Lk[i].last->nxt = Lk[i].nxt;
    
    			//插入链表尾部
    			Lk[i].last = head;
    			head->nxt->last = &Lk[i];
    			Lk[i].nxt = head->nxt;
    			head->nxt = &Lk[i];
    
    			head = &Lk[i];
    		}
    	}
    	
    	//剩余不用反转部分
    	for (i = (j - 1)*k + 1; i <= length; i++) {
    		Lk[i].nxt->last = Lk[i].last;
    		Lk[i].last->nxt = Lk[i].nxt;
    
    
    		Lk[i].last = head;
    		head->nxt->last = &Lk[i];
    		Lk[i].nxt = head->nxt;
    		head->nxt = &Lk[i];
    
    		head = &Lk[i];
    	}
    	
    	//输出
    	head = Lk[0].nxt;
    	printf("%05d %d", head->address, head->data);
    	head = head->nxt;
    	while (head->nxt != NULL) {
    		printf(" %05d
    %05d %d", head->address, head->address, head->data);
    		head = head->nxt;
    	}
    	printf(" -1
    ");
    	
    	return 0;
    }
    
    

    4、 问题与解决

    • 在链接新链表的时候,最开始都连到了原链表...新链表之间没有连接起来(⊙ˍ⊙)找了很久不知道错在哪里。最后想起栋哥说不会的时候就画图,果然,才模拟新链表第一个节点的时候就发现了问题。
    • 然后根据大神提醒,手动加头尾两个边界比较不容易出错 ( ̄︶ ̄)

    5、 最后

    • 其实,这代码并没有AC (⊙ˍ⊙) 有一个点超时了...
    • 大概能猜到是重新按顺序排列链表那边耗了很多时间,不过实在不会改了orz
    • 我觉得吧,对于一个全部用数组A掉上学期C语言上机的指针题以及这学期程序设计语言综合设计的指针题的人,做到这样已经很棒了(不要脸hhh)
    • 现在应该能算是勉强会用链表了吧 0 0 不过...还是好想用数组啊
    • 真的超级赞的呀~又快又好找bug
  • 相关阅读:
    nginx并发数设置_Nginx Ingress 高并发实践
    推荐一个国人开源的推荐系统
    异步并发利器:实际项目中使用CompletionService提升系统性能
    JDK中CompletableFuture类
    mysql日志redo log、undo log、binlog
    <a>标签下载文件 重命名失败 download 无效
    nginx geo黑名单
    夜莺微信报警-V3
    分布式事务的学习
    php实现AES/CBC/PKCS5Padding加密解密(又叫:对称加密)
  • 原文地址:https://www.cnblogs.com/HBING/p/5513770.html
Copyright © 2020-2023  润新知