問題定義:
You are given a binary tree in which each node contains a value. Design an algorithm to print all paths which sum up to that value. Note that it can be any path in the tree-it does not have to start at the root.
解題思路:
一層一層的遍歷,保存當前節點到根節點的完整路徑,然後從當前節點向上掃描,如果找到了當前節點到某個節點的和等於給定值,則輸出之。程序對每個節點都需要遍歷一遍,還要掃描當前節點到根節點的路徑,且需要保存每個節點到根節點的路徑,所以時間復雜度為O(nlgn),空間復雜度為O(nlgn)。(ps:關於本程序中建樹部分,可以參考: http://www.linuxidc.com/Linux/2012-05/61459.htm )
代碼實例:
- #include <algorithm>
- #include <iostream>
- #include <time.h>
- #include <assert.h>
- #include <stdio.h>
- #include <vector>
-
-
- using namespace std;
-
- struct node
- {
- int data;
- struct node * lchild;
- struct node * rchild;
- };
-
-
- //將數組轉換為深度最低的二叉樹,采用了二分查找的思想
- struct node* ConvertArrayToTree(int data[], int first, int last)
- {
- if (last < first)
- {
- return NULL;
- }
- else
- {
- int mid = ( last + first ) / 2;
- struct node * newNode = NULL;
- newNode = (struct node *)malloc(sizeof(struct node));
- newNode->data = data[mid];
- newNode->lchild = ConvertArrayToTree(data, first, mid - 1);
- newNode->rchild = ConvertArrayToTree(data, mid + 1, last);
- return newNode;
- }
- }
-
- //再最左邊插入一個節點
- void InsertNodeAtLeft(struct node *root, struct node *newNode)
- {
- assert(root != NULL && newNode != NULL);
- while(root->lchild != NULL)
- {
- root = root->lchild;
- }
- root->lchild = newNode;
- }
-
- //在最右邊插入一個節點
- void InsertNodeAtRight(struct node *root, struct node *newNode)
- {
- assert(root != NULL && newNode != NULL);
- while(root->rchild != NULL)
- {
- root = root->rchild;
- }
- root->rchild = newNode;
- }
- //中序遍歷
- void Traverse(struct node *root)
- {
- if (root == NULL)
- {
- return;
- }
- Traverse(root->lchild);
- Traverse(root->rchild);
- printf("%d\t", root->data);
- }
-
- //打印和為sum的路徑
- void print(vector<int>& buffer, int first, int last)
- {
- int i;
- for (i = first; i <= last; i++)
- {
- cout << buffer[i] << "\t";
- }
- cout << endl;
- }
- void findSum(struct node *head, int sum, vector<int> &buffer, int level)
- {
- if (head == NULL) return;
-
- int i;
- int tmp = sum;
- buffer.push_back(head->data);
- for (i = level; i >= 0; i--)
- {
- tmp -= buffer[i];
- if (tmp == 0) print(buffer, i, level);
- }
-
- vector<int> lbuffer(buffer);
- vector<int> rbuffer(buffer);
-
- findSum(head->lchild, sum, lbuffer, level + 1);
- findSum(head->rchild, sum, rbuffer, level + 1);
- }
-
- int main(int argc, char* argv[])
- {
- const int SIZE = 10;//測試的數據量
- int data[SIZE];//保存數據
- int i, j;
- struct node *head = NULL;
-
- for (i = 0; i < SIZE; i++)
- {
- data[i] = i + 1;
- }
-
- head = ConvertArrayToTree(data, 0, SIZE - 1);
-
- struct node *one = (struct node *)malloc(sizeof(struct node));
- struct node *two = (struct node *)malloc(sizeof(struct node));
- one->data = 11;
- one->lchild = NULL;
- one->rchild = NULL;
-
- two->data = 4;
- two->lchild = NULL;
- two->rchild = NULL;
-
- InsertNodeAtLeft(head, one);
- InsertNodeAtRight(head, two);
- //遍歷數據
- // Traverse(head);
- // printf("\n");
- vector<int> v;
- findSum(head, 14, v, 0);
- return 0;
- }
該示例中所使用的二叉樹如下所示:
運行結果如下: