標籤:資料結構 堆棧 漢諾塔
第三章 解決堆棧的編程問題
堆棧是一種特殊的線性表,是一種只允許在表的一端進行插入或刪除操作的線性表。
堆棧的主要特點是後進先出。
用一片連續的儲存空間來儲存棧中的元素,這樣的棧稱為順序棧。
用鏈式儲存結構儲存的棧稱為鏈棧。
漢諾塔問題
漢諾塔問題來自一個古老的傳說:在世界剛剛被建立的時候有一座磚石寶塔(A),其上有64個金蝶。所有按從大到小的順序從塔底堆放至塔頂。緊挨著這座塔有兩個磚石塔(B和C)。從世界創始之日起,婆羅門的牧師們就一直在試圖把A塔上的碟子移動到B上去,其間藉助於C的協助。由於碟子非常重,因此,每次只能移動一個碟子。另外,任何時候都不能把一個碟子放在比它小的碟子上面。按照這個傳說,當牧師們完成所有的任務之後,世界末日也就到了。
在漢諾塔問題中,已知n個碟子和3座塔。初始時所有的碟子按從大到小的次序從塔A的底部堆放至頂部,現在需要把碟子都移動到B塔,每次移動一個碟子,而且任何時候都不能把大碟子放到小碟子上面。
【基本要求】
(1) 編寫一個演算法實現將A塔上的碟子移動到B塔上,大碟子在下,小碟子在上。
(2) 將移動的過程顯示出來
思路:
650) this.width=650;" src="http://s3.51cto.com/wyfs02/M02/49/E0/wKiom1QdSrLwFtDQAAD-R53j8M8491.jpg" title="abcd.png" alt="wKiom1QdSrLwFtDQAAD-R53j8M8491.jpg" />
由上可知,要想把n個碟子從A移動到目標塔(不妨設為B),則需要將n-1個碟子移動到緩衝塔(C),然後將最大的碟子放到B;
再往前迭代,即以A為緩衝塔,只需將n-2個碟子移動到B,然後將次大的移動到C;
……
直到最後只需移動一個碟子到指定的塔。
漢諾塔碟子的移動次數為:2n-1
C#代碼實現如下:
1) 封裝棧結點:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LinkStack
{
class StackNode<T>
{
private T data;
privateStackNode<T> next;
public StackNode()
{
data = default(T);
next = null;
}
public StackNode(Tval)
{
data = val;
next = null;
}
public StackNode(Tval, StackNode<T> p)
{
data = val;
next = p;
}
public T Data
{
get
{
return data;
}
set
{
data = value;
}
}
publicStackNode<T> Next
{
get
{
return next;
}
set
{
next = value;
}
}
}
}
2) 棧操作介面:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LinkStack
{
interface IStack<T>
{
void Push(T item);//壓棧
T Pop();//出棧
bool isEmpty();
void Clear();
}
}
3) 鏈棧封裝:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LinkStack
{
classLStack<T>:IStack<T>
{
privateStackNode<T> top;
private int count;
private string name =string.Empty;
public int Count
{
get { returncount; }
}
public string Name
{
get { return name;}
set { name =value; }
}
public LStack()
{
top = null;
count = 0;
}
public LStack(stringname)
{
this.name = name;
top = null;
count = 0;
}
public void Push(Titem)
{
StackNode<T> tnode = newStackNode<T>(item);
if (top == null)
{
top = tnode;
}
else
{
tnode.Next =top;
top = tnode;
}
count++;
}
public T Pop()
{
if (top == null&& count == 0)
{
throw newException("棧為空白!");
}
StackNode<T>tnode = top;
top = top.Next;
count--;
return tnode.Data;
}
public bool isEmpty()
{
if (top == null&& count == 0)
{
return true;
}
return false;
}
public void Clear()
{
top = null;
count = 0;
}
}
}
4) 演算法實現:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LinkStack
{
class Program
{
/// <summary>
/// 解決漢諾塔問題
/// </summary>
/// <paramname="args"></param>
static voidMain(string[] args)
{
//三根塔柱
LStack<int>tln_A =new LStack<int>("A");
LStack<int>tln_B = new LStack<int>("B");
LStack<int>tln_C = new LStack<int>("C");
Console.WriteLine("請輸入漢諾塔中上碟子的個數");
string nstr =Console.ReadLine();
int n;
if(!int.TryParse(nstr, out n))
{
Console.WriteLine("請輸入有效整數!");
}
for (int i = n;i>=1; i--)
{
tln_A.Push(i);
}
MoveTa(n, tln_B,tln_A, tln_C);
Console.WriteLine("B塔元素依次為:");
for (int i = 0; i< n;i++ )
{
Console.Write(tln_B.Pop() + " ");
}
Console.ReadKey();
}
static void MoveTa(intn, LStack<int> desT, LStack<int> srcT,LStack<int> bufT)
{
if (n == 1)
{
int t =srcT.Pop();
desT.Push(t);
string str="將金碟"+t+"從塔" + srcT.Name + "移動到" +desT.Name;
Console.WriteLine(str);
}
else
{
MoveTa(n - 1,bufT,srcT,desT);
//移動最大的金蝶
int t =srcT.Pop();
desT.Push(t);
string str ="將金碟" + t + "從塔" + srcT.Name + "移動到" +desT.Name;
Console.WriteLine(str);
MoveTa(n - 1,desT, bufT, srcT);
}
}
}
}
本文出自 “虎哥的部落格” 部落格,請務必保留此出處http://7613577.blog.51cto.com/7603577/1555563
第三章解決堆棧的編程問題