1. 程式人生 > 實用技巧 >44 遞迴的思想與應用(中)

44 遞迴的思想與應用(中)

原文: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;
}