#ifndef TREE_H
#define TREE_H
#include"Head.h"
#include "List.h"
#define MAX_TREE_SIZE 100
//
//数据结构
//
//线索树的结点类型
typedef enum { _Link, _Thread }PointTag;
//顺序存储结构
typedef ElemType_Char SqBiTree[MAX_TREE_SIZE];
//二叉树
//二叉链表
typedef struct BiNode {
ElemType_Char data;
int DescNum;
struct BiNode* lchild, * rchild;
}BiNode, * BiTree;
//三叉链表
typedef struct TriNode {
ElemType_Char data;
struct TriNode* lchild, * rchild, * parent;
}TriNode, * TriTree;
//线索链表
typedef struct BiThrNode {
ElemType_Char data;
struct BiThrNode* lchild, * rchild;
PointTag LTag, RTag;
}BiThrNode, * BiThree;
//线索三叉链表
typedef struct TriTNode {
ElemType_Char data;
struct TriTNode* lchild, * rchild, * parent;
PointTag LTag, RTag;
}TriTNode, * TriThree;
//双亲表示法
typedef struct PTNode {
ElemType_Char data;
int parent;
}PTNode;
typedef struct {
PTNode nodes[MAX_TREE_SIZE];
int r, n;
}PTree;
//孩子表示法
typedef struct CTNode {
int child;
struct CTNode* next;
}CTNode, * ChildPtr;
typedef struct {
ElemType_Char data;
ChildPtr firstchild;
}CTBox;
typedef struct {
CTBox nodes[MAX_TREE_SIZE];
int n, r;//r根节点的位置
}CTree;
//孩子兄弟表示法
typedef struct CSNode {
ElemType_Char data;
struct CSNode* firstchild, * nextsibling;
}CSNode, * CSTree;
//赫夫曼树
typedef struct {
int weight;
int parent, lchild, rchild;
}HTNode, * HuffmanTree;
typedef char* HuffmanCode;//赫夫曼编码表
//三叉树
typedef struct TrieNode {
int data;
struct TrieNode* left, * mid, * right;
}TrieNode, * Trie;
//N皇后问题
typedef struct NQuNode {
int i, j;
}NQuNode;
typedef struct {
NQuNode* base, * top;//栈底,栈顶指针
int stacksize;//已分配的存储空间
}NQueens;
//创建二叉树
Status CreateBiTree(BiTree* T, FILE* fp);
//创建线索二叉树
Status CreatBiThrBiTree(BiThree* T, FILE* fp);
//创建线索三叉树
Status CreateTriTree(TriThree* T, FILE* fp);
//根据先序中序序列创建二叉树
Status CreateBiTree_Pre_In(BiTree* T, char* pre, char* in, int st_pre, int ed_pre, int st_in, int ed_in);
//先序中序后序遍历二叉树
void Visit(BiTree T);
Status PreOrderTraverse(BiTree T, void(*visit)(BiTree));//先序遍历
Status InOrderTraverse(BiTree T, void(*visit)(BiTree));//中序遍历
Status PostOrderTraverse(BiTree T, void(*visit)(BiTree));//后序遍历
//线索二叉树线索化
//先序线索树
void PreTreading(BiThree* p, BiThree* pre);
Status PreOrderTreading(BiThree* Thrt, FILE* fp);
//中序线索树
void InTreading(BiThree* p, BiThree* pre);
Status InOrderTreading(BiThree* Thrt, FILE* fp);
//后序线索三叉树
void PostTreading(TriThree* p, TriThree* pre);
void PostOrderTreading(TriThree* Thrt, FILE* fp);
//中序输出线索二叉树
void OutPutThread_In(BiThree T);
//后序输出线索三叉树
void OutPutThread_Post(TriThree T);
//求树的深度
int Depth_BiTree(BiTree T);
//输出赫夫曼树和赫夫曼编码表
void OutPutHuffmanTreeAndCode(HuffmanTree T, HuffmanCode C, int m, int n);
//销毁赫夫曼树和赫夫曼编码表
Status DestoryHuffmanTreeAndCode(HuffmanTree* T, HuffmanCode* C, int n);
//赫夫曼编码
//筛选最小的两个结点
Status Select(HuffmanTree* HT, int n, int* s1, int* s2);
Status HuffmanCoding(HuffmanTree* HT, HuffmanCode* HC, int* w, int n);
//n皇后问题
Status InitNQueens(NQueens* N);
Status PushNQuees(NQueens* N, NQuNode e);
Status PopNQuees(NQueens* N, NQuNode* e);
void OutPutNQueens(NQueens N, int n);
double slope(double i1, double j1, double i2, double j2);
Status JudgeNQueens(NQueens N);
void N_Queens(NQueens* N, int n, int i);
void NQueenQuestion();
//求幂集
void GetPowerSet(int i, SqList A, SqList* B);//
void PowerSet();
#endif // !TREE_H
#ifndef TREE_C
#define TREE_C
#include"Tree.h"
//空树/空结点用#或^表示
//创建二叉树
Status CreateBiTree(BiTree* T, FILE* fp) {
char tmp;
if (!Scanf(fp, "%c", &tmp))
return OK;
if (tmp == '#' || tmp == '^')
return OK;
*T = MALLOC(1, BiNode);
(*T)->data = tmp;
(*T)->lchild = NULL;
(*T)->rchild = NULL;
CreateBiTree(&(*T)->lchild, fp);
CreateBiTree(&(*T)->rchild, fp);
return OK;
}
//创建线索二叉树
Status CreatBiThrBiTree(BiThree* T, FILE* fp) {
char tmp;
if (!Scanf(fp, "%c", &tmp))
return OK;
if (tmp == '#' || tmp == '^')
return OK;
(*T) = (BiThree)malloc(sizeof(BiThrNode));
(*T)->data = tmp;
(*T)->LTag = _Link;
(*T)->RTag = _Link;
CreatBiThrBiTree(&(*T)->lchild, fp);
CreatBiThrBiTree(&(*T)->rchild, fp);
return OK;
}
//创建线索三叉树
Status CreateTriTree(TriThree* T, FILE* fp) {
char tmp;
if (!Scanf(fp, "%c", &tmp))
return OK;
if (tmp == '#' || tmp == '^')
return OK;
(*T) = (TriThree)malloc(sizeof(TriTNode));
(*T)->data = tmp;
(*T)->LTag = _Link;
(*T)->RTag = _Link;
CreateTriTree(&(*T)->lchild, fp);
CreateTriTree(&(*T)->rchild, fp);
if ((*T)->lchild)
(*T)->lchild->parent = *T;
if ((*T)->rchild)
(*T)->rchild->parent = *T;
return OK;
}
//根据先序中序序列创建二叉树
Status CreateBiTree_Pre_In(BiTree* T, char* pre, char* in, int st_pre, int ed_pre, int st_in, int ed_in) {
if (st_pre > ed_pre || st_in > ed_in) {
*T = NULL;
return OK;
}
int i;
for (i = 0; pre[st_pre] != in[st_in + i]; i++);
*T = MALLOC(1, BiNode);
(*T)->data = pre[st_pre];
CreateBiTree_Pre_In(&(*T)->lchild, pre, in, st_pre + 1, st_pre + i, st_in, st_in + i - 1);
CreateBiTree_Pre_In(&(*T)->rchild, pre, in, st_pre + i + 1, ed_pre, st_in + i + 1, ed_in);
return OK;
}
//先序中序后序遍历二叉树
void Visit(BiTree T) {
printf("%c", T->data);
}
//先序遍历
Status PreOrderTraverse(BiTree T, void(*visit)(BiTree)) {
if (!T)
return ERROR;
visit(T);
PreOrderTraverse(T->lchild, visit);
PreOrderTraverse(T->rchild, visit);
return OK;
}
//中序遍历
Status InOrderTraverse(BiTree T, void(*visit)(BiTree)) {
if (!T)
return ERROR;
InOrderTraverse(T->lchild, visit);
visit(T);
InOrderTraverse(T->rchild, visit);
return OK;
}
//后序遍历
Status PostOrderTraverse(BiTree T, void(*visit)(BiTree)) {
if (!T)
return ERROR;
PostOrderTraverse(T->lchild, visit);
PostOrderTraverse(T->rchild, visit);
visit(T);
return OK;
}
//线索二叉树线索化
//先序线索树
void PreTreading(BiThree* p, BiThree* pre) {
if (*p) {
if (!(*pre)->rchild) {
(*pre)->RTag = _Thread;
(*pre)->rchild = *p;
}
*pre = *p;
PreTreading(&(*p)->lchild, pre);
if (!(*p)->lchild) {
(*p)->LTag = _Thread;
(*p)->lchild = *pre;
}
if ((*p)->RTag == _Link)
PreTreading(&(*p)->rchild, pre);
}
}
Status PreOrderTreading(BiThree* Thrt, FILE* fp) {
BiThree T;
CreatBiThrBiTree(&T, fp);
*Thrt = (BiThree)malloc(sizeof(BiThrNode));
(*Thrt)->LTag = _Thread;
(*Thrt)->lchild = (*Thrt);
BiThree pre;
pre = *Thrt;
if (T) {
(*Thrt)->RTag = _Link;
(*Thrt)->rchild = T;
PreTreading(&T, &pre);
pre->RTag = _Thread;
pre->rchild = *Thrt;
}
else {
(*Thrt)->RTag = _Thread;
(*Thrt)->rchild = *Thrt;
}
return OK;
}
//中序线索树
void InTreading(BiThree* p, BiThree* pre) {
if (*p) {
InTreading(&(*p)->lchild, pre);
if (!(*p)->lchild) {
(*p)->LTag = _Thread;
(*p)->lchild = *pre;
}
if (!(*pre)->rchild) {
(*pre)->RTag = _Thread;
(*pre)->rchild = *p;
}
*pre = *p;
InTreading(&(*p)->rchild, pre);
}
}
Status InOrderTreading(BiThree* Thrt, FILE* fp) {
BiThree T;
CreatBiThrBiTree(&T, fp);
(*Thrt) = (BiThree)malloc(sizeof(BiThrNode));
(*Thrt)->LTag = _Link;
(*Thrt)->RTag = _Thread;
(*Thrt)->rchild = *Thrt;
BiThree pre;
if (!T)
(*Thrt)->lchild = (*Thrt);
else {
(*Thrt)->lchild = T;
pre = *Thrt;
InTreading(&T, &pre);
pre->rchild = *Thrt;
pre->RTag = _Thread;
(*Thrt)->rchild = pre;
}
return OK;
}
//后序线索三叉树
void PostTreading(TriThree* p, TriThree* pre) {
if (*p) {
PostTreading(&(*p)->lchild, pre);
if (!(*p)->lchild) {
(*p)->LTag = _Thread;
(*p)->lchild = pre;
}
PostTreading(&(*p)->rchild, pre);
if (!(*pre)->rchild) {
(*pre)->RTag = _Thread;
(*pre)->rchild = *p;
}
*pre = *p;
}
}
void PostOrderTreading(TriThree* Thrt, FILE* fp) {
TriThree T;
CreateTriTree(&T, fp);
*Thrt = (TriThree)malloc(sizeof(TriTNode));
(*Thrt)->LTag = _Thread;
(*Thrt)->lchild = T;
TriThree pre;
pre = *Thrt;
if (T) {
(*Thrt)->RTag = _Link;
(*Thrt)->rchild = NULL;
PostTreading(&T, &pre);
pre->parent = T;
}
else {
(*Thrt)->lchild = *Thrt;
(*Thrt)->RTag = _Thread;
(*Thrt)->rchild = *Thrt;
}
}
//中序输出线索二叉树
void OutPutThread_In(BiThree T) {
BiThree p;
p = T->lchild;
while (p->LTag == _Link)
p = p->lchild;
while (p != T) {
printf("%c", p->data);
if (p->RTag == _Link) {
p = p->rchild;
while (p->LTag == _Link)
p = p->lchild;
}
else
p = p->rchild;
}
printf("\n");
p = T->rchild;
while (p != T) {
printf("%c", p->data);
if (p->LTag == _Link) {
p = p->lchild;
while (p->RTag == _Link)
p = p->rchild;
}
else
p = p->lchild;
}
printf("\n");
}
//后序输出线索三叉树
void OutPutThread_Post(TriThree T) {
TriThree p, q;
p = T->rchild;
q = p;
while (1) {
printf("%c", p->data);
if (p == T->lchild)
break;
if (p->RTag == _Thread)
p = p->rchild;
else {
if (p == p->parent->lchild) {
if (p == T->lchild)
break;
else if (p->parent->RTag == _Thread)
p = p->parent;
else {
p = p->parent->rchild;
while (1) {
if (p->LTag == _Link) {
p = p->lchild;
continue;
}
if (p->RTag == _Link) {
p = p->rchild;
continue;
}
else
break;
}
}
}
else
p = p->parent;
}
}
}
//求树的深度
int Depth_BiTree(BiTree T) {
if (T) {
return (1 + Depth_BiTree(T->lchild)) > (1 + Depth_BiTree(T->rchild)) \
? (1 + Depth_BiTree(T->lchild)) : (1 + Depth_BiTree(T->rchild));
}
return 0;
}
//输出赫夫曼树和赫夫曼编码表
void OutPutHuffmanTreeAndCode(HuffmanTree T, HuffmanCode C, int m, int n) {
int i;
printf("No.\tW\tPt\tLc\tRc\n");
for (i = 1; i <= m; i++)
printf("%d\t%d\t%d\t%d\t%d\n", i, T[i].weight, T[i].parent, T[i].lchild, T[i].rchild);
printf("\nWt\tCode:\n");
for (i = 1; i <= n; i++)
printf("%d\t%s\n", T[i].weight, C[i]);
}
//销毁赫夫曼树和赫夫曼编码表
Status DestoryHuffmanTreeAndCode(HuffmanTree* T, HuffmanCode* C, int n) {
free(*T);
for (int i = 1; i <= n; i++)
free((*C)[i]);
free(*C);
return OK;
}
//赫夫曼编码
//筛选最小的两个结点
Status Select(HuffmanTree* HT, int n, int* s1, int* s2) {
int min, max, i, flag;
flag = 0;
for (i = 1; i <= n; i++)
if (!(*HT)[i].parent)
if (!flag) {
min = (*HT)[i].weight;
*s1 = i;
flag = 1;
}
else if (flag == 1) {
max = (*HT)[i].weight;
*s2 = i;
break;
}
if (min > max) {
i = min;
min = max;
max = i;
i = *s1;
*s1 = *s2;
*s2 = i;
}
for (i = 1; i <= n; i++) {
if (i != *s1 && i != *s2 && !(*HT)[i].parent)
if ((*HT)[i].weight < min) {
max = min; *s2 = *s1;
min = (*HT)[i].weight; *s1 = i;
}
else if ((*HT)[i].weight <= max) {
max = (*HT)[i].weight; *s2 = i;
}
}
return OK;
}
Status HuffmanCoding(HuffmanTree* HT, HuffmanCode* HC, int* w, int n) {
if (n <= 1) return ERROR;
int m = 2 * n - 1;
int i, s1, s2, start, c, f;
char* cd;
*HT = MALLOC(m + 2, HTNode);
cd = MALLOC(n, char);
*HC = MALLOC(n + 2, char);
/*for (i = 1; i <= n; i++)
(*HC)[i] = (HCNode)malloc(n * sizeof(char));*/
for (i = 1; i <= m + 1; i++) {
if (i <= n) {
(*HT)[i].weight = w[i - 1];
(*HT)[i].lchild = 0;
(*HT)[i].rchild = 0;
(*HT)[i].parent = 0;
}
else {
(*HT)[i].weight = 0;
(*HT)[i].lchild = 0;
(*HT)[i].rchild = 0;
(*HT)[i].parent = 0;
}
}
for (i = n + 1; i < m + 1; i++) {
Select(HT, i - 1, &s1, &s2);
(*HT)[s1].parent = i;
(*HT)[s2].parent = i;
(*HT)[i].lchild = s1;
(*HT)[i].rchild = s2;
(*HT)[i].weight = (*HT)[s1].weight + (*HT)[s2].weight;
}
cd[n - 1] = 0;
for (i = 1; i <= n; i++) {
start = n - 1;
for (c = i, f = (*HT)[i].parent; f; c = f, f = (*HT)[f].parent)
if ((*HT)[f].lchild == c) cd[--start] = '0';
else cd[--start] = '1';
(*HC)[i] = MALLOC(n - start, ElemType_Char);
strcpy((*HC)[i], &cd[start]);
}
free(cd);
OutPutHuffmanTreeAndCode(*HT, *HC, m, n);
DestoryHuffmanTreeAndCode(HT, HC, n);
return OK;
}
//n皇后问题
Status InitNQueens(NQueens* N){
(*N).base = MALLOC(MAX_TREE_SIZE, NQuNode);
(*N).top = (*N).base;
(*N).stacksize = MAX_TREE_SIZE;
return OK;
}
Status PushNQuees(NQueens* N,NQuNode e) {
if ((*N).top - (*N).base >= MAX_TREE_SIZE)
(*N).base = REALLOC((*N).base, ((*N).stacksize + MAX_TREE_SIZE), NQuNode);
*((*N).top++) = e;
return OK;
}
Status PopNQuees(NQueens* N, NQuNode* e) {
if ((*N).base == (*N).top)
return ERROR;
*e = *(--(*N).top);
return OK;
}
void OutPutNQueens(NQueens N, int n) {
int i, j, k;
k = 0;
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++)
if (i == N.base[k].i - 1 && j == N.base[k].j - 1)
printf("%2c", '1');
else
printf("%2c", '0');
printf("\n");
k++;
}
printf("\n");
}
double slope(double i1, double j1, double i2, double j2) {
return (j2 - j1) / (i2 - i1);
}
Status JudgeNQueens(NQueens N) {
NQuNode* p, * q;
for (p = N.base; p < N.top - 1; p++) {
q = N.top - 1;
if (p->j == q->j)
return ERROR;
else if (slope(p->i, p->j, q->i, q->j) == 1)
return ERROR;
else if (slope(p->i, p->j, q->i, q->j) == -1)
return ERROR;
}
return OK;
}
void N_Queens(NQueens* N, int n, int i) {
int j;
NQuNode e, t;
if (i > n)
OutPutNQueens(*N, n);
else
for (j = 1; j <= n; j++) {
e.i = i; e.j = j;
PushNQuees(N, e);
if (JudgeNQueens(*N))
N_Queens(N, n, i + 1);
PopNQuees(N, &t);
}
}
void NQueenQuestion() {
NQueens N;
InitNQueens(&N);
N_Queens(&N, 8, 1);
}
//求幂集
void GetPowerSet(int i, SqList A, SqList* B) {
int k, e, tmp;
if (i > A.length)
OutPutSqList(*B);
else {
GetElem_SqList(A, i, &e);
k = (*B).length;
Insert_SqList(B, e, k + 1);
GetPowerSet(i + 1, A, B);
Delete_SqList(B, k + 1, &tmp);
GetPowerSet(i + 1, A, B);
}
}
void PowerSet() {
SqList A, B;
InitSqList(&A);
InitSqList(&B);
//初始化数列
for (int i = 1; i < 5; i++)
Insert_SqList(&A, i, i);
GetPowerSet(1, A, &B);
}
#endif // !TREE_C