文章目录

  • 一、二叉树的创建和遍历
  • 二、二叉树求解
  • 三、哈夫曼树

一、二叉树的创建和遍历

#include<stdio.h>
#include<stdlib.h>
#define ElemType intvoid PreOrderTransverse(BTNode* t);         //先序遍历 VLR
void InOrderTransverse(BTNode* t);          //中序遍历 LVR
void PostOrderTransverse(BTNode* t);        //后序遍历 LRV   typedef struct btnode {                     // 二叉树节点结构体ElemType element;struct btnode* lChild;struct btnode* rChild;
}BTNode;//先序遍历
void PreOrderTransverse(BTNode* t) {if (t == NULL) {return;}printf("%c", t->element);           //打印输出根结点,此处可以定义其他操作PreOrderTransverse(t->lChild);  //然后先序遍历左子树PreOrderTransverse(t->rChild);  //最后先序遍历右子树
}//中序遍历 LVR
void InOrderTransverse(BTNode* t) {if (t == NULL) {return;}InOrderTransverse(t->lChild);  // 中序遍历根结点的左子树printf("%c", t->element);          //打印输出根结点InOrderTransverse(t->rChild);  // 中序遍历根结点的右子树
}//后序遍历
void PostOrderTransverse(BTNode* t) {if (t == NULL) {return;}PostOrderTransverse(t->lChild);  //后序遍历根结点的左子树PostOrderTransverse(t->rChild);  //然后后序遍历根结点的右子树printf("%c", t->element);            //最后打印输出根结点,此处可以定义其他操作
}//先序构建二叉树
BTNode* PreCreateBt(BTNode* t) {char c;c = getchar();if (c == '#') {                             // 输入#表示此节点没有孩子t = NULL;}else {t = (BTNode*)malloc(sizeof(BTNode));t->element = c;                         //构造根结点t->lChild = PreCreateBt(t->lChild);     //构造左子树t->rChild = PreCreateBt(t->rChild);     //构造右子树}return t;
}#include<iostream>// 123##4##5#6##
int main() {BTNode* t = NULL;// 为二叉树添加元素printf("请输入先序遍历的二叉树序列\n");t = PreCreateBt(t);     printf("\n先序遍历结果:\n");PreOrderTransverse(t);printf("\n\n中序遍历结果:\n");InOrderTransverse(t);printf("\n\n后序遍历结果:\n");PostOrderTransverse(t);printf("\n");return 0;
}/*//t = (BTNode*)malloc(sizeof(BTNode));//t->element = 0;                        //构造根结点//t1 = (BTNode*)malloc(sizeof(BTNode));//t1->element = 1;//t2 = (BTNode*)malloc(sizeof(BTNode));//t2->element = 2;//t->lChild = t1;//t->rChild = t2;//vector<BTNode*> v0;//v0.push_back(t);//vv.push_back(v0);//Transverse(t, v0);/*for (int i = 0; i < vv.size(); i++) {for (int j = 0; j < vv[i].size(); j++) {printf("%d", vv[i][j]->element);}printf("\n");static vector<vector<BTNode*>> vv;层次遍历
//void Transverse(BTNode* t, vector<BTNode*>& this_v) {
//    vector<BTNode*> v;
//    for (int i = 0; i < this_v.size(); i++){
//        v.push_back(this_v[i]->lChild);
//        v.push_back(this_v[i]->rChild);
//    }
//    vv.push_back(v);
//}
*/

二、二叉树求解

#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#define ElemType inttypedef struct btnode {ElemType element;struct btnode* lChild;struct btnode* rChild;
}BTNode;int GetNodeNum(BTNode* t);    //求二叉树结点个数int GetLeafNum(BTNode* t);    //求二叉树叶子结点个数int GetTreeHeight(BTNode* t);   //求二叉树的高度void SwapSubTree(BTNode* t);   //交换二叉树所有子树//先序遍历构建二叉树
BTNode* PreCreateBt(BTNode* t) {char ch;ch = getchar();if (ch == '#') {                           //输入为#表示这里建立空二叉树,即遍历算法的空操作t = NULL;}else {t = (BTNode*)malloc(sizeof(BTNode));t->element = ch;                        //构造根结点t->lChild = PreCreateBt(t->lChild);  //构造左子树t->rChild = PreCreateBt(t->rChild);  //构造右子树}return t;
}//先序遍历
void PreorderTransverse(BTNode* t) {if (t == NULL) {return;}printf("%c", t->element);           //打印输出根结点,此处可以定义其他操作PreorderTransverse(t->lChild);  //然后先序遍历左子树PreorderTransverse(t->rChild);  //最后先序遍历右子树
}//中序遍历
void MediumorderTransverse(BTNode* t) {if (t == NULL) {return;}MediumorderTransverse(t->lChild);  //中序遍历根结点的左子树printf("%c", t->element);          //打印输出根结点,此处可以定义其他操作MediumorderTransverse(t->rChild);  //最后中序遍历根结点的右子树
}//后序遍历
void PostorderTransverse(BTNode* t) {if (t == NULL) {return;}PostorderTransverse(t->lChild);  //后序遍历根结点的左子树PostorderTransverse(t->rChild);  //然后后序遍历根结点的右子树printf("%c", t->element);            //最后打印输出根结点,此处可以定义其他操作
}//求二叉树结点个数
int GetNodeNum(BTNode* t) {if (t == NULL) return 0;return GetNodeNum(t->lChild) + GetNodeNum(t->rChild) + 1;
}//求二叉树叶子结点个数
int GetLeafNum(BTNode* t) {if (t == NULL) return 0;if ((t->lChild == NULL) && (t->rChild == NULL)) return 1;return GetLeafNum(t->lChild) + GetLeafNum(t->rChild);
}//求二叉树的高度
int GetTreeHeight(BTNode* t) {if (t == NULL) return 0;else return 1 + std::max(GetTreeHeight(t->lChild), GetTreeHeight(t->rChild));
}//交换二叉树所有子树
void SwapSubTree(BTNode* t) {if (t) {BTNode* temp = t->lChild;t->lChild = t->rChild;t->rChild = temp;SwapSubTree(t->lChild);SwapSubTree(t->rChild);}
}/*
*     测试的树形12   53 4 # 6## ##  ##
*/// 123##4##5#6##
int main() {BTNode* t = NULL;// 为二叉树添加元素printf("请输入先序遍历的二叉树序列\n");t = PreCreateBt(t);printf("二叉树的节点数:%d\n", GetNodeNum(t));printf("二叉树的叶子数:%d\n", GetLeafNum(t));printf("二叉树的树高度:%d\n", GetTreeHeight(t));SwapSubTree(t);printf("\n交换所有左右子树后:\n\n");printf("先序遍历:\n");PreorderTransverse(t);printf("\n\n中序遍历:\n");MediumorderTransverse(t);printf("\n\n后序遍历:\n");PostorderTransverse(t);printf("\n");return 0;
}/*
编写程序实现求二叉树结点个数、叶子结点个数、二叉树的高度以及交换二叉树所有左右子树的操作。
*/

三、哈夫曼树

#include <iostream>
#include <string>
using namespace std;
#define ElemType intclass HfmTree;typedef struct hfmTNode {ElemType element;           //结点的数据域int w;                      //结点的权值struct hfmTNode* lChild;    //结点的左孩子指针struct hfmTNode* rChild;    //结点的右孩子指针
}HFMTNode;class BTNode
{public:BTNode(){lChild = rChild = parent = NULL;}BTNode(const ElemType& x, char& q){element = x;lChild = rChild = parent = NULL;ch = q;}BTNode(const ElemType& x, char& q, BTNode* l, BTNode* r){element = x;lChild = l;rChild = r;ch = q;parent = NULL;}ElemType element;BTNode* lChild, * rChild, * parent;string num;     // 储存路径编码,用string不用担心大小问题char ch;        // 储存字符
};void Print(ElemType& x)
{cout << x << " ";
}class BinaryTree
{public:BinaryTree();~BinaryTree();bool IsEmpty() const;void Clear() { }             // 移去所有结点,成为空二叉树bool Root(ElemType& x) const;      // 若二叉树不空,则x为根的值,并返回true,否则返回falsevoid MakeTree(const ElemType& x, char c, BinaryTree& left, BinaryTree& right);                        // 建树void BreakTree(ElemType& x, BinaryTree& left, BinaryTree& right);void PreOrder(void (*Visit) (ElemType& x));void InOrder(void (*Visit) (ElemType& x));void PostOrder(void (*Visit) (ElemType& x));int CountNode();             // 计算二叉树的结点个数void PrintHfm();             // 输出二叉树的前序和中序遍历
protected:BTNode* root;
private:void PreOrder(void (*Visit) (ElemType& x), BTNode* t);void InOrder(void (*Visit) (ElemType& x), BTNode* t);void PostOrder(void (*Visit) (ElemType& x), BTNode* t);int CountNode(BTNode* t); // 计算结点数量
};BinaryTree::BinaryTree()
{root = NULL;
}BinaryTree::~BinaryTree()
{Clear();
}bool BinaryTree::IsEmpty() const
{return root == NULL;
}bool BinaryTree::Root(ElemType& x) const
{if (root) {x = root->element;return true;}elsereturn false;
}void BinaryTree::MakeTree(const ElemType& x, char c, BinaryTree& left, BinaryTree& right)
{if (root || &left == &right) {std::cout << "MakeTree fail!" << endl;return;}root = new BTNode(x, c, left.root, right.root);left.root = right.root = NULL;
}void BinaryTree::BreakTree(ElemType& x, BinaryTree& left, BinaryTree& right)
{if (!root || &left == &right || left.root || right.root) {cout << "BreakTree failed!" << endl;return;}else {x = root->element;left.root = root->lChild;right.root = root->rChild;delete root;root = NULL;//this->parent = NULL;}
}void BinaryTree::PreOrder(void (*Visit) (ElemType& x))
{PreOrder(Visit, root);
}void BinaryTree::InOrder(void (*Visit) (ElemType& x))
{InOrder(Visit, root);
}void BinaryTree::PostOrder(void (*Visit) (ElemType& x))
{PostOrder(Visit, root);
}int BinaryTree::CountNode()
{return CountNode(root);
}void BinaryTree::PreOrder(void (*Visit) (ElemType& x), BTNode* t)
{if (t) {Visit(t->element);PreOrder(Visit, t->lChild);PreOrder(Visit, t->rChild);}
}void BinaryTree::InOrder(void (*Visit) (ElemType& x), BTNode* t)
{if (t) {InOrder(Visit, t->lChild);Visit(t->element);InOrder(Visit, t->rChild);}
}void BinaryTree::PostOrder(void (*Visit) (ElemType& x), BTNode* t)
{if (t) {PostOrder(Visit, t->lChild);PostOrder(Visit, t->rChild);Visit(t->element);}
}int BinaryTree::CountNode(BTNode* t)
{if (t) {return CountNode(t->lChild) + CountNode(t->rChild) + 1;}elsereturn 0;
}// 输出哈夫曼树的前序和中序遍历
void BinaryTree::PrintHfm()
{cout << "先序遍历哈夫曼树:" << endl;PreOrder(Print);cout << endl;cout << "中序遍历哈夫曼树:" << endl;InOrder(Print);cout << endl;
}class HfmTree :public BinaryTree
{public:operator ElemType () const{return weight;}ElemType GetWeight(){return weight;}void SetWeight(const ElemType& x){weight = x;}void SetNull(){root = NULL;}void Code();                                    // 根据输入的字符输出编码void DeCode() { DeCode(root); cout << endl; }   // 根据输入的编码输出字符void Create_code() { Create_code(root); }       // 写入路径编码void Conn_parent() { Conn_parent(root); }       // 令parent指向上级结点void test() { testprint(root); }                // 测试,输出字符对应的编码
private:void Create_code(BTNode* t);void DeCode(BTNode* q);void Conn_parent(BTNode* t);ElemType weight;void Code(BTNode* t, char a);void testprint(BTNode* t);
};class PriQueue
{private:HfmTree* hfmQueue;int n, maxSize;
public:PriQueue(int mSize = 100);~PriQueue() { delete[]hfmQueue; }bool IsEmpty() const { return n == 0; }bool IsFull() const { return n == maxSize; }void Append(const HfmTree& x);void Deal(HfmTree& x);void print();void AdjustDown(int r);void AdjustUp(int j);
};PriQueue::PriQueue(int mSize)
{maxSize = mSize;n = 0;hfmQueue = new HfmTree[maxSize];
}void PriQueue::Append(const HfmTree& x)
{if (IsFull()) {cout << "The PriQueue is full!" << endl;}hfmQueue[n++] = x;AdjustUp(n - 1);
}void PriQueue::Deal(HfmTree& x)
{if (IsEmpty()) {cout << "The PriQueue is Empty!" << endl;}x = hfmQueue[0];hfmQueue[0] = hfmQueue[--n];AdjustDown(0);
}void PriQueue::print()
{for (int i = 0; i < n; i++) {cout << hfmQueue[i] << " " << endl;}
}void PriQueue::AdjustDown(int r)
{int Child = 2 * r + 1;HfmTree temp = hfmQueue[r];while (Child < n) {if (Child + 1 < n && hfmQueue[Child + 1] < hfmQueue[Child]) {Child++;}if (temp > hfmQueue[Child]) {hfmQueue[r] = hfmQueue[Child];r = Child;Child = 2 * Child + 1;}else {break;}}hfmQueue[r] = temp;
}void PriQueue::AdjustUp(int j)
{HfmTree temp = hfmQueue[j];int i = j;while (i > 0 && temp < hfmQueue[(i - 1) / 2]) {hfmQueue[i] = hfmQueue[(i - 1) / 2];i = (i - 1) / 2;}hfmQueue[i] = temp;
}// 打印出所有的结点的权值以及对应的字符
void HfmTree::testprint(BTNode* t)
{static int u = 0;if (t){cout << t->num << " " << t->ch << " " << u++ << endl;testprint(t->lChild);testprint(t->rChild);}
}// 由输入的字符输出相应的编码
void HfmTree::Code()
{cout << "请输入要编码的字符串:" << endl;string s;cin >> s;for (int i = 0; i < s.length(); i++) {Code(root, s[i]);}cout << endl;
}// 由输入的编码输出相应的字符
void HfmTree::DeCode(BTNode* q)
{cout << "请输入二进制编码(0和1的组合):" << endl;string n;cin >> n;BTNode* t = q;int count = n.length();for (int i = 0; i < count; i++) {if (n[i] == '0' && t->lChild->ch != '*') {cout << t->lChild->ch;t = q;}else if (n[i] == '1' && t->rChild->ch != '*') {cout << t->rChild->ch;t = q;}else if (n[i] == '0' && t->lChild != NULL) {t = t->lChild;}else if (n[i] == '1' && t->rChild != NULL) {t = t->rChild;}else {cout << "Decode fail!";return;}}
}// 把空的parent指针指向每个节点的父级指针
void HfmTree::Conn_parent(BTNode* t)
{if (t) {if (t->lChild != NULL) {t->lChild->parent = t;}if (t->rChild != NULL) {t->rChild->parent = t;}Conn_parent(t->lChild);Conn_parent(t->rChild);}
}void HfmTree::Code(BTNode* t, char a)
{if (t) {if (t->ch == a) {cout << t->num;}Code(t->lChild, a);Code(t->rChild, a);}
}
// 用遍历把路径保存在字符串num里
void HfmTree::Create_code(BTNode* t)
{if (t) {if (t->parent != NULL) {if (t == t->parent->lChild) {t->num = t->parent->num + '0';}else if (t == t->parent->rChild) {t->num = t->parent->num + '1';}elsecout << "Creat_code Error!" << endl;}Create_code(t->lChild);Create_code(t->rChild);}
}/// <summary>
///
/// </summary>
/// <param name="weight">权值数组</param>
/// <param name="charArr">名称数组</param>
/// <param name="size">节点数量</param>
/// <returns></returns>
HfmTree CreateHfmTree(ElemType weight[], char charArr[], int size)
{PriQueue pQ(size);HfmTree x, y, z;for (int i = 0; i < size; i++) {z.MakeTree(weight[i], charArr[i], x, y);z.SetWeight(weight[i]);pQ.Append(z);z.SetNull();}for (int i = 1; i < size; i++) {pQ.Deal(x);pQ.Deal(y);z.MakeTree(x.GetWeight() + y.GetWeight(), '*', x, y); // *用于区别叶子和普通结点z.SetWeight(x.GetWeight() + y.GetWeight());pQ.Append(z);z.SetNull();}pQ.Deal(z);return z;
}// 6
// ABCDEFG
// 9 11 13 3 5 12
int main()
{cout << "请输入需要编码的字符数量:" << endl;int size;                          // 需要编码的字符数量cin >> size;cout << "请输入所要编码的字符:" << endl;char* charArr = new char[size + 1];      // 储存字符cin >> charArr;cout << "请输入对应字符的权值:" << endl;int* weightArr = new int[size + 1];        // 储存权值for (int i = 0; i < size; i++) {cin >> weightArr[i];}HfmTree hfmTree = CreateHfmTree(weightArr, charArr, size);hfmTree.Conn_parent();hfmTree.Create_code();//a.test();                     while (1) {cout << endl;cout << "请输入功能" << endl;cout << "1. 编码" << endl;cout << "2. 解码" << endl;cout << "3. 显示哈夫曼树(先序遍历+后序遍历)" << endl;cout << "4. 退出" << endl;int choice;cin >> choice;switch (choice) {case 1:hfmTree.Code();break;case 2:hfmTree.DeCode();break;case 3:hfmTree.PrintHfm();case 4:return 0;}}system("pause");   // 在vs上编译运行需要的暂停函数return 0;
}

南京邮电大学数据结构实验二(代码篇)相关推荐

  1. 南京邮电大学数据结构实验三(图的基本运算及飞机换乘次数最少问题)

    文章目录 实验一.图的基本运算 1.邻接矩阵表示 (1)验证基本运算 (2)图的深度和宽度优先遍历(邻接矩阵) 2.邻接表表示 (1)验证基本运算 (2)图的深度和宽度优先遍历(邻接表) 实验二.飞机 ...

  2. 南京邮电大学数据结构实验四(各种排序算法)

    南邮数据结构实验报告四----各种排序算法 一.各类算法 (一)简单选择排序 (二)直接插入排序 (三)冒泡排序 (四)快速排序 (五)两路合并排序 (六)堆排序 二.全部排序整合+时间测试 三.算法 ...

  3. 南京邮电大学离散数学实验二(二元关系的性质判定)

    文章目录 一. 实验目的和要求 二.实验环境(实验设备) 三.实验原理及内容 (一)数据结构 1.全局变量: 2.函数调用关系 (二)核心代码 1.代码 2.时间复杂度为O(n2)和O(n3) (三) ...

  4. 南京邮电大学操作系统实验二:线程的互斥与同步

    实验原理及内容 基于互斥锁的临界区管理 使用编辑器gedit 2_1.c,新建一个2_1.c源文件,创建双线程并发完成订票操作,输入后面的范例代码: #include <stdio.h> ...

  5. 南京邮电大学c语言实验报告3v2,南京邮电大学操作系统实验报告

    <南京邮电大学操作系统实验报告>由会员分享,可在线阅读,更多相关<南京邮电大学操作系统实验报告(20页珍藏版)>请在人人文库网上搜索. 1.通信与信息工程学院2015 / 20 ...

  6. 数据结构实验二 :二叉树的操作与实现

    数据结构实验一:线性表,堆栈和队列实现 数据结构实验二 :二叉树的操作与实现 数据结构实验三: 图的操作与实现 数据结构实验四 : 查找和排序算法实现 文章目录 一.实验目的: 二.使用仪器.器材 三 ...

  7. 数据结构实验二 树和二叉树的实现

    广州大学学生实验报告 开课实验室:计算机科学与工程实验(电子楼418A)     2019年5月13日 学院 计算机科学与教育软件学院 年级.专业.班 计算机科学与技术172班 姓名 学号 17061 ...

  8. 山东大学2021级数据结构实验全集代码

    具体的细节思路的话这边不放了,搜搜百度自己弄懂了就比较好做 这边提供完整的代码造福大家(供大家理解内容与自由修改) Github地址: https://github.com/SeKatien3tte/ ...

  9. 杭电和南邮计算机考研哪个好考,南京邮电大学研究生,二本考南邮研究生!

    南邮的研究生好考么 你好!当然可以的啊 其实考博士主要还是要导师推荐 仅代表个人观点,不喜勿喷,谢谢. [15届考研生]教南邮和杭电的选择 想问一下了解情况的同学,学长,老师,研究生考试,南京邮电大学 ...

最新文章

  1. Codeforces 813B The Golden Age(数学+枚举)
  2. uva-10152-乌龟排序
  3. 成功解决⑧NVIDIA安装程序无法继续 此NVIDL驱动程序与此Windows版本不兼容。 此图形驱动程序无法找到兼吝的图形硬件。
  4. bzoj 1914: [Usaco2010 OPen]Triangle Counting 数三角形——极角排序
  5. C库函数与系统函数的关系
  6. Exchange2010部署边缘服务器
  7. HashMap底层实现及原理
  8. CentOS 7系统升级备份恢复实验记录
  9. DOS 常用命令大全
  10. Android网络编程5之OkHttp2.x用法全解析
  11. 经典算法问题——稳定匹配(Stable Matching)
  12. 智能音箱中采用的数字音频功放
  13. AI快捷键大全 2020
  14. IE火狐的代理服务器的设置
  15. Android开发 SpannableString开发详解
  16. 陈年再创业:B2C必须标准化 VANCL只做男装
  17. 如何构建OctoberCMS Widget插件
  18. linux sqlite图形工具,SQLite 图形化管理工具
  19. 虚幻4引擎开发的手游_虚幻4引擎开发 《神佑》手游首次公开
  20. mysql范围查询如何建索引_MySQL索引(二):建索引的原则

热门文章

  1. CC2530 输入输出配置、中断配置、时钟、串口配置
  2. 集聚新潮流:iOS音乐合成器七大亮星
  3. Josephus 问题(2)
  4. mongodb的基本操作
  5. QMS-云质-质量管理软件-QMS软件-应该自己开发,外包还是购买软件产品?
  6. 【PHP微信公众号开发】微信上传素材curl用法
  7. 10% building 2/2 modules 0 active ERROR SyntaxError: Unexpected stringimport core-js/modules/es6.r
  8. hdu 4521 小明序列
  9. espressif中的sd库有问题
  10. spring boot和Spring Cloud