IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> c 二叉树模拟 -> 正文阅读

[数据结构与算法]c 二叉树模拟

头文件 tree.h

#ifndef _TREE_H_
#define _TREE_H_

#include <stdbool.h>

#define SLEN 20

typedef struct item
{
	char petname[SLEN];
	char petkind[SLEN];
} Item;

#define MAXITEMS 10

typedef struct trnode
{
	Item item;
	struct trnode* left;
	struct trnode* right;
} Trnode;

typedef struct tree
{
	Trnode* root;
	int size;
} Tree;

/**
* 操作: 把树初始化为空
* 前置条件: ptree指向一个树
* 后置条件: 树被初始化为空
*/
void InitializeTree(Tree* ptree);

/**
* 操作: 确定树是否为空
* 前置条件: ptree指向一个树
* 后置条件: 如果为空返回true,否则返回false
*/
bool TreeIsEmpty(const Tree* ptree);

/**
* 操作: 确定树是否已满
* 前置条件: ptree指向一个树
* 后置条件: 如果已满返回true,否则返回false
*/
bool TreeIsFull(const Tree* ptree);

/**
* 操作:返回树的项数
* 前置条件: ptree指向一个树
* 后置条件: 返回树的项数
*/
int TreeItemCount(const Tree* ptree);

/**
* 操作:在树中添加一个项
* 前置条件: ptree指向一个树, pi是待添加项的地址
* 后置条件: 添加成功返回true,否则返回false
*/
bool AddItem(const Item* pi, Tree* ptree);

/**
* 操作:在树中查找一个项
* 前置条件: ptree指向一个树, pi是待查找项
* 后置条件: 存在返回true,否则返回false
*/
bool InTree(const Item* pi, const Tree* ptree);

/**
* 操作:在树中删除一个项
* 前置条件: ptree指向一个树, pi是待删除项的地址
* 后置条件: 删除成功返回true,否则返回false
*/
bool DeleteItem(const Item* pi, Tree* ptree);

/**
* 操作:把函数应用于每一个项
* 前置条件: ptree指向一个树, pfunc是一个函数
* 后置条件: pfunc指向的这个函数为树中的每一项执行一次
*/
void Traverse(const Tree* ptree, void(*pfunc)(Item item));

/**
* 操作:删除树中的所有内容
* 前置条件: ptree指向一个树
* 后置条件: 清空树
*/
void DeleteAll(Tree* ptree);

#endif

实现文件 tree.c

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "tree.h"

typedef struct pair
{
	Trnode* parent;
	Trnode* child;
} Pair;

static Trnode* MakeNode(const Item* pi);
static bool ToLeft(const Item* i1, const Item* i2);
static bool ToRight(const Item* i1, const Item* i2);
static void AddNode(Trnode* newNode, Trnode* root);
static void InOrder(const Trnode* root, void(*pfunc)(Item item));
static Pair SeekItem(const Item* pi, const Tree* ptree);
static void DeleteNode(Trnode** ptr);
static void DeleteAllNodes(Trnode* ptr);

void InitializeTree(Tree* ptree)
{
	ptree->root = NULL;
	ptree->size = 0;
}

bool TreeIsEmpty(const Tree* ptree)
{
	if (ptree->root == NULL) {
		return true;
	} 
	return false;
}

bool TreeIsFull(const Tree* ptree)
{
	if (ptree->size == MAXITEMS) {
		return true;
	}
	return false;
}

int TreeItemCount(const Tree* ptree)
{
	return ptree->size;
}

bool AddItem(const Item* pi, Tree* ptree)
{
	Trnode* newNode;

	if (TreeIsFull(ptree)) {
		fprintf(stderr, "Tree is full\n");
		return false;
	}

	if (SeekItem(pi, ptree).child != NULL) {
		fprintf(stderr, "Attempted to add duplicate item\n");
		return false;
	}

	newNode = MakeNode(pi);
	if (newNode == NULL) {
		fprintf(stderr, "Could not create node\n");
		return false;
	}

	ptree->size++;

	if (ptree->root == NULL) {
		ptree->root = newNode;
	}
	else {
		AddNode(newNode, ptree->root);
	}

	return true;
}

bool InTree(const Item* pi, const Tree* ptree)
{
	return (SeekItem(pi, ptree).child == NULL) ? false : true;
}

bool DeleteItem(const Item* pi, Tree* ptree)
{
	Pair look;

	look = SeekItem(pi, ptree);
	if (look.child == NULL) {
		return false;
	}

	if (look.parent == NULL) {
		DeleteNode(&ptree->root);
	}
	else if (look.parent->left == look.child) {
		DeleteNode(&look.parent->left);
	}
	else {
		DeleteNode(&look.parent->right);
	}
	ptree->size--;

	return true;
}

void Traverse(const Tree* ptree, void(*pfunc)(Item item)) 
{
	if (ptree != NULL) {
		InOrder(ptree->root, pfunc);
	}
}

void DeleteAll(Tree* ptree)
{
	if (ptree != NULL) {
		DeleteAllNodes(ptree->root);
	}
	ptree->root = NULL;
	ptree->size = 0;
}

static void InOrder(const Trnode* root, void(*pfunc)(Item item))
{
	if (root != NULL) {
		InOrder(root->left, pfunc);
		(*pfunc)(root->item);
		InOrder(root->right, pfunc);
	}
}

static void DeleteAllNodes(Trnode* ptr)
{
	Trnode* pright;

	if (ptr != NULL) {
		pright = ptr->right;
		DeleteAllNodes(ptr->left);
		free(ptr);
		DeleteAllNodes(pright);
	}
}

static void AddNode(Trnode* newNode, Trnode* root)
{
	if (ToLeft(&newNode->item, &root->item)) {
		if (root->left == NULL) {
			root->left = newNode;
		}
		else {
			AddNode(newNode, root->left);
		}
	} 
	else if (ToRight(&newNode->item, &root->item)) {
		if (root->right == NULL) {
			root->right = newNode;
		}
		else {
			AddNode(newNode, root->right);
		}
	}
	else {
		fprintf(stderr, "Location error in AddNode()\n");
		exit(1);
	}
}

static bool ToLeft(const Item* i1, const Item* i2)
{
	int comp1 = 0;

	if ((comp1 = strcmp(i1->petname, i2->petname)) < 0) {
		return true;
	}
	else if (comp1 == 0 && strcmp(i1->petkind, i2->petkind) < 0) {
		return true;
	}
	return false;
}

static bool ToRight(const Item* i1, const Item* i2)
{
	int comp1 = 0;

	if ((comp1 = strcmp(i1->petname, i2->petname)) > 0) {
		return true;
	}
	else if (comp1 == 0 && strcmp(i1->petkind, i2->petkind) > 0) {
		return true;
	}
	return false;
}

static Trnode* MakeNode(const Item* pi)
{
	Trnode* newNode;

	newNode = (Trnode*)malloc(sizeof(Trnode));
	if (newNode != NULL) {
		newNode->item = *pi;
		newNode->left = NULL;
		newNode->right = NULL;
	}

	return newNode;
}

static Pair SeekItem(const Item* pi, const Tree* ptree)
{
	Pair look;
	look.parent = NULL;
	look.child = ptree->root;

	if (look.child == NULL) {
		return look;
	}

	while (look.child != NULL) {
		if (ToLeft(pi, &(look.child->item))) {
			look.parent = look.child;
			look.child = look.child->left;
		}
		else if (ToRight(pi, &(look.child->item))) {
			look.parent = look.child;
			look.child = look.child->right;
		}
		else {
			break;
		}
	}

	return look;
}



static void DeleteNode(Trnode** ptr)
{
	Trnode* temp;
	if ((*ptr)->left == NULL) {
		temp = *ptr;
		*ptr = (*ptr)->right;
		free(temp);
	}
	else if ((*ptr)->right == NULL) {
		temp = *ptr;
		*ptr = (*ptr)->left;
		free(temp);
	}
	else {
		for (temp = (*ptr)->left; temp->right != NULL; temp = temp->right) {
			continue;
		}
		temp->right = (*ptr)->right;
		temp = *ptr;
		*ptr = (*ptr)->left;
		free(temp);
	}
}

测试 main.c

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "tree.h"

char menu(void);
void addPet(Tree* pt);
void dropPet(Tree* pt);
void showPets(const Tree* pt);
void findPet(const Tree* pt);
void printItem(Item item);
void uppercase(char* ch);
char* s_gets(char* st, int n);

int main(void)
{
	Tree pets;
	char choice;

	InitializeTree(&pets);

	while ((choice = menu()) != 'q') {
		switch (choice)
		{
		case 'a':
			addPet(&pets);
			break;
		case 'l':
			showPets(&pets);
			break;
		case 'f':
			findPet(&pets);
			break;
		case 'n':
			printf("%d pets in club\n", TreeItemCount(&pets));
			break;
		case 'd':
			dropPet(&pets);
			break;
		default:
			puts("Switching error\n");
			break;
		}
	}

	DeleteAll(&pets);
	puts("Done!\n");

	return 0;
}

char menu(void)
{
	int ch;

	puts("Nerfville Pet Club Membership Program");
	puts("Enter the letter corresponding to your choice: ");
	puts("a) add a pet           l) show list of pets");
	puts("n) number of pets      f) find pets");
	puts("d) delete a pet        q) quit");

	while ((ch = getchar()) != EOF) {
		while (getchar() != '\n') {
			continue;
		}
		ch = tolower(ch);
		if (strchr("alrfndq", ch) == NULL) {
			puts("Please enter an a, l, f, n, d, q:");
		}
		else {
			break;
		}
	}

	if (ch == EOF) {
		ch = 'q';
	}

	return ch;
}

void addPet(Tree* pt)
{
	Item temp;

	if (TreeIsFull(pt)) {
		puts("No room in the club!\n");
	}
	else {
		puts("Please enter name of pet:");
		s_gets(temp.petname, SLEN);
		puts("Please enter pet kind:");
		s_gets(temp.petkind, SLEN);

		uppercase(temp.petname);
		uppercase(temp.petkind);
		AddItem(&temp, pt);
	}
}

void showPets(const Tree* pt)
{
	if (TreeIsEmpty(pt)) {
		puts("No entries\n");
	}
	else {
		Traverse(pt, printItem);
	}
}

void printItem(Item item)
{
	printf("Pet: %-19s Kind: %-19s\n", item.petkind, item.petkind);
}

void findPet(const Tree* pt)
{
	Item temp;
	if (TreeIsEmpty(pt)) {
		puts("No entries\n");
		return;
	}

	puts("Please enter name of pet you wish to find: ");
	s_gets(temp.petname, SLEN);
	puts("Please enter kind: ");
	s_gets(temp.petkind, SLEN);

	uppercase(temp.petname);
	uppercase(temp.petkind);
	printf("%s the %s ", temp.petname, temp.petkind);
	if (InTree(&temp, pt)) {
		printf("is a member\n");
	}
	else {
		printf("is not a member\n");
	}
}

void dropPet(Tree* pt)
{
	Item temp;
	if (TreeIsEmpty(pt)) {
		puts("No entries\n");
		return;
	}

	puts("Please enter name of pet you wish to find: ");
	s_gets(temp.petname, SLEN);
	puts("Please enter kind: ");
	s_gets(temp.petkind, SLEN);

	uppercase(temp.petname);
	uppercase(temp.petkind);
	printf("%s the %s ", temp.petname, temp.petkind);

	if (DeleteItem(&temp, pt)) {
		puts("is dropped from the club\n");
	}
	else {
		puts("is not a member\n");
	}
}

void uppercase(char* str)
{
	while (*str) {
		*str = toupper(*str);
		str++;
	}
}

char* s_gets(char* st, int n)
{
	char* ret_val;
	char* find;

	ret_val = fgets(st, n, stdin);
	if (ret_val) {
		find = strchr(st, '\n');
		if (find) {
			*find = '\0';
		}
		else {
			while (getchar() != '\n') {
				continue;
			}
		}
	}
	return ret_val;
}

来自《c primer plus》

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-09-23 11:42:30  更:2021-09-23 11:44:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 11:29:24-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码