存储结构(物理结构):数据对象在计算机中的存储。即要存储数据元素的数据,也要存储元素之间的逻辑关系。
顺序存储结构:借助元素在存储器上的相对位置来表示元素之间的关系。要求一片连续的空间。
链式存储结构:无需一片连续的空间,但是为了表示元素之间的关系,需要添加一个指针字段,保存后继元素的存储地址。
数据类型(Data Type):是一个值的集合和定义在这个值集上的一组操作的总称。
抽象数据类型(Abstract Data Type, ADT): 一般由用户定义,表示应用问题的数学模型,以及在这个模型上的一组操作的总称,包含数据对象、数据关系、基本关系。
#include
#include
#include
#define MAXSIZE 1005
#define OK 1
#define ERROR 0
typedef int Status;
using namespace std;
struct Book{
char no[30];
char name[30];
double price;
bool operator == (const Book &w) const {
if (!strcmp(no, w.no)) return true;
return false;
}
};
struct List {
Book* elem;
int lenth;
};
//初始化线性表
Status initList(List &list) {
list.elem = new Book[MAXSIZE];
if (!list.elem) exit(0); //创建失败
list.lenth = 0;
return OK;
}
//获取线性表元素
Status getElem(List &list, int i, Book &elem) {
if (i < 1 || i > list.lenth) return ERROR;
elem = list.elem[i - 1];
return OK;
}
//获取某个元素在线性表中的位置 不存在返回0
int locateElem(List &list, Book &elem) {
for (int i = 0; i < list.lenth; i++) {
if (elem == list.elem[i]) return i + 1;
}
return 0;
}
//添加元素
Status insertElem(List &list, Book &elem) {
if (list.lenth == MAXSIZE) return ERROR;
list.elem[list.lenth++] = elem;
return OK;
}
//添加元素通过位置
Status insertElem(List &list, int i, Book &elem) {
if (i < 1 || i > list.lenth + 1) return ERROR;
for (int j = list.lenth - 1; j >= i - 1; j--) {
list.elem[j + 1] = list.elem[j];
}
list.elem[i - 1] = elem;
list.lenth++;
return OK;
}
//删除指定位置的元素
Status deleteElem(List &list, int i) {
if (i < 1 || i > list.lenth) return ERROR;
for (int j = i - 1; j < list.lenth - 1; j++) list.elem[j] = list.elem[j + 1];
list.lenth--;
return OK;
}
void output(Book &elem) {
printf("no:%s name:%s price: %lf\n", elem.no, elem.name, elem.price);
}
List list;
int main() {
initList(list);
//添加元素
Book books[100];
for (int i = 1; i <= 3; i++) {
Book book;
scanf("%s%s%lf", book.no, book.name, &book.price);
insertElem(list, i, book);
}
for (int i = 0; i < list.lenth; i++) output(list.elem[i]);
return 0;
}
首元结点:是指链表中存储的第一元素结点。
头结点:是首元结点之前设置的一个结点,其指针域指向首元结点。
链表是非随机存取的结构,要取得某个元素,必须从头指针出发进行寻找,也可称为顺序存取的结构。
ASL(Average Search Length) = n-1 / 2 (0, 1, 2,…,n-1)
#include
#include
#include
#define MAXSIZE 1005
#define OK 1
#define ERROR 0
typedef int Status;
using namespace std;
struct Book{
string no;
string name;
double price;
bool operator == (const Book &w) const {
if (no == w.no) return true; return false;
}
};
typedef struct Node {
Book elem;
Node *next;
}Node, *List;
//初始化头节点
Status initList(List &L) {
L = new Node();
L->next = NULL;
return OK;
}
//获取链表中的元素
Status getElem(List &L, int i, Book &e) {
Node *p = L->next;
int j = 1; //代表标号
while (p && j < i) {
p = p->next; j++;
}
if (!p || j > i) return ERROR;
e = p->elem;
return OK;
}
//单链表的插入, 插入位置为i 即ai-1 与ai之间 合法区间[1,n+1]
Status insertElem(List &L, int i, Book &e) {
Node *p = L; //初始从0开始
int j = 0;
while (p && j < i - 1) { //在i-1的位置停下
p = p->next; j++;
}
if (!p || j > i - 1) return ERROR;
Node *s = new Node();
s->elem = e;
//执行链接操作
s->next = p->next;
p->next = s;
return OK;
}
//输出链表中的元素
void output(List &L) {
Node *p = L;
while (p->next) {
p = p->next;
cout << p->elem.no << " " << p->elem.name << " " << p->elem.price << endl;
}
}
//按值查找 查找失败返回NULL
Node *locateElem(List &L, Book &e) {
Node *p = L->next;
while (p && !(p->elem == e)) p = p->next;
return p;
}
//删除指定位置的结点 [1, n]
Status deleteElem(List &L, int i) {
Node *p = L;
int j = 0;
while (p && j < i - 1) {
p = p->next; j++;
}
//注意必须后面结点存在
if (!(p->next) || j > i - 1) return ERROR;
Node *s = p->next;
delete(s); //释放结点
p->next = p->next->next;
return OK;
}
//创建链表,并添加n个元素--前插法
void createListHead(List &L, int n) {
L = new Node();
L->next = NULL;
for (int i = 1; i <= n; i++) {
Node *p = new Node();
cin >> p->elem.no >> p->elem.name >> p->elem.price;
p->next = L->next;
L->next = p;
}
}
//创建链表,并添加n个元素--后插法
void createListRear(List &L, int n) {
L = new Node();
L->next = NULL;
Node *r = L;
for (int i = 1; i <= n; i++) {
Node *p = new Node();
cin >> p->elem.no >> p->elem.name >> p->elem.price;
r->next = p;
p->next = NULL;
r = p; //新的节点成为尾结点
}
}
List L;
int main() {
// initList(L); //初始化
createListRear(L, 3);
output(L);
return 0;
}
#include
#include
#include
#define MAXSIZE 1005
#define OK 1
#define ERROR 0
typedef int Status;
using namespace std;
struct Book{
string no;
string name;
double price;
bool operator == (const Book &w) const {
if (no == w.no) return true; return false;
}
};
typedef struct Node {
Book elem;
Node *next;
Node *prior; //直接前驱
}Node, *List;
//初始化头节点
Status initList(List &L) {
L = new Node();
L->next = L;
L->prior = L;
return OK;
}
int getLength(List &L) {
Node *p = L;
int j = 0;
while (p->next != L) {
j++; p = p->next;
}
return j;
}
//获取链表中的元素
Status getElem(List &L, int i, Book &e) {
Node *p = L->next;
int j = 1; //代表标号
while (p != L && j < i) {
p = p->next; j++;
}
if (p == L || j > i) return ERROR;
e = p->elem;
return OK;
}
//单链表的插入, 插入位置为i 即ai-1 与ai之间 合法区间[1,n+1]
Status insertElem(List &L, int i, Book &e) {
Node *p = L; //初始从0开始
int len = getLength(L);
if (i < 1 || i > len + 1) return ERROR;
while (i) {
i--; p = p->next;
}
Node *s = new Node();
s->elem = e;
//执行链接操作
s->next = p;
s->prior = p->prior;
p->prior->next = s;
p->prior = s; //最后一步连接p的前驱
return OK;
}
//输出链表中的元素
void output(List &L) {
Node *p = L;
while (p->next != L) {
p = p->next;
cout << p->elem.no << " " << p->elem.name << " " << p->elem.price << endl;
}
}
//按值查找 查找失败返回NULL
Node *locateElem(List &L, Book &e) {
Node *p = L->next;
while (p != L && !(p->elem == e)) p = p->next;
return p;
}
//删除指定位置的结点 [1, n]
Status deleteElem(List &L, int i) {
Node *p = L;
int len = getLength(L);
if (i < 1 || i > len) return ERROR;
while (i) {
i--; p = p->next;
}
p->prior->next = p->next;
p->next->prior = p->prior;
delete(p);
return OK;
}
//创建链表,并添加n个元素--前插法
void createListHead(List &L, int n) {
L = new Node();
L->next = L;
L->prior = L;
for (int i = 1; i <= n; i++) {
Node *s = new Node(), *p = L->next;
cin >> s->elem.no >> s->elem.name >> s->elem.price;
s->next = p;
s->prior = p->prior;
p->prior->next = s;
p->prior = s;
}
}
List L;
int main() {
initList(L); //初始化
// createListHead(L, 3);
for (int i = 1; i <= 3; i++) {
Book book;
cin >> book.no >> book.name >> book.price;
insertElem(L, i, book);
}
output(L);
return 0;
}
#include
#include
#include
using namespace std;
typedef struct Node {
int data;
Node *next;
}Node, *List;
//合并2个有序链表, 按照非递减进行排列
void merge(List &C, List &A, List &B) {
C = A; Node *p = C;
Node *pa = A->next, *pb = B->next;
while (pa && B) {
if (pa->data <= pb->data) {
p->next = pa;
p = pa;
pa = pa->next;
} else {
p->next = pb;
p = pb;
pb = pb->next;
}
}
p->next = pa ? pa : pb;
delete(B);
}
//创建链表,并添加n个元素--后插法
void createListRear(List &L, int n) {
L = new Node();
L->next = NULL;
Node *r = L;
for (int i = 1; i <= n; i++) {
Node *p = new Node();
cin >> p->data;
r->next = p;
p->next = NULL;
r = p; //新的节点成为尾结点
}
}
void output(List &L) {
Node *p = L;
while (p->next) {
p = p->next;
printf("%d ", p->data);
}
}
List A, B, C;
int main() {
createListRear(A, 3);
createListRear(B, 5);
merge(C, A, B);
output(C);
return 0;
}
#include
#include
#include
using namespace std;
typedef struct Node {
double coef; //系数
int expo; //指数
Node *next;
}Node, *List;
void createPoly(List &L, int n) {
L = new Node();
L->next = NULL;
for (int i = 1; i <= n; i++) {
Node *s = new Node(), *p = L->next, *pre = L;
cin >> s->coef >> s->expo;
//找到第一个比它大的
while (p && p->expo < s->expo) {
pre = p;
p = p->next;
}
s->next = p;
pre->next = s;
}
}
void addPoly(List &C, List &A, List &B) {
C = A;
Node *pa = A->next, *pb = B->next, *pc = C;
while (pa && pb) {
if (pa->expo == pb->expo) {
double sum = pa->coef + pb->coef;
if (sum) {
pa->coef = sum;
Node *s = pb;
pc->next = pa; pc = pc->next;
pb = pb->next;
pa = pa->next;
delete(s);//在pb转移之后释放
} else {
Node *s = pa; pa = pa->next; delete(s);
s = pb; pb = pb->next; delete(s);
}
} else if(pa->expo < pb->expo) {
pc->next = pa; pc = pc->next; pa = pa->next;
} else {
pc->next = pb; pc = pc->next; pb = pb->next;
}
}
pc->next = pa ? pa : pb;
}
void output(List &L) {
Node *p = L;
while (p->next) {
p = p->next;
if (p->next) cout<< p->coef << "x^" << p->expo << " + ";
else cout<< p->coef << "x^" << p->expo;
}
cout << endl;
}
int main() {
List A, B, C;
createPoly(A, 3);
output(A);
createPoly(B, 3);
output(B);
addPoly(C, A, B);
output(C);
return 0;
}
#include
#include
#include
typedef long long ll;
using namespace std;
stack<char> OPTR;
stack<int> OPND;
char prt[7][8] = {
{">><<<>>"},
{">><<<>>"},
{">>>><>>"},
{">>>><>>"},
{"<<<<<=>"},
{">>>>=>>"},
{"<<<<<<="}
};
char id[8] = {"+-*/()\n"};
//返回2个操作符大小关系
char compare(char lop, char rop) {
int ld = 0, rd = 0;
for (int i = 0; i < 7; i++) if (lop == id[i]) {ld = i;break;}
for (int i = 0; i < 7; i++) if (rop == id[i]) {rd = i;break;}
return prt[ld][rd];
}
void cal() {
int b = OPND.top(); OPND.pop(); //先出来的为b
int a = OPND.top(); OPND.pop();
char ch = OPTR.top(); OPTR.pop();
if (ch == '+') OPND.push((a + b));
if (ch == '-') OPND.push(a - b);
if (ch == '*') OPND.push(a * b);
if (ch == '/') OPND.push(a / b);
}
void evaluateExpression() {
char ch;
OPTR.push('\n');
scanf("%c", &ch);
//当字符不是换行就执行操作,当遇到换行将OPTR所有操作清空
ll num = 0; //要添加的数
while (ch != '\n' || OPTR.top() != '\n') {
if (ch >= '0' && ch <= '9') {
num = num * 10 + (ch - '0');
scanf("%c", &ch);
continue;
}
if (num) OPND.push(num), num = 0;
switch (compare(OPTR.top(), ch)) {
case '>':
//大于就弹出2个数和操作符进行运算
cal();
break;
case '<':
//小于那么就将次操作符入栈,并输入下一个字符
OPTR.push(ch); scanf("%c", &ch);
break;
case '=':
//等于代表括号匹配
OPTR.pop(); //弹出匹配括号
scanf("%c", &ch);
}
}
if (num) OPND.push(num);
cout << OPND.top() << endl;
}
int main() {
freopen("expr.in","r",stdin);
freopen("expr.out","w",stdout);
evaluateExpression();
return 0;
}
#include
using namespace std;
typedef struct BiTNode {
char data;
BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
//通过输入先序序列创建二叉树
void createBiTreeByPreOrder(BiTree &T) {
char c;
cin >> c;
if (c != '#') {
T = new BiTNode();
T->data = c;
createBiTreeByPreOrder(T->lchild);
createBiTreeByPreOrder(T->rchild);
} else {
T = NULL;
}
}
//对二叉树进行中序遍历
void inOrderTraverse(BiTree &T) {
if (!T) return;
inOrderTraverse(T->lchild);
cout << T->data;
inOrderTraverse(T->rchild);
}
//复制二叉树
void copyTree(BiTree &T, BiTree &tem) {
if (!T) {
tem = NULL;
return;
}
tem = new BiTNode();
tem->data = T->data;
copyTree(T->lchild, tem->lchild);
copyTree(T->rchild, tem->rchild);
}
//获取二叉树的深度
int getDepth(BiTree &T) {
if (!T) return 0;
int rdp = getDepth(T->lchild);
int ldp = getDepth(T->rchild);
return rdp > ldp ? rdp + 1 : ldp + 1;
}
//获取二叉树的结点个数
int getNodeCount(BiTree &T) {
if (!T) return 0;
return getNodeCount(T->lchild) + 1 + getNodeCount(T->rchild);
}
//获取度为0的结点个数
int getNodeCountN0(BiTree &T) {
if (!T) return 0;
if (T->lchild == NULL && T->rchild == NULL) return 1;
return getNodeCountN0(T->lchild) + getNodeCountN0(T->rchild);
}
//获取度为1的结点个数
int getNodeCountN1(BiTree &T) {
if (!T) return 0;
bool v = (T->lchild && !T->rchild) || (T->rchild && !T->lchild);
return getNodeCountN1(T->lchild) + getNodeCountN1(T->rchild) + (v ? 1 : 0);
}
//获取度为2的结点个数
int getNodeCountN2(BiTree &T) {
if (!T) return 0;
bool v = T->lchild && T->rchild;
return getNodeCountN2(T->lchild) + getNodeCountN2(T->rchild) + (v ? 1 : 0);
}
int main() {
//ABC##DE#G##F###
BiTree T, tem;
createBiTreeByPreOrder(T); //先序创建
inOrderTraverse(T); puts(""); //中序遍历
copyTree(T, tem);
inOrderTraverse(tem); puts("");
cout << getDepth(T) << endl; //获取深度
cout << getNodeCount(T) << endl; //获取结点总数
cout << getNodeCountN0(T) << endl; //获取度为0的结点
cout << getNodeCountN1(T) << endl;
cout << getNodeCountN2(T) << endl;
return 0;
}
Node *pre;
void inThread(Tree &p) {
if (p) {
inThread(p->lchild);
//若p->lchild为空,则保存前驱
if (p->lchild) {
p->lTag = 0; //代表不为空 保存孩子
} else {
p->lchild = pre;
p->lTag = 1;
}
//同理pre
if (pre->rchild) {
pre->rTag = 0;
} else {
pre->rchild = p;
pre->rTag = 1;
}
//pre变成p 成为新前驱
pre = p;
inThread(p->rchild);
}
}
//带头节点的线索二叉树
void inThread(Tree &Th, Tree &T) {
Th = new Node();
Th->lTag = 0; //左边指向树的根结点,若为空则指向自己
Th->rTag = 1; //右边指向最后一个结点,若T为空则指向自己
Th->rchild = Th;
if (!T) Th->lchild = Th;
else {
Th->lchild = T;
//初始应该为NULL
Th->rchild = NULL; pre = Th;
inThread(T);
pre->rchild = Th; pre->lTag = 1;
Th->rchild = pre; //pre这时候代表最后一个结点
}
}
//对中序线索二叉树进行遍历---带头节点
void inOrderThreadTraverseWithHead(Tree &Th) {
Node *p = Th->lchild; //最先指向根节点
while (p != Th) {
//转向p的最左结点即为第一个中序结点
while (p->lTag == 0) p = p->lchild;
cout << p->data;
//找p的后继 直接转向
while (p->rTag == 1 && p->rchild != Th) {
p = p->rchild;
cout << p->data;
}
//转向p的右子树
p = p->rchild;
}
}
//不带头节点
void inOrderThreadTraverseWithoutHead(Tree &T) {
Node *p = T;
while (p != NULL) {
while (p->lTag == 0) p = p->lchild;
cout << p->data;
while (p->rTag == 1 && p->rchild != NULL) {
p = p->rchild;
cout << p->data;
}
p = p->rchild;
}
}
#include
using namespace std;
typedef struct Node {
char data;
Node *lchild, *rchild;
int lTag, rTag; //0代表指针域存储孩子,1代表存储线索
} Node, *Tree;
//通过输入先序序列创建二叉树
void createBiTreeByPreOrder(Tree &T) {
char c;
cin >> c;
if (c != '#') {
T = new Node();
T->data = c;
createBiTreeByPreOrder(T->lchild);
createBiTreeByPreOrder(T->rchild);
} else {
T = NULL;
}
}
Node *pre;
void inThread(Tree &p) {
if (p) {
inThread(p->lchild);
//若p->lchild为空,则保存前驱
if (!p->lchild) {
p->lchild = pre;
p->lTag = 1;
} else {
p->lTag = 0; //代表不为空 保存孩子
}
//同理pre
if (!pre->rchild) {
pre->rchild = p;
pre->rTag = 1;
} else {
pre->rTag = 0;
}
//pre变成p 成为新前驱
pre = p;
inThread(p->rchild);
}
}
//带头节点的线索二叉树
void inThread(Tree &Th, Tree &T) {
Th = new Node();
Th->lTag = 0; //左边指向树的根结点,若为空则指向自己
Th->rTag = 1; //右边指向最后一个结点,若T为空则指向自己
Th->rchild = Th;
if (!T) Th->lchild = Th;
else {
Th->lchild = T;
//初始应该为NULL
Th->rchild = NULL; pre = Th;
inThread(T);
pre->rchild = Th; pre->lTag = 1;
Th->rchild = pre; //pre这时候代表最后一个结点
}
}
//对二叉树进行中序遍历
void inOrderTraverse(Tree &T) {
if (!T) return;
inOrderTraverse(T->lchild);
cout << T->data;
inOrderTraverse(T->rchild);
}
//对中序线索二叉树进行遍历---带头节点
void inOrderThreadTraverseWithHead(Tree &Th) {
Node *p = Th->lchild; //最先指向根节点
while (p != Th) {
//转向p的最左结点即为第一个中序结点
while (p->lTag == 0) p = p->lchild;
cout << p->data;
//找p的后继 直接转向
while (p->rTag == 1 && p->rchild != Th) {
p = p->rchild;
cout << p->data;
}
//转向p的右子树
p = p->rchild;
}
}
//不带头节点
void inOrderThreadTraverseWithoutHead(Tree &T) {
Node *p = T;
while (p != NULL) {
while (p->lTag == 0) p = p->lchild;
cout << p->data;
while (p->rTag == 1 && p->rchild != NULL) {
p = p->rchild;
cout << p->data;
}
p = p->rchild;
}
}
int main() {
Tree T, Th;
//-+a##*b##-c##d##/e##f##
createBiTreeByPreOrder(T);
inOrderTraverse(T); puts("");
// pre = new Node(); pre->rchild = NULL;
// inThread(T);
// inOrderThreadTraverseWithoutHead(T);
inThread(Th, T);
inOrderThreadTraverseWithHead(Th);
return 0;
}
#include
const int INF = 0x3f3f3f3f;
using namespace std;
typedef struct Node {
int w, lchild, rchild, parent;
}Node, *HuffmanTree;
void selectMin(HuffmanTree &T, int n, int &l, int &r) {
int w1 = INF, w2 = INF;
for (int i = 1; i <= n; i++) {
if (!T[i].parent) {
if (T[i].w < w1) {
w2 = w1; r = l;
w1 = T[i].w; l = i;
} else if(T[i].w < w2) {
w2 = T[i].w; r = i;
}
}
}
}
void createHuffmanTree(HuffmanTree &T, int n) {
//初始化条件
int m = 2 * n - 1; //有2n-1个结点
T = new Node[m + 1];
for (int i = 1; i <= m; i++) {
T[i].lchild = T[i].rchild = T[i].parent = 0;
}
for (int i = 1; i <= n; i++) cin >> T[i].w;
//构造哈夫曼树
int l, r; //代表选择的2个权值最小的根节点编号
for (int i = n + 1; i <= m; i++) {
//选择根结点权值最少且无双亲的
selectMin(T, i - 1, l, r);
T[i].lchild = l, T[i].rchild = r;
T[l].parent = T[r].parent = i;
T[i].w = T[l].w + T[r].w;
cout << l <<":"<<T[l].w <<"===" << r <<":" << T[r].w<<endl;
}
}
int main() {
//5 29 7 8 14 23 3 11
HuffmanTree T;
createHuffmanTree(T, 8);
for (int i = 8; i <= 15; i++) {
cout << T[i].w << " ";
}
return 0;
}
#include
const int INF = 0x3f3f3f3f;
using namespace std;
typedef struct Node {
int w, lchild, rchild, parent;
}Node, *HuffmanTree;
void selectMin(HuffmanTree &T, int n, int &l, int &r) {
int w1 = INF, w2 = INF;
for (int i = 1; i <= n; i++) {
if (!T[i].parent) {
if (T[i].w < w1) {
w2 = w1; r = l;
w1 = T[i].w; l = i;
} else if(T[i].w < w2) {
w2 = T[i].w; r = i;
}
}
}
}
void createHuffmanTree(HuffmanTree &T, int n) {
//初始化条件
int m = 2 * n - 1; //有2n-1个结点
T = new Node[m + 1];
for (int i = 1; i <= m; i++) {
T[i].lchild = T[i].rchild = T[i].parent = 0;
}
for (int i = 1; i <= n; i++) cin >> T[i].w;
//构造哈夫曼树
int l, r; //代表选择的2个权值最小的根节点编号
for (int i = n + 1; i <= m; i++) {
//选择根结点权值最少且无双亲的
selectMin(T, i - 1, l, r);
T[i].lchild = l, T[i].rchild = r;
T[l].parent = T[r].parent = i;
T[i].w = T[l].w + T[r].w;
}
}
string *HC; //用来保存每个编码的字符串
void createHuffmanCode(HuffmanTree &T, int n) {
HC = new string[n + 1]; //每个下标从1开始
//从每个根结点出发
for (int i = 1; i <= n; i++) {
int f = T[i].parent; //双亲
int s = i; //当前结点编号
while (f != 0) { //哈夫曼树的根结点无双亲
if (T[f].lchild == s) {
HC[i].insert(0, "0"); //是左边分支 编码为0
} else {
HC[i].insert(0, "1");
}
s = f; f = T[s].parent; //继续往上
}
}
}
string encode(string prestr) {
string enc;
for (int i = 0; i < prestr.length(); i++) {
enc.append(HC[prestr[i] - 'a' + 1]);
}
return enc;
}
string str = "*abcdefgh"; //代表输入的字符
string decode(HuffmanTree &T, string enc) {
string dec;
int m = 15;
int s = m; //根节点编号
for (int i = 0; i < enc.length(); i++) {
if (T[s].lchild == 0 && T[s].rchild == 0) {
dec += str[s];
s = m;
}
if (enc[i] == '0') {
s = T[s].lchild;
} else s = T[s].rchild;
}
return dec;
}
int main() {
//5 29 7 8 14 23 3 11
//a b c d e f g h 代表每个根结点代表的字符
HuffmanTree T;
createHuffmanTree(T, 8);
for (int i = 9; i <= 15; i++) {
cout << T[i].w << " " << T[i].parent << endl;
}
createHuffmanCode(T, 8);
//输出每个根结点的编码
for (int i = 1; i <= 8; i++) {
cout << str[i] << "-" << T[i].w << ":" << HC[i] << endl;
}
//编码
cout << "编码:" << encode("aabbccddeeffgghh") << endl;
//解码
cout << "解码:" << decode(T, encode("aabbccddeeffgghh")) << endl;
return 0;
}
#include
#include
using namespace std;
typedef struct Node {
char ch;
Node *lchild, *rchild;
}Node, *Tree;
char prt[7][8] = {
{">><<<>>"},
{">><<<>>"},
{">>>><>>"},
{">>>><>>"},
{"<<<<<=>"},
{">>>>=>>"},
{"<<<<<<="}
};
char id[8] = {"+-*/()#"};
char compare(char lop, char rop) {
int ld, rd;
for (int i = 0; i < 7; i++) if (id[i] == lop) {ld = i; break;}
for (int i = 0; i < 7; i++) if (id[i] == rop) {rd = i; break;}
return prt[ld][rd];
}
//创建表达式树保存在T中
void creatExpTree(Tree &T) {
stack<Tree> EXPT;
stack<char> OPTR;
OPTR.push('#');
char ch;
cin >> ch;
while (ch != '#' || OPTR.top() != '#') {
if (ch >= '0' && ch <= '9') {
Tree root = new Node(); root->lchild = root->lchild = NULL;
root->ch = ch;
EXPT.push(root);
cin >> ch;
continue;
}
switch (compare(OPTR.top(), ch)) {
case '<':
//直接将这个字符压入OPTR
OPTR.push(ch); cin >> ch;
break;
case '>':
//弹出2个树进行合并
Tree rt, lt, root;
rt = EXPT.top(); EXPT.pop();
lt = EXPT.top(); EXPT.pop();
root = new Node(); root->ch = OPTR.top(); OPTR.pop();
root->lchild = lt; root->rchild = rt;
EXPT.push(root);
break;
case '=':
OPTR.pop(); cin >> ch;
break;
}
}
//最后栈顶的就是形成的表达式树
T = EXPT.top();
}
void inOrederTraverse(Tree &T) {
if (T == NULL) return;
inOrederTraverse(T->lchild);
cout << T->ch;
inOrederTraverse(T->rchild);
}
int expValue(Tree &T) {
if (!T->lchild && !T->rchild) return (T->ch - '0');
int a = expValue(T->lchild);
int b = expValue(T->rchild);
switch (T->ch) {
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
return a / b;
}
}
int main() {
//(3+2)+(1)+4*(5-2)-8/4
Tree T;
creatExpTree(T);
inOrederTraverse(T);
cout << endl << expValue(T) << endl;
return 0;
}