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\n%05d %d", head->address, head->address, head->data);
			head = head->nxt;
		}
		printf(" -1\n");

		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\n%05d %d", head->address, head->address, head->data);
		head = head->nxt;
	}
	printf(" -1\n");
	
	return 0;
}


4、 问题与解决

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

5、 最后

  • 其实,这代码并没有AC (⊙ˍ⊙) 有一个点超时了...
  • 大概能猜到是重新按顺序排列链表那边耗了很多时间,不过实在不会改了orz
  • 我觉得吧,对于一个全部用数组A掉上学期C语言上机的指针题以及这学期程序设计语言综合设计的指针题的人,做到这样已经很棒了(不要脸hhh)
  • 现在应该能算是勉强会用链表了吧 0 0 不过...还是好想用数组啊
  • 真的超级赞的呀~又快又好找bug
posted @ 2016-05-20 23:27  H_BING  阅读(283)  评论(0编辑  收藏  举报