C语言数据结构--树

#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

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值