- 一列货运列车共有n节车厢,每节车厢将停放在不同的车站。假定n个车站的编号分别为1~n,即货运列车按照第n站至第1站的次序经过这些车站。为了便于从列车上卸掉相应的车厢,车厢的编号应与车站的编号相同,这样,在每个车站只要卸掉最后一节车厢。所以,给定任意次序的车厢,必须重新排列它们。车厢的重排工作可以通过转轨站完成。在转轨站中有一个入轨、一个出轨和k个缓冲轨,缓冲轨位于入轨和出轨之间。假定缓冲轨按先进先出的方式运作,设计算法解决火车车厢重排问题。
基本要求
设计存储结构表示n个车厢、k个缓冲轨以及入轨和出轨;
设计并实现车厢重排算法;
分析算法的时间性能。
设计思想
假设有3个缓冲轨,入轨中有9节车厢,次序为5,8,1,7,4,2,9,6,3,重排后,9节车厢出轨次序为9,8,7,6,5,4,3,2,1。重排过程如下:
3号车厢不能直接移至出轨(因为1号车厢和2号车厢必须排在3号车厢之前),因此,把3号车厢移至H1。6号车厢可放在H1中3号车厢之后(因为6号车厢将在3号车厢之后出轨)。9号车厢可以继续放在H1中6号车厢之后,而接下来的2号车厢不能放在9号车厢之后(因为2号车厢必须在9号车厢之前出轨)。因此,应把2号车厢移至H2,4号车厢可以放在H2中2号车厢之后,7号车厢可以继续放在4号车厢之后,如图4所示。至此,1号车厢可通过H3直接移至出轨,如图5所示。由于5号车厢此时仍在入轨中,所以把8号车厢移动至H2,这样就可以把5号车厢直接从入轨移至出轨,如图6所示。此后,可依次从缓冲轨中移出6号、7号、8号和9号车厢,如图7所示。注意:图片由于没有图床,所以自己画一下就好
代码
- 接口一:链表接口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace train
{
interface ILinearList<T> where T :IComparable<T>
{
int Length { get; }
T this[int index]{ get; set; }
bool IsEmpty();
void Insert(int index, T data);
void Remove(int index);
int Search(T data);
void Clear();
}
}
- 接口二:栈的接口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace train
{
interface IStack<T> where T : IComparable<T>
{
int Length { get; }
T StackTop { get; }
void Push(T data);
void Pop();
bool IsEmpty();
void Clear();
}
}
- 工具类一:节点封装,链表
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace train
{
class SNode<T> where T :IComparable<T>
{
public T Data { get; set; }
public SNode<T> Next { get; set; }
public SNode(T data)
{
Data = data;
Next = null;
}
public SNode(T data, SNode<T> next) {
Data = data;
Next = next;
}
}
}
- 工具类二 链表结构封装
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace train
{
class SLinkList<T> :ILinearList<T> where T : IComparable<T>
{
protected SNode<T> PHead;
public int Length
{
get;
private set;
}
public SLinkList()
{
Length = 0;
PHead = null;
}
public void InsertAtFirst(T data)
{
PHead = new SNode<T>(data, PHead);
Length++;
}
private SNode<T> Locate(int index)
{
if (index < 0 || index > Length - 1)
throw new IndexOutOfRangeException("1");
SNode<T> temp = PHead;
for (int i = 0; i < index; i++)
temp = temp.Next;
return temp;
}
public void InsertAtRear(T data)
{
if (PHead == null)
PHead = new SNode<T>(data);
else
Locate(Length - 1).Next = new SNode<T>(data);
Length++;
}
public T this[int index]
{
get
{
if (index < 0 || index > Length - 1)
throw new IndexOutOfRangeException("2");
return Locate(index).Data;
}
set
{
if (index < 0 || index > Length - 1)
throw new IndexOutOfRangeException("3");
Locate(index).Data = value;
}
}
public void Clear()
{
PHead = null;
Length = 0;
}
public void Insert(int index, T data)
{
if (index < 0 || index > Length)
throw new IndexOutOfRangeException("4");
if (index == 0)
{
InsertAtFirst(data);
}
else if (index == Length) {
InsertAtRear(data);
}
else
{
Locate(index - 1).Next = new SNode<T>(data,Locate(index));
Length++;
}
}
public bool IsEmpty()
{
return Length == 0;
}
public void Remove(int index)
{
if (index < 0 || index > Length - 1)
throw new IndexOutOfRangeException("5");
if (index == 0)
PHead = PHead.Next;
else
Locate(index - 1).Next = Locate(index).Next;
Length--;
}
public int Search(T data)
{
int i;
SNode<T> temp = PHead;
for (i = 0; i < Length; i++)
{
if (temp.Data.CompareTo(data) == 0)
break;
temp = temp.Next;
}
return i == Length ? -1 : i;
}
}
}
- 工具类三:栈的结构封装
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace train
{
class LinkStack<T> : IStack<T> where T : IComparable<T>
{
private readonly SLinkList<T> _lst;
public LinkStack()
{
_lst = new SLinkList<T>();
}
public int Length
{
get
{
return _lst.Length;
}
}
public T StackTop
{
get
{
if (_lst.Length == 0)
throw new Exception("栈为空");
return _lst[0];
}
}
public void Clear()
{
_lst.Clear();
}
public bool IsEmpty()
{
return _lst.IsEmpty();
}
public void Pop()
{
if (_lst.Length == 0)
throw new Exception("栈为空");
_lst.Remove(0);
}
public void Push(T data)
{
_lst.InsertAtFirst(data);
}
}
}
- 最终结果program的封装
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace train
{
class Program
{
//火车入轨出轨问题
static void Main(string[] args)
{
int[] num = { 5, 8, 4, 7, 1, 9, 2, 6, 3 };
bool a = change(num, 3);
do
{
if (a == false)
{
Console.WriteLine("你的输入的栈不够");
Console.WriteLine("请输入新加多少栈");
}
else
{
break;
}
string b = Console.ReadLine();
a = change(num, 3 + int.Parse(b));
} while (a == false);
}
private static bool change(int[] num, int k)
{
LinkStack<int>[] h = new LinkStack<int>[k];
for (int b = 0; b < k; b++)
{
h[b] = new LinkStack<int>();
}
int j = 1;
int i = 0;
do
{
if (i < 9)
{
if (num[i] == j)
{
Console.WriteLine("{0}从入轨到出轨", j);
i++;
j++;
}
else
{
bool judge = false;
//进行栈顶的比较
for (int a = 0; a < k; a++)
{
if (h[a].Length > 0)
{
if (h[a].StackTop == j)
{
Console.WriteLine("{0}从栈{1}出栈", j, a);
judge = true;
h[a].Pop();
j++;
break;
}
}
}
//进行入轨
if (judge == false)
{
bool c = ru(h, k, num[i]);
if (c == false)
return false;
}
i++;
}
}
else
{
for (int a = 0; a < k; a++)
{
if (h[a].Length > 0)
{
if (h[a].StackTop == j)
{
h[a].Pop();
Console.WriteLine("{0}从栈{1}出栈", j, a);
j++;
break;
}
}
}
}
} while (j != 10);
if (j == 10)
return true;
else
return false;
}
private static bool ru(LinkStack<int>[] h, int k, int b)
{
bool mathod = false;
for (int i = 0; i < k; i++)
{
if (h[i].Length == 0)
{
h[i].Push(b);
Console.WriteLine("{0}进入栈{1}", b, i);
mathod = true;
break;
}
else if (b < h[i].StackTop)
{
h[i].Push(b);
Console.WriteLine("{0}进入栈{1}", b, i);
mathod = true;
break;
}
}
return mathod;
}
}
}