アルゴリズムの美しさソースコードリリース(3)


本論文は『アルゴリズムの美——データ構造の背後に隠れた言語』(電子工業出版社2016年出版)の第4章のコード(P 91~P 17)を収録している.全文目録、「45アルゴリズム」カタログ、「22つの経典問題リスト」、及び賞虫つかみ活動の詳細は下記のリンクをご覧ください.http://blog.csdn.net/baimafujinji/article/details/50484348
付録の中の経典筆記試験、面接問題の参考解答は以下の通りです.
http://blog.csdn.net/baimafujinji/article/details/50484683
算法之美_源代码发布(3)_第1张图片
シークレットアルゴリズムの世界、データ構造の道.経典の問題を集めて、プログラミングの技法の趣を楽しんでいます.就職活動のホットスポットを呼び出して、営業界の有名企業の門をたたく.この本はアルゴリズムとデータ構造という話題をめぐって、順を追って漸進的に、深く浅く近代的なコンピュータ技術でよく使われている四十余りの古典的アルゴリズムを紹介しました.この過程で、本書は、一方向リンク表、一方向循環チェーン表、双方向循環リンク表を含むリンク表、スタック、キュー(普通の列と優先列を含む)、ツリー(二叉樹、ハフマンツリー、ヒープ、赤黒い木、AVLツリー、辞書ツリーを含む)、図、集合(非交差を含む)、および辞書などの一般的なデータ構造を体系的に説明している.また、22の経典問題(ジョセフ環問題、ハノータ問題、八皇后問題、騎士周遊問題などを含む)について説明することによって、データ構造の背後に隠されたアルゴリズム原理を徐々に明らかにし、読者の知識準備を促進し、思考技術を活性化させ、プログラミング能力の向上を妨げる十重二十重の垣根を突き破ることができる.完全なC+++ソースコードを補間してSTLの様々な容器を紹介しました.
オンライン書店:
China-pub中国インタラクティブ出版ネット:http://product.china-pub.com/4911922
ネットに入れる:http://product.dangdang.com/23851244.html
アマゾン:http://www.amazon.cn/%E7%AE%97%E6%B3%95%E4%B9%8B%E7%BE%8E-%E 9%A%90%E 5%8 C%BF%E 5%9 C%A 8%E 6%B 0%E 6%E 6%E 6%8 D%E 7%BB%93%E 6%E 8%83%E 8%E 5%E 7%E 7%E 8%E 7%E 8%E 8%E 8%E 8%E 8%E 8%E 8%E 8%E 5%E 9%E 9%E 9%E 9%E 9%E 9%E 7%E 9%E 9%E 9%E 9%E 9%E 7%E 9%E 9%E 9%E 7%E 7%E 7%E 9%E 8%E 8%E 8%E 8%E 8%E 8%E 81_8ですか?ie=UTF 8&qid=1453527399&sr=8-8&keywords=%E 5%B 7%A 6%E 9%A 39 E
もしあなたが本の読者だったら、ぜひアルゴリズム学習群(495573865)を加えてください.中にはもっと多くの資源があります.あなたが本を読む中で出会った疑問も私の第一時間の解答を得られます.このブログにもっと注目してください.この本のソースコードを全部ブログに発表します.
P 94:チェーンノード類
// #ifndef _LISTNODE_H_
// #define _LISTNODE_H_

template <class T> class ListNode {
          
	T data;
	ListNode<T>*  link;

public:

	ListNode() : link(NULL){}
	ListNode (T value) : link(NULL) , data(value) {}
	~ListNode(){};
	void SetLink(ListNode<T>* next);
	void SetData(T value);
	ListNode<T>*  GetLink ();
	T& GetData ();
};

template <class T>
void ListNode<T>::SetLink(ListNode<T>* next){ 
	link = next;
}

template <class T>
void ListNode<T>::SetData(T value){
	data = value;
}

template <class T>
ListNode<T>* ListNode<T>::GetLink(){
	return link;
}

template <class T>
T&  ListNode<T>::GetData(){//        
	return data;
}

//#endif
P 96:チェーン類
 #ifndef _LIST_H_
 #define _LIST_H_

#include "ListNode.h"

template <class T> class List{

ListNode<T>* head;
ListNode<T>* tail;

public:

	List ();
	virtual ~List ();

	bool AddTail (T value);
	bool RemoveTail ();
	bool InsertAt (int index , T value);
	bool RemoveAt (int index);

	T& GetAt (int index);
	bool IsEmpty ();
	int GetCount ();
	void RemoveAll ();

	ListNode<T>* GetHead();
	ListNode<T>* GetTail();
	ListNode<T>* GetNodeAt(int index);
	ListNode<T>* GetCur();
	ListNode<T>* TowardCur();
};

template<class T>  
List<T>::List()  
{  
    head=new ListNode<T>();  
    tail=head;  
    tail->SetLink (NULL);  
} 

template<class T>  
List<T>::~List()  
{  
    RemoveAll();  
    delete head;  
} 

template <class T> 
bool List<T> :: AddTail (T value){ 
	ListNode<T>* add = new ListNode<T> (value);
	tail->SetLink (add);    	//         ,     
	tail = tail->GetLink();		//            
	tail->SetLink (NULL); 
	if (tail != NULL)
		return true;
	else  
		return false;
}

template <class T > 
bool List< T >::InsertAt ( int index,T value ) {
	//         
	if(index > this->GetCount ()-1 || index<0 ) {  
		cout<<"A wrong position!
"; return false; } ListNode<T>* current = head; // while(index) { current = current->GetLink (); // , cur --index; } ListNode<T>* add = new ListNode<T> (value); add->SetLink (current->GetLink ()); // current->SetLink (add); if (current->GetLink () != NULL) return true; else return false; } template <class T> bool List<T>::RemoveTail() {// // RemoveAt(int index) return RemoveAt(this->GetCount()-1); } template <class T> bool List<T>::RemoveAt(int index){ // if(index > this->GetCount ()-1 || index<0){ cout<<"A wrong position!
"; return false; } // 。 ,cur //preCur ListNode<T>* cur,* curPre; cur = head; // index curPre = cur->GetLink(); // preCur cur while(index){ cur = cur->GetLink(); // , cur preCur curPre = curPre->GetLink(); --index; } // , cur if(tail == curPre) tail = cur; cur->SetLink (curPre->GetLink()); // delete curPre; if(curPre != NULL) return true; else return false; } template <class T> T& List<T>::GetAt(int index) { // value if (index > this->GetCount()-1 || index<0) { cout<<"A wrong position!
"; } ListNode<T>* cur; cur = head->GetLink(); while(index){ // ,cur cur = cur->GetLink(); --index; } return cur->GetData (); // value } template <class T> bool List< T >::IsEmpty ( ) { // return head ->GetLink()==NULL ; } template <class T> int List< T >::GetCount() { // ( ) int count = 0; // count // ( ) ListNode<T>* current = head->GetLink ( ); while(current != NULL) { ++count; current = current->GetLink ( ); // cur } return count; } template <class T> void List< T >::RemoveAll() { // ListNode<T>* cur; // , while(head->GetLink() != NULL) { cur = head->GetLink(); head->SetLink (cur->GetLink()); delete cur; } tail = head; // } template <class T> ListNode<T>* List<T>::GetHead(){// return head; } template <class T> ListNode<T>* List<T>::GetTail(){// return tail; } // index template <class T > ListNode< T >* List< T >::GetNodeAt(int index){ // if(index > this->GetCount()-1 || index<0){ cout<<"A wrong position!
"; } //handle , index 。 ListNode< T >* handle = head->GetLink(); while(index){ // index handle = handle->GetLink(); --index; } return handle; } template <class T> ListNode<T>* List<T>::GetCur(){ return cur; } template <class T> ListNode<T>* List<T>::TowardCur(){ cur = cur->GetLink(); return cur } #endif
チェーンテストプログラム
#include "stdafx.h"
#include "List.h"
#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	List<int> list;
	for(int i = 0; i <9; i++)
		list.AddTail(i);

	cout<<list.GetCount()<<endl;

	cout<<list.GetAt(3)<<endl;

	list.RemoveAt(3);

	cout<<list.GetCount()<<endl;
	cout<<list.GetAt(3)<<endl;

	list.RemoveAll();
	cout<<list.GetCount()<<endl;

	system("PAUSE");
	return 0;
}
P 101:秩序チェーンの結合
#include "stdafx.h"
#include "List.h"
#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	//      listFirst, listSecond
	List<int> listFirst;
	List<int> listSecond;

	//     listFirst
	listFirst.AddTail(1);
	listFirst.AddTail(6);
	listFirst.AddTail(8);
	listFirst.AddTail(9);
	listFirst.AddTail(13);

	//     listSecond
	listSecond.AddTail(0);
	listSecond.AddTail(3);
	listSecond.AddTail(4);
	listSecond.AddTail(6);
	listSecond.AddTail(11);
	listSecond.AddTail(17);

	while (listSecond.GetCount() != 0){ // listSecond        
		int indexFirst = 0;
		//   listSecond            listFirst  
		// while          
		while (listSecond.GetAt(0)>listFirst.GetAt(indexFirst)){
			++indexFirst;
			//  listFirst      ,      
			if (indexFirst == listFirst.GetCount()){
				break;
			}
		}
		if (indexFirst == listFirst.GetCount()){//     listFirst    
			listFirst.AddTail(listSecond.GetAt(0));
			listSecond.RemoveAt(0);
		}
		else{//     listFirst    
			listFirst.InsertAt(indexFirst, listSecond.GetAt(0));
			listSecond.RemoveAt(0);
		}
	}

	ListNode<int> * curNode = listFirst.GetHead();
	while (curNode != listFirst.GetTail())
	{
		curNode = curNode->GetLink();
		cout << curNode->GetData() << endl;
	}
	

	system("PAUSE");

	return 0;
}
P 104:一方向循環チェーン類
//#ifndef _CIRLIST_H_
//#define _CIRLIST_H_

#include "ListNode.h"

template <class T > class CirList{

	ListNode<T>* head;
	ListNode<T>* tail;
	ListNode<T>* cur;

public :
	CirList();
	~CirList();

	bool AddTail(T value);
	void RemoveThis();
	void RemoveAll();
	void SetBegin();
	int GetCount();
	ListNode<T>* GetCur();

	bool IsEmpty();
	T GetNext();
};

template <class T >  
CirList<T>::CirList(){//       
	head = tail = new ListNode<T>; //    ,    head   tail 
	cur = head; 
	head->SetLink(head);
}

template <class T>  
CirList<T>::~CirList(){
	RemoveAll();
	delete head;
}

template <class T> 
bool CirList< T >::AddTail(T value){ //         
    //    ,     value 
	ListNode<T>* add = new ListNode<T>(value);

	tail->SetLink(add);			//        
	tail = tail->GetLink();		//  tail      
	tail->SetLink(head);		//         

	if(tail != NULL)
		return true;
	else
		return false;
}

template <class T> 
void CirList<T>::RemoveThis(){// cur        
	if(cur == head){
    	//    cur head  ,          ,    cur     
		//  。
	    cur = cur->GetLink();
	}
 
	//   preCur  cur     , node_del        
	ListNode<T>* node_del = cur;
	ListNode<T>* preCur = cur;
    //  cur     ,  preCur    
	for(int i=0;i<this->GetCount();i++){
	    preCur = preCur->GetLink();
	}

    // cur         cur    ,   cur     
	preCur->SetLink(cur->GetLink());
	delete node_del;
    //   cur        。
	cur = preCur->GetLink();
	preCur = NULL;
}

template <class T> 
void CirList< T >::RemoveAll(){//      
    SetBegin();//          
	int length = GetCount();//      
	for(int i=0;i<length;i++){ 
		RemoveThis();
	}
	cur = head;  // cur  head  
}

template <class T> 
void CirList< T >::SetBegin(){// cur  head  ,       
	cur = head;
}

template <class T> 
int CirList<T>::GetCount(){//      
	int num = 0;
	if (cur==NULL)
		this->SetBegin();
	ListNode<T>* here = cur;  //        
	while(cur->GetLink() != here){ //      ,      
		cur = cur->GetLink();
		++num;
	}
	//cur = cur->GetLink();// cur         
	cur = here;
	return 
		num;
}

template <class T> 
ListNode<T>* CirList< T >::GetCur(){//       cur
	return cur;
}

template <class T > 
bool CirList< T >::IsEmpty(){//        
	return 
		head->GetLink() == head;
}

//          ,  cur        
template <class T> 
T CirList< T >::GetNext(){
	if(cur == head){
        //      ,              
		cur = cur->GetLink();
	}
	T num = cur->GetData();	//    
	cur = cur->GetLink();	//    cur       
	return 	
	num; 
}

//#endif
P 107:ジョセフリング問題
#include "stdafx.h"
#include "CirList.h"
#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	CirList<int> jos; //        ,       
	
	//      1~15 ,     1~15   
	for(int i=1;i<16;i++){
		jos.AddTail(i);
	}

	jos.SetBegin();//         

	//         ,                
	//      14 
	int length = jos.GetCount();
	for(int i=1;i<length;i++)
	{
		for(int j=0;j<3;j++)
			jos.GetNext();
		jos.RemoveThis();
	}
	
	cout<<jos.GetNext()<<endl;

	system("PAUSE");
	return 0;
}
P 108:マジシャン発牌問題
#include "stdafx.h"
#include "CirList.h"
#include <iostream>
//#include "vld.h"

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	CirList<int> poker;
	for(int i=0;i<13;i++){
		poker.AddTail(0);			//      ,  13    
	}
	cout<<poker.GetCount()<<endl;

	poker.SetBegin();
	poker.GetCur()->GetLink()->SetData(1);
	for(int i=2;i<14;i++){
		for(int j=0;j<i;j++){
			poker.GetNext();                //      
			if(poker.GetCur()->GetData() != 0){
				j--;			//         ,          
			}
		}
		poker.GetCur()->SetData(i);
	}

	poker.SetBegin();
	for(int i=0;i<13;i++){
		cout<<poker.GetNext()<<"*";
	}
	cout<<endl;

	system("PAUSE");
	return 0;
}
P 109:ラテン方陣問題
#include "stdafx.h"
#include "CirList.h"
#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	int num;
	cout<<"        (2<=N<=9):";
	cin>>num;
	CirList<int> latin;
	for(int i=1;i <= num; i++){
		latin.AddTail(i);				//      
	}

	latin.SetBegin();
	for(int i=1; i<=num; i++){
		for(int j=1; j<=num; j++){
			cout<<latin.GetNext()<<" ";	        //         
		}
		cout<<endl;
		latin.GetNext();				//             
	}

	system("PAUSE");
	return 0;
}
P 111:双方向循環チェーンノード類
#ifndef _DOULISTNODE_H
#define _DOULISTNODE_H

template <class T > class DouListNode{

	T data;
	DouListNode<T>* link;
	DouListNode<T>* prior;

public :

	DouListNode() : link(NULL),prior(NULL){}
	DouListNode(T value) : link(NULL),prior(NULL),data(value){}
	~DouListNode(){};
	void SetLink(DouListNode<T>* next);
	void SetPrior(DouListNode<T>* pre);
	DouListNode<T>* GetLink();
	DouListNode<T>* GetPrior();
	T& GetData();
};


template <class T > 
void DouListNode< T >::SetLink( DouListNode<T>* next ){ //  link  
	link = next;
}

template <class T > 
void DouListNode< T >::SetPrior( DouListNode<T>* pre ){ //  prior  
	prior = pre;
}

//                
template <class T > 
DouListNode<T>* DouListNode< T >::GetLink(){
	return link;
}

//                
template <class T > 
DouListNode<T>* DouListNode< T >::GetPrior(){
	return prior;
}

template <class T > 
T& DouListNode< T >::GetData(){//          
	return data;
}

#endif
P 14:双方向循環チェーン類
#ifndef _DOULIST_H
#define _DOULIST_H

#include "DouListNode.h"

template <class T> class DouList{
	DouListNode<T>* head;
	DouListNode<T>* tail;
	DouListNode<T>* cur;

public :
	DouList();
 	~DouList();

	bool AddTail(T value);
	bool AddHead(T value);
	void RemoveThis(bool direction);
	void RemoveAll();
	void SetBegin();
	int GetCount();
	void TowardCur();
	void BackCur();
	DouListNode<T>* GetCur();
	DouListNode<T>* GetHead();
	DouListNode<T>* GetTail();
	void InsertAfter(T value);

	bool IsEmpty();
	T GetNext();
	T GetPrior();
};


template <class T>  
DouList<T>::DouList(){//       

	//      ,    head    tail    
	head = tail = new DouListNode<T>; 
	cur = head; 
	head->SetLink(head); //      。
	head->SetPrior(tail);
}

template <class T>  
DouList<T>::~DouList(){
	RemoveAll();
	delete head;
}

template <class T> 
bool DouList<T>::AddTail(T value){ //          

	//     ,        value   
	DouListNode<T>* add = new DouListNode<T>(value);
    tail->SetLink(add);  //               
	add->SetPrior(tail);  
	tail = tail->GetLink(); 
	tail->SetLink(head);  //           

	//              ,        
	head->SetPrior(add);
    //            ,     。
	if(tail != NULL){
		return true;
	}
	else 
		return false;
}

//                          
template <class T> 
bool DouList<T>::AddHead(T value){

    //     ,    value 
	DouListNode<T>* add = new DouListNode<T>(value);
	add->SetPrior(head);          
	add->SetLink(head->GetLink()); 

	//             add
        //  add           
	head->GetLink()->SetPrior(add);
	head->SetLink(add);      

 	//            ,        tail 
	if(tail == head){
		tail = head->GetLink();
	}
	if(add != NULL){
		return true;
	}
	else 
	    return false;
}

//   cur        ,   cur       direction   
template <class T>
void DouList<T>::RemoveThis(bool direction){
    //    cur      ,           ,    cur
    //      
	if(cur == head){
		//  direction==0,  link     cur
		if(direction == 0)
	    	cur = cur->GetLink();
		//  direction==1,  prior      cur
		if(direction == 1)
			cur = cur->GetPrior();
	}
	
 	//    preCur   nextCur。
	//preCur   cur      
	//nextCur    cur      
	DouListNode<T>* preCur = NULL;
	DouListNode<T>* nextCur = NULL;
	preCur = cur->GetPrior();        
	nextCur = cur->GetLink(); 
	DouListNode<T>* node_del = cur;
	preCur->SetLink(cur->GetLink());  // cur              
	nextCur->SetPrior(cur->GetPrior()); // cur             
 
    //  direction     cur      
    // direction ==0,  link     cur 
	if(direction == 0)
		cur = nextCur;
	// direction ==1,  prior     cur
	if(direction == 1)
		cur = preCur;
	delete node_del;
}

template <class T > 
void DouList<T>::RemoveAll(){//      (      )

	SetBegin();            //      
	int length = GetCount();  //        
	for(int i=0;i<length;i++){ //    
		RemoveThis(0);
	}
	cur = head;
}

template <class T > 
void DouList<T>::SetBegin(){// cur     
	cur = head;
}

//           (      )
template <class T > 
int DouList<T>::GetCount(){
	int num = 0;   //         
	DouListNode<T>* here = cur; // here           
	while(cur->GetLink() != here){ //    
		cur = cur->GetLink();
		++num;
	}

	cur = cur->GetLink();    //     , cur      
	//      
	return num;
}

template <class T> 
void DouList<T>::TowardCur(){// cur link    
	cur = cur->GetLink();
}

template <class T > 
void DouList<T>::BackCur(){// cur prior    
	cur = cur->GetPrior();
}

template <class T > 
DouListNode<T>* DouList<T>::GetCur(){//    cur 
	return 
		cur;
}

template <class T > DouListNode<T>* DouList<T>::GetHead(){
	return 
		head;
}

template <class T > DouListNode<T>* DouList<T>::GetTail(){
	return 
		tail;
}

//        。
template <class T > 
bool DouList<T>::IsEmpty(){
	//                
	return 
		head->GetLink() == head;
}

// cur                value     
//            ,     AddTail( T value )
template <class T > 
void DouList<T>::InsertAfter(T value){

	DouListNode<T>* add = new DouListNode<T>(value);
	DouListNode<T>* nextCur = cur->GetLink();  //  cur      
	cur->SetLink(add);    // cur             
	add->SetLink(nextCur); 
    nextCur->SetPrior(add); // cur             
	add->SetPrior(cur);   

	if(cur==tail){
		tail = cur->GetLink();
	}
}

//  cur         ,  cur  link     
template <class T > 
T DouList<T>::GetNext(){
    //  cur     ,     cur
	if(cur == head){
		cur = cur->GetLink();
	}
	T num = cur->GetData();  //          
	cur = cur->GetLink();//       cur(link   )
	return 	
		num;
}

//  cur         ,  cur  prior     
template <class T > 
T DouList<T>::GetPrior(){
	//  cur     ,     cur
	if(cur == head){
		cur = cur->GetPrior();
	}
	T num = cur->GetData(); //          
	cur = cur->GetPrior();   //       cur (prior   )
	return 
		num;
}

#endif
P 115:バージニア暗号化問題
#include "stdafx.h"
#include "DouListNode.h"
#include "DouList.h"
#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	DouList<char> planText;
	DouList<char> cryptograph;
	DouList<int> key;
	DouList<char> trans;
	planText.SetBegin();
	planText.AddTail('y');
	planText.AddTail('o');
	planText.AddTail('u');
	planText.AddTail('a');
	planText.AddTail('r');
	planText.AddTail('e');
	planText.AddTail('i');
	planText.AddTail('n');
	planText.AddTail('d');
	planText.AddTail('a');
	planText.AddTail('n');
	planText.AddTail('g');      
	planText.AddTail('e');
	planText.AddTail('r');

	planText.SetBegin();
	cout<<"  :"<<'\t';
        for(int z=0;z<planText.GetCount();z++){
		cout<<planText.GetNext()<<" ";
	}
	cout<<endl<<endl;

       key.SetBegin(); //      
       for(int i=0;i<6;i++){
	   key.AddTail(1+rand()%9);
       }

	cout<<"  :"<<'\t';
	for(int i=0;i<key.GetCount();i++){
		cout<<key.GetNext()<<" ";
	}
	cout<<endl<<endl;

	planText.SetBegin();
	key.SetBegin();
	cryptograph.SetBegin();
	for(int i=0;i<planText.GetCount();i++){

		char c = planText.GetNext();
		int num = key.GetNext();
		if('a'<=c&&c<='z'-num)
			c=c+num;
		else if('z'-num<c&&c<='z')
			c = c+num-1-'z'+'a';
		cryptograph.AddTail(c);
	}

	cryptograph.SetBegin();
	cout<<"  :"<<'\t';
        for(int j=0; j<cryptograph.GetCount(); j++){
		cout<<cryptograph.GetNext()<< " ";
	}
	cout<<endl<<endl;

	trans.SetBegin();
	planText.SetBegin();
	key.SetBegin();
	for(int k=0; k<planText.GetCount(); k++){


		char c = cryptograph.GetNext();
		int num = key.GetNext();
		if('a'<=c-num && c-num<='z')
			c=c-num;
		else if('a'>c-num && c>='a')
			c = 'z'-('a'-c+num)+1;

		cryptograph.AddTail(c);
		trans.AddHead(c);
	}

	trans.SetBegin();
	cout<<"  :"<<'\t';
        for(int k=0;k<trans.GetCount();k++){
		cout<<trans.GetPrior()<<" ";
	}
	cout<<endl<<endl;

	system("PAUSE");
	return 0;
}