您的位置:首页 > 理论基础 > 数据结构算法

算法竞赛入门经典:第六章 数据结构基础 6.3移动小球

2015-08-17 19:50 507 查看
/*
移动小球:
我有小球,从左到右一次编号为1,2,3,...,n
你可以执行两种指令:
A X Y表示把小球X移动到小球Y的左边,B X Y表示把小球X移动到小球Y的右边。指令保证合法,即X不等于Y。
输入小球个数n,指令条数m和m条指令,从左到右输出最后的序列。注意,n可能高达500000,而m可能高达100000
输入:
6 2
A 1 4
B 3 5
输出:
2 1 4 5 3 6

关键:建立单链表,添加左移和右移函数
*/
#include <stdio.h>
#include <stdlib.h>

typedef struct LNode
{
	int iData;
	struct LNode* next;
}LNode,*LinkList;

void move(LinkList list,int n1,int n2)
{
	//先找到n1与n2的位置
	LNode* q = list,*q1,*q2,*p1,*p2;//p1与p2是n1与n2前面一个节点指针
	LNode* p = q->next;
	int iPos1,iPos2;
	while(p)
	{
		if(p->data == n1)
		{
			q1 = q;
			p1 = q1->next;
		}
		else if(p->data == n2)
		{
			q2 = q;
			p2 = q2->nxt;
		}
		q = p;
		p = p->next;
	}
	//拆下n1
	q1->next = p1->next;
	//q2指向p1
	q2->next = p1;
	//p1指向p2
	p1->next = p2;
}

//尾插法建立单链表
LinkList buildLinkList(LinkList list,int n)
{
	LNode* rear = list;
	for(int i = 1 ;i < n;i++)
	{
		LNode* newNode = (LNode*)malloc(sizeof(LNode));
		newNode->iData = i;
		rear->next = newNode;//尾插法建立单链表时,只需要将末尾指向新节点,再让末尾节点称为新节点即可
		rear = newNode;
	}
	rear->next = NULL;//置最后一个节点为空
	return list;
}

void moveBall()
{
	int n,m;
	while(EOF != scanf("%d %d",&n,&m))
	{
		//LinkList list;//单链表的头结点必须用malloc建立起来
		LinkList list = (LinkList)malloc(sizeof(LNode));
		list->iData = -1;
		buildLinkList(list,n);
		for(int i = 0 ; i < m;i++)
		{
			char ch[10];
			int n1,n2;
			scanf("%s %d %d",&ch,&n1,&n2);
			if('A' == ch[0])//易错,这里scanf("%s")指令类型用%s是因为:用%d读取整数后,没有读取回车换行符,而后面的%c会读取换行符,用%s跳过换行符
			{
				move(list,n1,n2);//左移
			}
			else
			{
				move(list,n2,n1);//右移
			}
		}
		LNode* front = list->next;
		while(front)
		{
			printf("%d ",front->iData);
			front = front->next;
		}
	}
}

int main(int argc,char* argv[])
{
	system("pause");
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: