二叉树的存储方式分为顺序存储和链式存储方式
顺序存储方式只能存储完全二叉树,也可以通过将普通二叉树补全转换为完全二叉树来存储
二叉树的链式存储方式
结点由三部分构成,左孩子,右孩子,值
typedef struct bitree
{
int val;
struct bitree* leftchild;
struct bitree* rightchild;
};
初始化
bitree* inittree()
{
bitree* bt = (bitree*)malloc(sizeof(bitree));
bt->val = 1;
bitree* bt2 = (bitree*)malloc(sizeof(bitree));
bt2->val = 2;
bitree* bt3 = (bitree*)malloc(sizeof(bitree));
bt3->val = 3;
bt->leftchild = bt2;
bt->rightchild = bt3;
bitree* bt4 = (bitree*)malloc(sizeof(bitree));
bt4->val = 4;
bitree* bt5 = (bitree*)malloc(sizeof(bitree));
bt5->val = 5;
bt2->leftchild = bt4;
bt2->rightchild = bt5;
bt4->leftchild = NULL;
bt4->rightchild = NULL;
bt5->leftchild = NULL;
bt5->rightchild = NULL;
bitree* bt6 = (bitree*)malloc(sizeof(bitree));
bt6->val = 6;
bitree* bt7 = (bitree*)malloc(sizeof(bitree));
bt7->val = 7;
bt3->leftchild = bt6;
bt3->rightchild = bt7;
bt6->leftchild = NULL;
bt6->rightchild = NULL;
bt7->leftchild = NULL;
bt7->rightchild = NULL;
return bt;
}
先序遍历
void printnode(bitree* bt)
{
cout << bt->val << " ";
}
void frontbl(bitree* bt)
{
if (bt == NULL)
{
return;
}
printnode(bt);
frontbl(bt->leftchild);
frontbl(bt->rightchild);
}
中序遍历
void middlebl(bitree* bt)
{
if (bt == NULL)
{
return;
}
middlebl(bt->leftchild);
printnode(bt);
middlebl(bt->rightchild);
}
后序遍历
void lastbl(bitree* bt)
{
if (bt == NULL)
{
return;
}
lastbl(bt->leftchild);
lastbl(bt->rightchild);
printnode(bt);
}
层次遍历
void ccbl1(bitree* bt1, bitree* bt2)
{
if (bt1 == NULL || bt2 == NULL)
{
return;
}
printnode(bt1);
printnode(bt2);
ccbl1(bt1->leftchild, bt1->rightchild);
ccbl1(bt2->leftchild, bt2->rightchild);
}
void ccbl(bitree* bt)
{
printnode(bt);
ccbl1(bt->leftchild, bt->rightchild);
}
线索二叉树
typedef struct xsbitree
{
struct xsbitree* leftchild;
struct xsbitree* rightchild;
int val;
int ltag;
int rtag;
};
通过中序遍历构建线索二叉树
void middle(xsbitree* p,xsbitree* pre)
{
if (p == NULL)
{
return;
}
middle(p->leftchild, pre);
if (p->leftchild == NULL)
{
p->leftchild = pre;
p->ltag = 1;
}
if (pre->leftchild != NULL && pre->rightchild == NULL)
{
pre->rightchild = p;
pre->rtag = 1;
}
pre = p;
middle(p->rightchild, pre);
}
void mxstree(xsbitree* bt)
{
xsbitree* pre = NULL;
middle(bt, pre);
pre->rightchild = NULL;
pre->rtag = 1;
}
普通二叉树三种表示方法
双亲表示法
#define max_size 100
typedef struct pnode
{
int val;
int parent;
};
typedef struct ptree
{
pnode* node[max_size];
int num;
};
初始化
ptree* initptree()
{
ptree* pt = (ptree*)malloc(sizeof(ptree));
pt->num = 7;
pt->node[0] = (pnode*)malloc(sizeof(pnode));
pt->node[0]->val = 0;
pt->node[0]->parent = -1;
pt->node[1] = (pnode*)malloc(sizeof(pnode));
pt->node[1]->val = 1;
pt->node[1]->parent = 0;
pt->node[2] = (pnode*)malloc(sizeof(pnode));
pt->node[2]->val = 2;
pt->node[2]->parent = 0;
pt->node[3] = (pnode*)malloc(sizeof(pnode));
pt->node[3]->val = 3;
pt->node[3]->parent = 0;
pt->node[4] = (pnode*)malloc(sizeof(pnode));
pt->node[4]->val = 4;
pt->node[4]->parent = 2;
pt->node[5] = (pnode*)malloc(sizeof(pnode));
pt->node[5]->val = 5;
pt->node[5]->parent = 2;
pt->node[6] = (pnode*)malloc(sizeof(pnode));
pt->node[6]->val = 6;
pt->node[6]->parent = 3;
return pt;
}
查找元素
void findnode(ptree* pt, int val)
{
for (int i = 0; i < pt->num; i++)
{
if (val == pt->node[i]->val)
{
cout << "父节点:" << pt->node[pt->node[i]->parent]->val << "存储下标" << pt->node[i]->parent << endl;
}
}
}
孩子节点法
//孩子结点表示法
typedef struct cnode
{
int loc;
struct cnode* child;
};
typedef struct chead
{
int val;
cnode* chead;
};
typedef struct ctree
{
chead* head[max_size];
int num;
};
初始化
ctree* initctree()
{
ctree* c = (ctree*)malloc(sizeof(ctree));
c->head[0] = (chead*)malloc(sizeof(chead));
c->head[0]->chead = (cnode*)malloc(sizeof(cnode));
c->head[0]->val = 0;
cnode* c1 = (cnode*)malloc(sizeof(cnode));
c1->loc = 1;
c->head[0]->chead = c1;
cnode* c2 = (cnode*)malloc(sizeof(cnode));
c2->loc = 2;
c1->child = c2;
cnode* c3 = (cnode*)malloc(sizeof(cnode));
c3->loc = 3;
c3->child = NULL;
c2->child = c3;
c->head[1] = (chead*)malloc(sizeof(chead));
c->head[1]->chead = (cnode*)malloc(sizeof(cnode));
c->head[1]->val = 1;
cnode* c4 = (cnode*)malloc(sizeof(cnode));
c4->loc = 4;
c->head[1]->chead = c4;
cnode* c5 = (cnode*)malloc(sizeof(cnode));
c5->loc = 5;
c4->child = c5;
c5->child = NULL;
c->head[2] = (chead*)malloc(sizeof(chead));
c->head[2]->chead = (cnode*)malloc(sizeof(cnode));
c->head[2]->chead->child = NULL;
c->head[2]->val = 2;
c->head[3] = (chead*)malloc(sizeof(chead));
c->head[3]->chead = (cnode*)malloc(sizeof(cnode));
c->head[3]->chead->child = NULL;
c->head[3]->val = 3;
c->head[4] = (chead*)malloc(sizeof(chead));
c->head[4]->chead = (cnode*)malloc(sizeof(cnode));
c->head[4]->chead->child = NULL;
c->head[4]->val = 4;
c->head[5] = (chead*)malloc(sizeof(chead));
c->head[5]->chead = (cnode*)malloc(sizeof(cnode));
c->head[5]->chead->child = NULL;
c->head[5]->val = 5;
return c;
}
孩子兄弟表示法
将普通树转换为二叉树的表示方法
typedef struct cbtree
{
cbtree* child;
cbtree* brother;
int val;
};
将普通树转换为二叉树
cbtree* bl(int val, cbtree* cb)
{
if (!cb) return NULL;
if (val == cb->val) return cb;
return bl(val,cb->child) != NULL ? bl(val,cb->child) : bl(val,cb->brother);
}
cbtree* changtobitree(ptree* p)
{
cbtree* cb = (cbtree*)malloc(sizeof(cbtree));
cb->val = p->node[0]->val;
cb->brother = NULL;
cb->child = NULL;
for (int i = 1; i < p->num; i++)
{
cbtree* temp = cb;
cbtree* cb1 = (cbtree*)malloc(sizeof(cbtree));
cb1->val = p->node[i]->val;
cb1->brother = NULL;
cb1->child = NULL;
temp = bl(p->node[i]->parent, temp);
//cout << temp->val << endl;
if (temp->child == NULL)
{
temp->child = cb1;
}
else
{
temp = temp->child;
while (temp->brother != NULL)
{
temp = temp->brother;
}
temp->brother = cb1;
}
}
return cb;
}