1. 程式人生 > >八皇后問題-遞迴和迭代兩種解法

八皇后問題-遞迴和迭代兩種解法

問題:

經典的八皇后問題

分析:

遞迴解法直觀易懂,但是迭代法需要想點思路

程式碼如下:

/*
 * eightQueen.cpp
 *
 *  Created on: 2012-10-14
 *      Author: happier
 */

#include <iostream>
using namespace std;

#define N 8
int sum = 0;
int *x = new int[N + 1];

bool place(int k)
{
	int i;
	for (i = 1; i < k; i++)
	{
		if (x[i] == x[k] || abs(i - k) == abs(x[i] - x[k]))	//第一個判斷行不能相同,第二個判斷對角線不能相同
			return false;
	}
	return true;
}

void backtrack2()//迭代回溯
{
	int i;
	x[1]=0;
	int k=1;
	while(k>0)
	{
		x[k]+=1;//當前列加1的位置開始搜尋
		while((x[k]<=N) && !place(k))//當前列位置是否滿足條件
			x[k]+=1;//不滿足條件,繼續搜尋下一個位置

		if(x[k]<=N)//存在滿足條件的列
		{
			if(k==N)//是最後一個皇后,完成搜尋
			{
				for(i=1; i<=N; i++)
					cout<<x[i]<<" ";
				cout<<endl;
				sum++;

			}
			else//不是,則處理下一個皇后
			{
				k++;
				x[k]=0;
			}
		}
		else//回溯
		{
			k--;
		}

	}
}

void backtrack(int t) //遞歸回溯
{
	int i = 0;
	if (t > N)	//遞迴結束返回
	{
		for (i = 1; i <= N; i++)
			cout << x[i] << " ";
		cout << endl;
		sum++;
	}
	else
	{
		for (i = 1; i <= N; i++)
		{
			x[t] = i;	//選擇一個皇后
			if (place(t))	//判斷第t列,第i行放一個皇后是否合法
				backtrack(t + 1);
		}
	}
}
int main()
{

	backtrack(1);
	cout << sum << endl;
	sum = 0;
	backtrack2();
	cout << sum << endl;

	return 0;
}

總結:

這裡迭代法沒有用棧去模擬,因為理解了其中的含義,可以寫出非遞迴法,但是本質上還是存在回溯的。

相關推薦

皇后問題-解法

問題: 經典的八皇后問題 分析: 遞迴解法直觀易懂,但是迭代法需要想點思路 程式碼如下: /* * eightQueen.cpp * * Created on: 2012-10-14 * Author: happier */ #include <

方式實現歸併排序(Java版)

遞迴版 package MergeSort; import Utils.SortUtils; /** * 歸併排序遞迴版 * @author liguodong */ pub

C語言實現斐波那契數列的方法()

兩種方法實現斐波那契數列,遞迴實現起來稍簡單些,思路也清晰些,但執行效率顯然不如迭代 下面是編譯通過的兩種方式實現斐波那契數列的C語言程式碼:/* * fibanacci.c * * Created on: 2015-3-16 * Author: flo

01揹包問題:回溯法限界分支、方式

01揹包問題 遞迴方式模板: void backtrack(int t){ if(t > n) output(x); else{ for(int i = f(n,t); i <= g(n,t);i++){ x[t

關於

首先明確遞迴和迭代的概念。 遞迴:程式呼叫自身的程式設計技巧(將大問題化解為相同結構的小問題,從待解問題一直分解到已知答案的最小問題,在逐級返回得            到原解)       &nb

dns的查詢及linux下dns主從關係的部署(推薦)

什麼是dns dns存在的意義 dns解析的過程及原理 dns主從關係的部署 什麼是dns Domain Name Server的縮寫,就是域名伺服器的意思,域名包括域名伺服器和域名解析器,域名是什麼呢?我們平時在瀏覽器中輸入的baidu.com就

分治:分治動態規劃的區別,二分檢索方式實現

分治法 分治一般可以直接使用遞迴實現,在不考慮空間消費的情況下和迭代方式時間消耗相差不多 ================================================================== 分治一般形式: T(n) = k*T(n/m) + f(

的區別

遞迴和迭代都是迴圈中的一種。 簡單地說,遞迴是重複呼叫函式自身實現迴圈。迭代是函式內某段程式碼實現迴圈,而迭代與普通迴圈的區別是:迴圈程式碼中參與運算的變數同時是儲存結果的變數,當前儲存的結果

leetcode 101. Symmetric Tree 判斷對稱樹,

Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). For example, this binary tree is symmetr

圖形結構:克隆圖,圖的遍歷的應用,

克隆一張無向圖,圖中的每個節點包含一個 label (標籤)和一個 neighbors (鄰接點)列表 。 克隆圖時圖的遍歷的應用,樹的遍歷,圖的遍歷是最基本的操作,他們和陣列的遍歷是一樣的,線性結構的問題都是在陣列遍歷的基礎上進行操作,同樣樹的問題和圖的問題也都是在其遍歷的基礎上操作,

php實現斐波那契數列

<?php //1 1 2 3 5 8 13 21 34 55 //迭代 function fib($n){ if($n<1) return -1; $a[1]=$a[2]=1;

94 Binary Tree Inorder Traversal 【的對比較分析】

一道很常規的二叉樹遍歷題,相信大家都在課上學習過。 但是題目要求是不能用遞迴呼叫的方法,也就是課上講過的方法。要用iterative迭代的方法,也就是一個一個找,通過while迴圈來輸出。 先把遞迴的方法程式碼寫出來,如下。要注意的是,我連遞迴呼叫都不能立馬想起來,只想到了

菲波那切數列演算法

#include <iostream> using namespace std; int Fabonaqie1(int num){ //迭代演算法1 int a2 = 0; if (num == 1){ return 0; } else if(num == 2){

用斐波那契數列來說明的區別

遞迴:自己呼叫自己 迭代:反覆替換的意思 遞迴與迭代都是基於控制結構:迭代用重複結構,而遞迴用選擇結構。 遞迴與迭代都涉及重複:迭代顯式使用重複結構,而遞迴通過重複函式呼叫實現重複。 遞迴與迭代都涉及

深究的區別、聯絡、優缺點及例項對比

萬物的存在是需要時間的檢驗的,遞迴沒有被歷史所埋沒,即有存在的理由。從理論上說,所有的遞迴函式都可以轉換為迭代函式,反之亦然,然而代價通常都是比較高的。但從演算法結構來說,遞迴宣告的結構並不總能夠轉換為迭代結構,原因在於結構的引申本身屬於遞迴的概念,用迭代的方法在設計初期根本無法實現,這就像動多型的東西並不總

有什麼區別?

遞迴和迭代都是迴圈的一種。 簡單地說,遞迴是重複呼叫函式自身實現迴圈。迭代是函式內某段程式碼實現迴圈,而迭代與普通迴圈的區別是:迴圈程式碼中參與運算的變數同時是儲存結果的變數,當前儲存的結果作為下一次迴圈計算的初始值。 遞迴迴圈中,遇到滿足終止條件的情況時逐層返回來

【演算法】二叉樹、N叉樹先序、中序、後序、BFS、DFS遍歷的實現記錄(Java版)

        本文總結了刷LeetCode過程中,有關樹的遍歷的相關程式碼實現,包括了二叉樹、N叉樹先序、中序、後序、BFS、DFS遍歷的遞迴和迭代實現。這也是解決樹的遍歷問題的固定套路。 一、二叉樹的先序、中序、後序遍歷  1、遞迴模板  (1)

LeetCode 926. 將字串翻轉到單調遞增 實現動態規劃 解法

這個題做了一個多小時,考慮複雜了。 開始推動規沒有推出來,然後找到一個遞推關係:從左往右,如果是0,則不需要變動;如果是1,則有兩種選擇(1)將1變為0(2)將1後面的所有數字變為1,這兩種方法中的變動數字最小的方法就是最佳方法,然後依次遞推,很容易寫出遞迴程式。但是這裡面存

遍歷

  遞迴   如果一個函式在內部呼叫自身本身,這個函式就是遞迴函式。   條件:必須要有收斂條件和遞迴公式。   特性:1.必須有一個明確的結束條件。      2.每次進入更深一層遞迴時,問題規模相比賞析遞迴都應有所減少。      3.遞迴效率不高,遞迴層次過多會導致棧溢位(遞迴最大999層)。

斐波那契數列的解題思路:VS

一、問題描述 要求輸入一個整數n,請你輸出斐波那契數列的第n項 二、演算法分析 給出一系列斐波拉契數列:0 1 1 3 5 8 13 21 。。。 通過觀察,很容易發現:          1     n=0,