键树的两种表示法(双链表示以及Trie树)(无主函数,可自行验证)

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <math.h>
#define OK 1
#define ERROR 0
#define FALSE 0
#define TRUE 1
#define OVERFLOW -2
#define LH 1
#define RH -1
#define EH 0
#define GRADE 4
typedef int Status;
typedef int KeyType;
typedef struct
{
	KeyType key;
}ElemType;
typedef struct
{
	ElemType* elem;
	int length;
}SSTable;
typedef ElemType TElemType;
typedef struct BiTNode
{
	TElemType data;
	struct BiTNode* lchild, * rchild;
}BiTNode, * BiTree;
typedef struct BSTNode
{
	TElemType data;
	int bf;
	struct BSTNode* lchild, * rchild;
}BSTNode, * BSTree;
typedef struct BTNode
{
	int keynum;
	struct BTNode* parent;
	KeyType key[GRADE + 1];
	struct BTNode* ptr[GRADE + 2];
	ElemType* recptr[GRADE + 1];
}BTNode, * BTree;
typedef struct
{
	BTNode* ptr;
	int i;
	int tag;
}Result;


//查找表元素输入,关键字赋值以及比较
void InputTableElem(ElemType* e)
{
	printf("请输入关键字信息\n");
	scanf("%d", &(e->key));
}
void KeyWordAssign(KeyType* destination, KeyType source)
{
	(*destination) = source;
}
void KeyWordPrint(KeyType key)
{
	printf("%d\n", key);
}
void TableElemAssign(ElemType* destination, ElemType source)
{
	(*destination).key = source.key;
}
void TableElemPrint(ElemType e)
{
	printf("%d\n", e.key);
}
Status EQ(KeyType key1, KeyType key2)
{
	if (key1 == key2)
		return TRUE;
	else
		return FALSE;
}
Status LT(KeyType key1, KeyType key2)
{
	if (key1 < key2)
		return TRUE;
	else
		return FALSE;
}
Status LE(KeyType key1, KeyType key2)
{
	if (key1 <= key2)
		return TRUE;
	else
		return FALSE;
}
Status MT(KeyType key1, KeyType key2)
{
	if (key1 > key2)
		return TRUE;
	else
		return FALSE;
}
Status ME(KeyType key1, KeyType key2)
{
	if (key1 >= key2)
		return TRUE;
	else
		return FALSE;
}


//静态查找表
Status CreatSSTable(SSTable* T, int n)
{
	T->length = n;
	T->elem = (ElemType*)malloc(sizeof(ElemType) * (n + 1));
	if (!T->elem) exit(OVERFLOW);
	for (int i = 1; i <= T->length; i++)
	{
		printf("请输入第%d个表项信息:\n", i);
		InputTableElem(&(T->elem[i]));
	}
	return OK;
}
int Search_Seq(SSTable ST, KeyType key)                   //Sequence Search
{
	KeyWordAssign(&(ST.elem[0].key), key);
	int i = ST.length;
	while (!EQ(ST.elem[i].key, key))
		i--;
	return i;
}
int Search_Bin(SSTable ST, KeyType key)                    //Binary Search
{
	int low = 1, high = ST.length;
	int mid = (low + high) / 2;
	while (low <= high)
	{
		if (EQ(ST.elem[mid].key, key))
			return mid;
		if (MT(ST.elem[mid].key, key))
			high = mid - 1;
		else
			low = mid + 1;
	}
	return 0;
}
void SecondOptimal(BiTree* T, SSTable S, int* sw, int low, int high)
{
	int i = low;
	int w = sw[high] + sw[low - 1];
	int min = abs(sw[high] - sw[low]);
	for (int j = low + 1; j <= high; j++)
	{
		if (abs(w - sw[j - 1] - sw[j]) < min)
		{
			i = j;
			min = abs(w - sw[i] - sw[i - 1]);
		}
	}
	(*T) = (BiTree)malloc(sizeof(BiTNode));
	if (!(*T)) exit(OVERFLOW);
	KeyWordAssign(&((*T)->data.key), S.elem[i].key);
	if (i == low)
		(*T)->lchild = NULL;
	else
		SecondOptimal(&((*T)->lchild), S, sw, low, i - 1);
	if (i == high)
		(*T)->rchild = NULL;
	else
		SecondOptimal(&((*T)->rchild), S, sw, i + 1, high);
}
//键树(双链树)
#define MAXKEYLEN 16
typedef struct
{
	char ch[MAXKEYLEN];
	int num;
}KeysType;
typedef struct
{
	KeysType K;
}Record;
typedef enum { LEAF, BRANCH } NodeKind;
typedef struct DLTNode
{
	char symbol;
	struct DLTNode* next;
	NodeKind kind;
	union
	{
		Record* infoptr;
		struct DLTNode* first;
	};
}DLTNode, * DLTree;
Status InputRecord(Record* R)
{
	printf("请输入关键字的字符数目\n");
	scanf("%d", &(R->K.num));
	getchar();
	printf("请逐个输入关键字字符\n");
	for (int i = 0; i < R->K.num; i++)
	{
		printf("第%d个字符为:\n", i + 1);
		R->K.ch[i] = getchar();
		getchar();
	}
	return OK;
}
Status InputKeysType(KeysType* K)
{
	printf("请输入关键字的字符数目\n");
	scanf("%d", &(K->num));
	getchar();
	printf("请逐个输入关键字字符\n");
	for (int i = 0; i < K->num; i++)
	{
		printf("第%d个字符为:\n", i + 1);
		K->ch[i] = getchar();
		getchar();
	}
	return OK;
}
Status InitDLTree(DLTree* T)
{
	(*T) = (DLTree)malloc(sizeof(DLTNode));
	if (!(*T)) exit(OVERFLOW);
	(*T)->next = NULL;
	(*T)->kind = BRANCH;
	(*T)->first = NULL;
	(*T)->symbol = '@';
	return OK;
}
Status RecordAssign(Record* R1, Record R2)
{
	R1->K.num = R2.K.num;
	for (int i = 0; i < R2.K.num; i++)
		R1->K.ch[i] = R2.K.ch[i];
	return OK;
}
Status RecordPrint(Record R)
{
	for (int i = 0; i < R.K.num; i++)
		putchar(R.K.ch[i]);
	return OK;
}
Status InsertKeysType(DLTree* T, Record R)
{
	KeysType K = R.K;
	DLTNode* p = (*T)->first, * q = *T;
	int count = 0;
	while (count < K.num)
	{
		if (p && p->symbol == K.ch[count])
		{
			q = p;
			p = p->first;
			count++;
		}
		else
		{
			if (p && p->symbol != K.ch[count])
			{
				q = p;
				p = p->next;
			}
			else
			{
				if (count - 1 >= 0 && q->symbol != K.ch[count - 1])
				{
					p = (DLTNode*)malloc(sizeof(DLTNode));
					if (!p) exit(OVERFLOW);
					p->first = NULL;
					p->kind = BRANCH;
					p->next = NULL;
					p->symbol = K.ch[count];
					q->next = p;
					q = p;
					p = p->first;
					count++;
				}
				while (count < K.num)
				{
					p = (DLTNode*)malloc(sizeof(DLTNode));
					if (!p) exit(OVERFLOW);
					p->first = NULL;
					p->kind = BRANCH;
					p->next = NULL;
					p->symbol = K.ch[count];
					q->first = p;
					q = p;
					p = p->first;
					count++;
				}
			}
		}
	}
	p = (DLTNode*)malloc(sizeof(DLTNode));
	if (!p) exit(OVERFLOW);
	p->kind = LEAF;
	p->next = NULL;
	p->symbol = '#';
	p->infoptr = (Record*)malloc(sizeof(Record));
	if (!p->infoptr) exit(OVERFLOW);
	RecordAssign(p->infoptr, R);
	q->first = p;
	return OK;
}
Record* SearchDLTree(DLTree T, KeysType K)
{
	DLTNode* p = T->first;
	int count = 0;
	while (p && count < K.num)
	{
		if (p->symbol == K.ch[count])
		{
			p = p->first;
			count++;
		}
		while (count < K.num && p && p->symbol != K.ch[count])
			p = p->next;
	}
	if (!p || p->kind != LEAF)
		return NULL;
	else
		return p->infoptr;
}


//键树(Trie树)
typedef struct TrieNode
{
	NodeKind kind;
	union
	{
		struct
		{
			KeysType K;
			Record* infoptr;
		}leaf;
		struct
		{
			struct TrieNode* ptr[27];
			int num;
		}branch;
	};
}TrieNode, * TrieTree;
Status KeysTypeAssign(KeysType* K1, KeysType K2)
{
	(*K1).num = K2.num;
	for (int i = 0; i < K2.num; i++)
		(*K1).ch[i] = K2.ch[i];
	return OK;
}
int Order(KeysType K, int m)
{
	if (m == K.num)
		return 0;
	int i = (int)K.ch[m] - 97 + 1;
	return i;
}
Status KeysTypeEqual(KeysType K1, KeysType K2)
{
	if (K1.num != K2.num)
		return FALSE;
	for (int i = 0; i < K1.num; i++)
		if (K1.ch[i] != K2.ch[i])
			return FALSE;
	return TRUE;
}
Status CreatTrieBranchNode(TrieTree* T)
{
	(*T) = (TrieTree)malloc(sizeof(TrieNode));
	if (!(*T)) exit(OVERFLOW);
	(*T)->kind = BRANCH;
	for (int i = 0; i < 27; i++)
		(*T)->branch.ptr[i] = NULL;
	(*T)->branch.num = 0;
	return OK;
}
Status InsertTrieLeafNode(TrieTree* T, Record R, int ord)
{
	(*T)->branch.num++;
	(*T)->branch.ptr[ord] = (TrieTree)malloc(sizeof(TrieNode));
	if (!(*T)->branch.ptr[ord]) exit(OVERFLOW);
	TrieNode* p = (*T)->branch.ptr[ord];
	p->kind = LEAF;
	p->leaf.infoptr = (Record*)malloc(sizeof(Record));
	if (!p->leaf.infoptr) exit(OVERFLOW);
	RecordAssign(p->leaf.infoptr, R);
	KeysTypeAssign(&(p->leaf.K), R.K);
	return OK;
}
Status InsertTrieTree(TrieTree* T, Record R, int m)
{
	if (!(*T))
	{
		CreatTrieBranchNode(T);
		int ord = Order(R.K, m);
		InsertTrieLeafNode(T, R, ord);
	}
	else
	{
		int ord = Order(R.K, m);
		TrieNode* p = (*T)->branch.ptr[ord];
		TrieNode* q;
		if (!p)
			InsertTrieLeafNode(T, R, ord);
		else
		{
			if (p->kind == LEAF)
			{
				if (KeysTypeEqual(p->leaf.K, R.K))
				{
					printf("已经存在\n");
					return ERROR;
				}
				else
				{
					CreatTrieBranchNode(&q);
					(*T)->branch.ptr[ord] = q;
					InsertTrieTree(&q, *(p->leaf.infoptr), m + 1);
					InsertTrieTree(&q, R, m + 1);
				}
			}
			else
				InsertTrieTree(&p, R, m + 1);
		}
	}
	return OK;
}
Record* SearchTrieTree(TrieTree T, KeysType K)
{
	TrieNode* p = T;
	if (!p) return NULL;
	int i = 0;
	int ord;
	while (p && i < K.num && p->kind == BRANCH)
	{
		ord = Order(K, i);
		p = p->branch.ptr[ord];
		i++;
	}
	if (!p || (p->kind == LEAF && !KeysTypeEqual(p->leaf.K, K)))
		return NULL;
	if (p->kind == LEAF)
		return p->leaf.infoptr;
	else
	{
		p = p->branch.ptr[0];
		if (p)
			return p->leaf.infoptr;
		else
			return NULL;
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值