搜索二叉树转化为双向链表

来源:互联网 发布:哪里能买到淘宝账号 编辑:程序博客网 时间:2024/04/29 07:33

1.    将搜索二叉树转化为双向链表

       分析:二叉树问题一定要想递归,比如我们整体思考左子树转化为双向链表,右子树转化为双向链表,我们只用将根节点和左子树链表和右子树链表连接起来即可。

好了,问题在于,连接的时候左子树形成链表的最后一个节点à根节点à右子树形成链表第一个节点。这样连起来就可以了。

       左子树形成链表和右子树形成链表是大问题的两个子问题,就是用递归。而我们需要用到左子树返回值的最后一个节点和右子树返回值的第一个节点。两个子问题统一返回第一个节点和最后一个节点。我们在实现的时候采用了将最后一个节点指向第一个节点的结构,这样就满足条件了。

       看代码:

第一种方法:利用中序遍历得到序列,然后按顺序连接即可。

#include<iostream>#include<queue>using namespace std;struct Node { int value; Node * left; Node * right;     Node(int data)  {value = data;left=NULL;right=NULL; }}; void inOrderToQueue(Node * head, queue<Node *>& queue) {if (head == NULL) {return;}inOrderToQueue(head->left, queue);queue.push(head);inOrderToQueue(head->right, queue);}Node * convert1(Node * head) {queue<Node *> queue;inOrderToQueue(head, queue);if (queue.empty()) {return head;}head = queue.front();queue.pop();Node * pre = head;pre->left = NULL;Node * cur = NULL;while (!queue.empty()) {cur = queue.front();queue.pop();pre->right = cur;cur->left = pre;pre = cur;}pre->right = NULL;return head;}


第二种方法:就是我一开始讲的利用递归。

//我们返回链表的最后一个节点,但同时该节点right指向 Node * process(Node * head) {if (head == NULL) {return NULL;}Node *leftE = process(head->left); // left endNode *rightE = process(head->right); // right endNode *leftS = leftE != NULL ? leftE->right : NULL; // left startNode *rightS = rightE != NULL ? rightE->right : NULL; // right startif (leftE != NULL && rightE != NULL) {leftE->right = head;head->left = leftE;head->right = rightS;rightS->left = head;rightE->right = leftS;   //此步是最后一个节点指向第一个头结点return rightE;} else if (leftE != NULL) {leftE->right = head;head->left = leftE;head->right = leftS;return head;} else if (rightE != NULL) {head->right = rightS;rightS->left = head;rightE->right = head;return rightE;} else {head->right = head;return head;}} Node * convert2(Node * head) {if (head == NULL) {return NULL;}Node* last = process(head);head = last->right;last->right = NULL;return head;}

测试代码:

void inOrderPrint(Node * head) {if (head == NULL) {return;}inOrderPrint(head->left);printf("%d ",head->value);inOrderPrint(head->right);}  void printBSTInOrder(Node * head) {//printf("BST in-order: ");if (head != NULL) {inOrderPrint(head);}printf("\n");} void printDoubleLinkedList(Node * head) {printf("Double Linked List: ");Node * end =NULL;while (head != NULL) {printf("%d ",head->value);end = head;head = head->right;}printf("| ");while (end != NULL) {printf("%d ",end->value);end = end->left;}printf("\n");} int main(){    Node * head = new Node(5);head->left = new Node(2);head->right = new Node(9);head->left->left = new Node(1);head->left->right = new Node(3);head->left->right->right = new Node(4);head->right->left = new Node(7);head->right->right = new Node(10);head->right->left->left = new Node(6);head->right->left->right = new Node(8);printBSTInOrder(head);head = convert1(head);printDoubleLinkedList(head);head = new Node(5);head->left = new Node(2);head->right = new Node(9);head->left->left = new Node(1);head->left->right = new Node(3);head->left->right->right = new Node(4);head->right->left = new Node(7);head->right->right = new Node(10);head->left->left = new Node(1);head->right->left->left = new Node(6);head->right->left->right = new Node(8);printBSTInOrder(head);head = convert2(head);printDoubleLinkedList(head);return 0;}

       第一种用到queue来容纳中序序列,进而进行双链表的链接。第二种就是递归调用,要分清子问题,确保子问题和父问题的返回值一致。

       第一种其实思想是利用容器来遍历二叉树,第二种方法明显的二叉树。用C++写的,思想来自牛客网左程云大神。



0 0
原创粉丝点击