44 遞迴的思想與應用(中)
阿新 • • 發佈:2020-08-15
原文:https://www.cnblogs.com/wanmeishenghuo/p/9678143.html參考狄泰軟體相關教程
將大問題分解,先將第一個節點拿出來,將其它的節點看成一個整體。
#include <iostream> #include <cstring> #include "DTString.h" using namespace std; using namespace DTLib; struct Node { int value; Node* next; }; Node* create_list(int v, int len) // v:資料元素從哪一個之開始。 len:長度 { Node* ret = NULL; Node* slider = NULL; for(int i=0; i<len; i++) { Node* n = new Node(); n->value = v++; n->next = NULL; if( slider == NULL ) { slider = n; ret = n; } else { slider->next = n; slider = n; } } return ret; } void destroy_list(Node* list) { while( list ) { Node* del = list; list = list->next; delete del; } } void print_list(Node* list) { while( list ) { cout << list->value << "->"; list = list->next; } cout << "NULL" << endl; } Node* reverse(Node* list) { if( (list == NULL) || (list->next == NULL) ) { return list; } else { Node* guard = list->next; Node* ret = reverse(list->next); guard->next = list; list->next = NULL; return ret; } } int main() { Node* list = create_list(1, 5); print_list(list); list = reverse(list); print_list(list); destroy_list(list); return 0; }
實驗2:
#include <iostream> #include <cstring> #include "DTString.h" using namespace std; using namespace DTLib; struct Node { int value; Node* next; }; Node* create_list(int v, int len) // v:資料元素從哪一個之開始。 len:長度 { Node* ret = NULL; Node* slider = NULL; for(int i=0; i<len; i++) { Node* n = new Node(); n->value = v++; n->next = NULL; if( slider == NULL ) { slider = n; ret = n; } else { slider->next = n; slider = n; } } return ret; } void destroy_list(Node* list) { while( list ) { Node* del = list; list = list->next; delete del; } } void print_list(Node* list) { while( list ) { cout << list->value << "->"; list = list->next; } cout << "NULL" << endl; } Node* reverse(Node* list) { if( (list == NULL) || (list->next == NULL) ) { return list; } else { Node* guard = list->next; Node* ret = reverse(list->next); guard->next = list; list->next = NULL; return ret; } } Node* merge(Node* list1, Node* list2) { if( list1 == NULL ) { return list2; } else if( list2 == NULL ) { return list1; } else if( list1->value < list2->value ) { /* Node* list1_ = list1->next; Node* list = merge(list1_, list2); list1->next = list; return list1; */ return (list1->next = merge(list1->next, list2), list1); //逗號表示式 } else { /* Node* list2_ = list2->next; Node* list = merge(list1, list2_); list2->next = list; return list2; */ return (list2->next = merge(list2->next, list1), list2); //逗號表示式 } } int main() { Node* list1 = create_list(1, 5); Node* list2 = create_list(2, 6); print_list(list1); print_list(list2); Node* list = merge(list1, list2); print_list(list); destroy_list(list); return 0; }
#include <iostream> #include <cstring> #include "DTString.h" using namespace std; using namespace DTLib; void HanoiTower(int n, char a, char b, char c) // a ==> src b ==> middle c ==> dest { if( n == 1 ) { cout << a << "-->" << c << endl; } else { HanoiTower(n-1, a, c, b); HanoiTower(1, a, b, c); HanoiTower(n-1, b, a, c); } } int main() { HanoiTower(3, 'a', 'b', 'c'); return 0; }
e始終指向字串的開頭,用來列印,s用來控制交換。
一開始,a和a交換,全排列b、c。
然後,a和b交換,全排列a、c。
然後交換a和c,全排列b、a。
如果兩個字元是一樣的,就沒有必要交換,否則全排列有重複的現象。
#include <iostream> #include <cstring> #include "DTString.h" using namespace std; using namespace DTLib; void HanoiTower(int n, char a, char b, char c) // a ==> src b ==> middle c ==> dest { if( n == 1 ) { cout << a << "-->" << c << endl; } else { HanoiTower(n-1, a, c, b); HanoiTower(1, a, b, c); HanoiTower(n-1, b, a, c); } } void permutation(char* s, char* e) // e始終指向字串開頭,用於列印 { if( *s == '\0' ) { cout << e << endl; } else { int len = strlen(s); for(int i=0; i<len; i++) //第一個字元一次和後面的元素交換 { if( (i == 0) || (s[0] != s[i]) ) { swap(s[0], s[i]); // 交換 permutation(s+1, e); // 交換之後將子串全排列 swap(s[0], s[i]); // 再交換回來 } } } } int main() { char s[] = "abc"; char s1[] = "aac"; permutation(s, s); cout << "----------" << endl; permutation(s1, s1); return 0; }