#include "pch.h"
#include
#include"pch.h"
#include
#include"stdio.h"
#include
#include
#include
#include
using namespace std;
#define ElemType int
#define VOID -999999
#define MAXSIZE 50
typedef struct ThreadNode {
ElemType data;
char cData;
struct ThreadNode *lchild =NULL, *rchild=NULL;
int ltag = 1, rtag = 1;
}ThreadNode,*ThreadTree;
typedef struct Node {
ThreadNode *data;
Node *next, *prior;
};
typedef struct que {
Node *front,*rear;
}queue, *Queue;
bool IsEmpty(Queue &q) {
if (q->front->next==NULL) return true;
return false;
}
void InitQueue(Queue &q) {
Node* node = new Node;
node->data = NULL;
node->next = NULL;
q->front = node;
q->rear = node;
}
void EnQueue(Queue &q, ThreadNode *&tnode) {
Node *node = new Node;
node->data = tnode;
node->next = NULL;
node->prior = q->rear;
q->rear->next = node;
q->rear = node;
}
ThreadNode* DeQueue(Queue &q, ThreadNode *&tnode) {
Node* node = q->front->next;
if (node == NULL) {
return NULL;
}
tnode = node->data;
if (node->next == NULL) {
q->rear = q->front;
}
else {
node->next->prior = q->front;
}
q->front->next = node->next;
return tnode;
}
int GetQueueLength(Queue &q) {
int length = 0;
Node *p = q->front->next;
if (p->next == NULL) return 0;
while (p->next != q->rear) {
length++;
p = p->next;
}
return length;
}
typedef struct stack {
ThreadTree datas[MAXSIZE] = {};
int top = -1;
}stk,*Stack;
bool Push(Stack &s,ThreadNode *&e) {
if (s->top == MAXSIZE) return false;
s->datas[++s->top] = e;
return true;
}
bool Pop(Stack &s, ThreadNode *&e) {
if (s->top == -1) {
e = NULL; return false;
}
e = s->datas[s->top--];
return true;
}
void InitStack(Stack &s) {
for (int i = 0; i < MAXSIZE; i++) {
s->datas[i] = NULL;
}
s->top = -1;
}
bool IsEmpty(Stack &s) {
if (s->top == -1) return true;
return false;
}
void CreateNode(ThreadNode *&Node, ElemType e,ThreadNode *&parent,bool left) {
if (Node != NULL) {
Node->data = e;
return;
}
Node = new ThreadNode;
Node->data = e;
if (parent != NULL) {
if (left) {
parent->lchild = Node;
parent->ltag = 0;
}
else {
parent->rchild = Node;
parent->rtag = 0;
}
}
}
void InsertNode(ThreadTree &tree, const char Order[], ElemType e) {
int i = 0;
ThreadNode* p = tree;
ThreadNode* pre = tree;
if (p == NULL) return;
while (Order[i] != '\0') {
if (Order[i] == 'L') {
if (p->lchild != NULL) {
pre = p;
p = p->lchild;
}
else {
CreateNode(p->lchild, e, p, true);
return;
}
}
else {
if (p->rchild != NULL) {
pre = p;
p = p->rchild;
}
else {
CreateNode(p->rchild, e, p, false);
return;
}
}
i++;
}
CreateNode(p, e, pre, Order[i-1]=='L'?true:false);
return;
}
void InOrderThread(ThreadNode *&node,ThreadNode *&pre) {
if (node->ltag == 0)InOrderThread(node->lchild,pre);
if (!pre) {
pre = node;
}
else {
if (pre->rtag == 1) pre->rchild = node;
if (node->ltag == 1) node->lchild = pre;
pre = node;
}
if (node->rtag == 0)InOrderThread(node->rchild,pre);
}
ThreadNode* FindPostPreInOrder(ThreadNode *&node, ThreadNode*&ret) {
ThreadNode *p = node,*q;
if (p->rtag == 0) {
q = p->rchild;
}
else if (p->ltag == 0) {
q = p->lchild;
}
else if (!p->lchild) {
q = NULL;
}
else {
while (p->ltag == 1 && p->lchild)
p = p->lchild;
if (p->ltag == 0) {
q = p->lchild;
}
else {
q = NULL;
}
}
ret = q;
return q;
}
void PrintTreePreOrderInChar(ThreadTree &tree) {
if (tree == NULL) return;
cout << tree->cData << " ";
if (tree->ltag == 0)PrintTreePreOrderInChar(tree->lchild);
if (tree->rtag == 0)PrintTreePreOrderInChar(tree->rchild);
}
void PrintTreeInOrderInChar(ThreadTree &tree) {
if (tree == NULL) return;
if (tree->ltag == 0)PrintTreeInOrderInChar(tree->lchild);
cout << tree->cData << " ";
if (tree->rtag == 0)PrintTreeInOrderInChar(tree->rchild);
}
void PrintTreePostOrderInChar(ThreadTree &tree) {
if (tree->ltag == 0)PrintTreePostOrderInChar(tree->lchild);
if (tree->rtag == 0)PrintTreePostOrderInChar(tree->rchild);
cout << tree->cData << " ";
}
void PrintTreePreOrder(ThreadTree &tree) {
if (tree == NULL) return;
cout << tree->data << " ";
if (tree->ltag == 0)PrintTreePreOrder(tree->lchild);
if (tree->rtag == 0)PrintTreePreOrder(tree->rchild);
}
void PrintTreeInOrder(ThreadTree &tree) {
if (tree == NULL) return;
if (tree->ltag == 0)PrintTreeInOrder(tree->lchild);
cout << tree->data << " ";
if (tree->rtag == 0)PrintTreeInOrder(tree->rchild);
}
void PrintTreePostOrder(ThreadTree &tree) {
if (tree->ltag == 0)PrintTreePostOrder(tree->lchild);
if (tree->rtag == 0)PrintTreePostOrder(tree->rchild);
cout << tree->data << " ";
}
void PrintTreePreOderStack(ThreadTree &tree, Stack &S) {
ThreadNode *p = tree;
InitStack(S);
while (p != NULL || !IsEmpty(S)) {
while (p != NULL) {
cout << p->data << " ";
Push(S, p);
p = p->lchild;
}
if(!IsEmpty(S)){
Pop(S, p);
p = p->rchild;
}
}
}
void PrintTreeInOderStack(ThreadTree &tree,Stack &S) {
ThreadNode *p = tree;
InitStack(S);
while (p!=NULL|| !IsEmpty(S)) {
if (p!=NULL) {
Push(S, p);
p = p->lchild;
}
else {
Pop(S, p);
cout << p->data << " ";
p = p->rchild;
}
}
}
void PrintTreePostOderStack(ThreadTree &tree, Stack &S) {
ThreadNode *p = tree,*r =NULL;
InitStack(S);
while (p != NULL || !IsEmpty(S)) {
if (p != NULL) {
Push(S, p);
p = p->lchild;
}
else {
Pop(S, p);
if (p->rtag == 1 || p->rchild==r) {
cout << p->data << " ";
r = p;
p = NULL;
}
else {
Push(S, p);
p = p->rchild;
}
}
}
}
void PrintTreeLevelOrder(ThreadTree &tree) {
Queue q = new que;
InitQueue(q);
ThreadNode *p = tree;
EnQueue(q,p);
while (!IsEmpty(q)) {
DeQueue(q, p);
cout << p->data << " ";
if (p->lchild != NULL) {
EnQueue(q, p->lchild);
}
if (p->rchild != NULL) {
EnQueue(q, p->rchild);
}
}
}
void PrintTreeInvertLevelOrder(ThreadTree &tree) {
Stack s = new stk;
Queue q = new que;
InitStack(s);
InitQueue(q);
ThreadNode *p = tree;
EnQueue(q, p);
while (!IsEmpty(q)) {
DeQueue(q, p);
Push(s, p);
if (p->lchild != NULL) {
EnQueue(q, p->lchild);
}
if (p->rchild != NULL) {
EnQueue(q, p->rchild);
}
}
while (!IsEmpty(s)) {
Pop(s, p);
cout << p->data << " ";
}
}
int GetBinaryTreeHeight(ThreadTree &tree) {
int lh , rh , height;
if (!tree) {
height = 0;
}else{
lh = GetBinaryTreeHeight(tree->lchild);
rh = GetBinaryTreeHeight(tree->rchild);
height = 1 + (lh > rh?lh:rh) ;
}
return height ;
}
int GetBinaryTreeHeightRecursive(ThreadTree &tree) {
Queue qs[2];
int height = 0;
for (int i = 0; i < 2; i++) {
qs[i] = new que;
}
InitQueue(qs[0]);
InitQueue(qs[1]);
ThreadNode *p = tree;
EnQueue(qs[0], p);
while (!IsEmpty(qs[0])|| !IsEmpty(qs[1])) {
while (!IsEmpty(qs[height % 2])) {
DeQueue(qs[height % 2], p);
if (p->lchild != NULL)EnQueue(qs[height%2 == 0 ? 1 : 0], p->lchild);
if (p->rchild != NULL)EnQueue(qs[height%2 == 0 ? 1 : 0], p->rchild);
}
height++;
}
return height;
}
ThreadNode* PreInCreate(const int preOrder[], const int inOrder[], int left1, int right1, int left2, int right2) {
ThreadNode *p = new ThreadNode;
p->data = preOrder[left1];
int i;
for (i = left2; inOrder[i] != p->data; i++);
int llen = i - left2;
int rlen = right2 - i;
if (llen) {
p->lchild = PreInCreate(preOrder, inOrder, left1 + 1, left1 + llen, left2, i - 1);
p->ltag = 0;
}
else
p->lchild = NULL;
if (rlen) {
p->rchild = PreInCreate(preOrder, inOrder, right1 - rlen + 1, right1, i + 1, right2);
p->rtag = 0;
}
else
p->rchild = NULL;
return p;
}
ThreadNode* PreInCreateInChar(const char preOrder[], const char inOrder[], int left1, int right1, int left2, int right2) {
ThreadNode *p = new ThreadNode;
p->cData = preOrder[left1];
int i;
for (i = left2; inOrder[i] != p->cData; i++);
int llen = i - left2;
int rlen = right2 - i;
if (llen) {
p->lchild = PreInCreateInChar(preOrder, inOrder, left1 + 1, left1 + llen, left2, i - 1);
p->ltag = 0;
}
else
p->lchild = NULL;
if (rlen) {
p->rchild = PreInCreateInChar(preOrder, inOrder, right1 - rlen + 1, right1, i + 1, right2);
p->rtag = 0;
}
else
p->rchild = NULL;
return p;
}
bool IsComplete(ThreadNode* node) {
if (!node)
return true;
Queue qs[2];
for (int i = 0; i < 2; i++) {
qs[i] = new que;
InitQueue(qs[i]);
}
int count = 0;
ThreadNode *p = node;
EnQueue(qs[0], p);
while (!IsEmpty(qs[0])||!IsEmpty(qs[1])) {
bool b = false;
int k = 0;
while (!IsEmpty(qs[count % 2])) {
DeQueue(qs[count % 2], p);
if (p->ltag==0) {
EnQueue(qs[count % 2 == 0], p->lchild);
}
if (p->rtag==0) {
EnQueue(qs[count % 2 == 0], p->rchild);
}
k++;
}
if (k != pow(2, count)) {
return false;
}
count++;
}
return true;
}
int DSonNodes(ThreadNode* node) {
if (node == NULL)
return 0;
else if (node->ltag == 0 && node->rtag == 0)
return 1 + DSonNodes(node->lchild) + DSonNodes(node->rchild);
else
return DSonNodes(node->lchild) + DSonNodes(node->rchild);
}
void Swap(ThreadNode *&tree) {
if (tree) {
Swap(tree->lchild);
Swap(tree->rchild);
ThreadNode *node = tree->rchild;
tree->rchild = tree->lchild;
tree->lchild = node;
int tag = tree->ltag;
tree->ltag = tree->rtag;
tree->rtag = tag;
}
}
int PreOrderFindNode(ThreadNode *&tree,int &k,int &num) {
if (tree == NULL) return 0;
if (--k == 0) { num = tree->data; return num; }
int k1 = VOID,k2 = VOID;
if (tree->ltag == 0)k1 = PreOrderFindNode(tree->lchild, k, num);
if (tree->rtag == 0)k2 = PreOrderFindNode(tree->rchild, k, num);
return k1 > k2 ? k1 : k2;
}
void DeleteSons(ThreadNode *&tree) {
if (tree->ltag == 0)DeleteSons(tree->lchild);
if (tree->rtag == 0)DeleteSons(tree->rchild);
free(tree);
}
void DeleteNode(ThreadNode *&tree,ThreadNode *&parent,bool left,ElemType e) {
if (tree->data == e) {
DeleteSons(tree);
if (tree != parent) {
if (left) {
parent->lchild = NULL;
parent->ltag = 1;
}
else {
parent->rchild = NULL;
parent->rtag = 1;
}
}
return;
}
parent = tree;
if (tree->ltag == 0)DeleteNode(tree->lchild, parent,true,e);
if (tree->rtag == 0)DeleteNode(tree->rchild, parent,false,e);
}
void PrintNodeParent(ThreadNode *&tree,ElemType e) {
ThreadNode* p = tree,*r = NULL;
Stack s = new stk;
bool finded = false;
InitStack(s);
while (p != NULL||!IsEmpty(s)) {
if (p != NULL) {
if (p->data == e) {
finded = true;
}
if (finded) {
if (!Pop(s, p)) {
p = NULL;
free(s);
return;
}
cout << p->data << " ";
}
else {
Push(s, p);
p = p->lchild;
}
}
else {
Pop(s, p);
if (p->rtag != 0 || p->rchild == r) {
r = p;
p = NULL;
}
else {
Push(s, p);
p = p->rchild;
}
}
}
free(s);
}
ThreadNode* FindNode(ThreadNode *&tree, ElemType e) {
if (tree == NULL) return NULL;
if (tree->data == e) return tree;
ThreadNode *p1 = NULL,*p2 = NULL;
if (tree->ltag == 0) p1 = (FindNode(tree->lchild, e));
if (tree->rtag == 0) p2 = (FindNode(tree->rchild, e));
return p1==NULL?p2:p1;
}
ThreadNode* Ancestor(ThreadNode *&root, ThreadNode *&p, ThreadNode *&q, ThreadNode *&r) {
ThreadNode *pp = root,*rp = NULL,*qp = NULL;
Stack s = new stk;
Queue pq = new que;
Queue qq = new que;
Queue rq = new que;
Stack rs = new stk;
InitStack(s);
InitQueue(pq);
InitQueue(qq);
InitQueue(rq);
InitStack(rs);
while (pp || !IsEmpty(s)) {
if (pp) {
Push(s, pp);
if (pp == p) {
while (Pop(s, qp)) {
EnQueue(pq, qp);
Push(rs, qp);
}
while (Pop(rs, qp)) {
Push(s, qp);
}
}
if (pp == q) {
while (Pop(s, qp)) {
EnQueue(qq, qp);
Push(rs, qp);
}
while (Pop(rs, qp)) {
Push(s, qp);
}
}
pp = pp->lchild;
}
else {
Pop(s, pp);
if (pp->rtag == 1 || pp->rchild == rp) {
rp = pp;
pp = NULL;
}
else {
Push(s, pp);
pp = pp->rchild;
}
}
}
while (DeQueue(pq, pp)!=NULL) {
while (DeQueue(qq, qp)!=NULL) {
EnQueue(rq, qp);
if (pp == qp) {
r = pp;
return pp;
}
}
while (DeQueue(rq, qp)) {
EnQueue(qq, qp);
}
}
r = NULL;
return NULL;
}
int GetWidth(ThreadNode *&root) {
Queue q[2];
for (int i = 0; i < 2; i++) {
q[i] = new que;
InitQueue(q[i]);
}
ThreadNode *p = root;
if (p == NULL) return 0;
EnQueue(q[0], p);
int height = 0;
int maxWidth = 0;
while (!IsEmpty(q[0]) || !IsEmpty(q[1])) {
int width = 0;
while (!IsEmpty(q[height % 2])) {
DeQueue(q[height % 2], p);
if (p->ltag == 0) EnQueue(q[height % 2 == 0], p->lchild);
if (p->rtag == 0) EnQueue(q[height % 2 == 0], p->rchild);
width++;
}
if (width > maxWidth)
maxWidth = width;
height++;
}
return maxWidth;
}
void PreToPost(int pre[], int left1, int right1, int post[], int left2, int right2) {
post[right2] = pre[left1];
int len = right1 - left1;
if (len > 1) {
PreToPost(pre, left1 + 1,left1+ len / 2, post, left2, left2 + len / 2 - 1);
PreToPost(pre, right1 - len / 2 + 1, right1, post, right2 - len / 2, right2 - 1);
}
else {
post[left2] = pre[left1];
post[right2] = pre[right1];
}
}
void LeafLinkList(ThreadNode *&root,ThreadNode *&lastLeaf,ThreadNode *&head) {
if (root->ltag == 1 && root->rtag == 1) {
if (lastLeaf == NULL) {
lastLeaf = root;
head = root;
}
else {
lastLeaf->rchild = root;
lastLeaf = root;
}
return;
}
if (root->ltag == 0)LeafLinkList(root->lchild, lastLeaf, head);
if (root->rtag == 0)LeafLinkList(root->rchild, lastLeaf, head);
}
void PrintLeafLinkList(ThreadNode *&head) {
ThreadNode *p = head;
while (p) {
cout << p->data << " ";
p = p->rchild;
}
}
bool IsSimilar(ThreadNode *&tree1, ThreadNode *&tree2) {
if (!tree1) {
if (tree2) {
return false;
}
else {
return true;
}
}
bool b1, b2;
b1 = IsSimilar(tree1->lchild, tree2->lchild);
b2 = IsSimilar(tree1->rchild, tree2->rchild);
return b1 == false ? b1 : b2;
}
int WPL(ThreadNode *&root, int deep) {
static int wpl = 0;
if (root->rtag == 1 && root->ltag == 1) {
wpl += deep * root->data;
}
if (root->ltag == 0)
WPL(root->lchild, deep + 1);
if (root->rtag == 0)
WPL(root->rchild, deep + 1);
return wpl;
}
void BtreeToExp(ThreadNode *&node,int deep) {
if (!node) return;
if (node->ltag != 0 && node->rtag !=0) {
cout << node->cData;
}
else {
if (deep > 1)cout << "(";
BtreeToExp(node->lchild,deep+1);
cout << node->cData;
BtreeToExp(node->rchild,deep+1);
if (deep > 1)cout << ")";
}
}
int main()
{
cout << endl << "练习题4-3-3" << endl;
ThreadTree tree = NULL;
ThreadTree treeTemp = NULL;
Stack s = new stk;
CreateNode(tree, 5, treeTemp, true);
InsertNode(tree, "L", 2);
InsertNode(tree, "R", 3);
InsertNode(tree, "LL", 4);
InsertNode(tree, "LR", 5);
InsertNode(tree, "RRR", 8);
InsertNode(tree, "RRL", 4);
InsertNode(tree, "RRR", 8);
cout << endl << "前序遍历结果:";
PrintTreePreOrder(tree);
cout << endl << "中序遍历结果:";
PrintTreeInOrder(tree);
cout << endl << "后序遍历结果:";
PrintTreePostOrder(tree);
cout << endl << "非递归前序遍历结果:";
PrintTreePreOderStack(tree, s);
cout << endl << "非递归中序遍历结果:";
PrintTreeInOderStack(tree,s);
cout << endl << "非递归后序遍历结果:";
PrintTreePostOderStack(tree, s);
cout << endl << "层次遍历结果:";
PrintTreeLevelOrder(tree);
cout << endl << "逆序层次遍历结果:";
PrintTreeInvertLevelOrder(tree);
cout << endl << "树的高度为:";
cout << GetBinaryTreeHeight(tree);
cout << endl << "树的高度为(非递归算法):";
cout << GetBinaryTreeHeightRecursive(tree);
int a[20] = { 5,2,4,8,9,6,3,1,12,7,10,11 };
int b[20] = { 8,4,9,2,6,5,1,12,3,10,7,11 };
ThreadNode * tree2 = PreInCreate(a, b, 0, 11, 0, 11);
cout << endl << "前序遍历结果:";
PrintTreePreOrder(tree2);
cout << endl << "中序遍历结果:";
PrintTreeInOrder(tree2);
cout << endl;
cout << (IsComplete(tree2)?"是":"不是") << "完全二叉树";
cout << endl;
cout << "度为2的节点个数为:" << DSonNodes(tree2) << endl;
Swap(tree2);
cout << endl << "前序遍历结果:";
PrintTreePreOrder(tree2);
cout << endl << "中序遍历结果:";
PrintTreeInOrder(tree2);
int num = 0,k = 3;
int k1 = k;
int num1 = PreOrderFindNode(tree2, k, num);
cout << endl;
cout << "树先序序列的第"<< k1 <<"个元素为:" << num <<endl;
cout << endl << "前序遍历结果:";
PrintTreePreOrder(tree2);
cout << endl << "中序遍历结果:";
PrintTreeInOrder(tree2);
cout << endl << "tree的元素7的所有祖先节点:";
PrintNodeParent(tree2, 7);
ThreadNode* p1 = FindNode(tree2, 7);
ThreadNode* p2 = FindNode(tree2, 3);
ThreadNode* p3 = NULL;
Ancestor(tree2, p1, p2, p3);
cout << endl << "7和3最近公共祖先节点为:";
cout << p3->data;
cout << endl << "tree2的宽度为:";
cout << GetWidth(tree2);
cout << endl;
int pre [20] = { 5,2,4,8,9,6,13,14,3,1,15,12,7,10,11 };
int post[20] = {};
PreToPost(pre, 0, 14, post, 0, 14);
cout << endl << "后序序列为:";
for (int i = 0; i < 15; i++) {
cout << post[i] << " ";
}
treeTemp = NULL;
ThreadNode *leftLinkHead;
cout << endl << "tree2前序遍历结果:";
PrintTreePreOrder(tree2);
cout << endl << "tree2中序遍历结果:";
PrintTreeInOrder(tree2);
cout << endl << "tree2的叶子节点链表为:";
LeafLinkList(tree2, treeTemp, leftLinkHead);
PrintLeafLinkList(leftLinkHead);
int c[20] = { 5,2,4,8,9,6,13,14,3,1,15,12,7,10,11 };
int d[20] = { 8,4,9,2,13,6,14,5,15,1,12,3,10,7,11 };
int e[20] = { 5,2,4,8,55,6,13,14,3,1,15,12,7,10,11 };
int f[20] = { 8,4,55,2,13,6,14,5,15,1,12,3,10,7,11 };
ThreadNode * tree4 = PreInCreate(c, d, 0, 14, 0, 14);
ThreadNode * tree5 = PreInCreate(e, f, 0, 14, 0, 14);
cout << endl << "tree4与tree5" << (IsSimilar(tree5,tree4)?"相似":"不相似");
treeTemp = NULL;
ThreadNode * tree3 = PreInCreate(a, b, 0, 11, 0, 11);
InOrderThread(tree4,treeTemp);
ThreadNode* p4 = FindNode(tree4, 15);
treeTemp = NULL;
FindPostPreInOrder(p4, treeTemp);
if (treeTemp != NULL) {
cout << endl << "15的后序序列中的前驱为:" << treeTemp->data;
}
else {
cout << endl << "15的后序序列中的前驱为:无" ;
}
cout << endl << "tree4的WPL值为:" << WPL(tree4, 0);
char charTempPre[10] = { '*','+','a','b','*','c','-','d' };
char charTempIn[10] = { 'a','+','b','*','c','*','-','d' };
ThreadNode * tree6 = PreInCreateInChar(charTempPre, charTempIn, 0, 7, 0, 7);
cout << endl << "tree6前序遍历结果:";
PrintTreePreOrderInChar(tree6);
cout << endl << "tree6中序遍历结果:";
PrintTreeInOrderInChar(tree6);
cout << endl;
BtreeToExp(tree6,1);
cout << endl;
}