孩子兄弟表示法
孩子兄弟链存储结构的类型声明
typedef struct CSNode
{
ElemType data;
struct CSNode *firstchild,*nextsibling;
}CSNode,*CSTree;
- 孩子兄弟链存储结构是为每个结点设计3个域。即一个数据元素域、一个指向该结点的左边第一个孩子结点(长子)的指针域、一个指向该结点的下一个兄弟结点的指针域。由于树的孩子兄弟链存储结构固定有两个指针域,并且这两个指针是有序的(即兄弟域和孩子域不能混淆),所以孩子兄弟链存储结构实际上是把该树转换为二又树的存储结构。
- 优点:可方便地实现树和二又树的相互转换。
- 缺点:从当前结点查找双亲结点比较麻烦,需要从树的根结点开始逐个结点比较查找。
代码实现
#include<stdio.h>
#include<malloc.h>
typedef char ElemType;
#define MaxSize 15
typedef struct CSNode
{
ElemType data;
struct CSNode* firstchild, * nextsibling;
}CSNode, * CSTree;
typedef struct
{
CSNode* data[MaxSize];
int top;
}SqStack;
void InitStack(SqStack*& s)
{
s = (SqStack*)malloc(sizeof(SqStack));
if (s == NULL) printf("内存分配不成功!\n");
s->top = -1;
}
bool EmptyStack(SqStack* s)
{
return s->top == -1;
}
bool Push(SqStack*& st, CSNode*b)
{
if (st->top == MaxSize - 1) return false;
st->data[++st->top] = b;
return true;
}
bool Pop(SqStack*& st, CSNode*&b)
{
if (st->top == -1) return false;
b = st->data[st->top--];
return true;
}
bool GetTop(SqStack* st, CSNode*&b)
{
if (st->top == -1) return false;
b = st->data[st->top];
return true;
}
void DestroyStack(SqStack*& s)
{
free(s);
}
void InitCSTree(CSTree t)
{
t = NULL;
}
void ClearCSTree(CSTree t)
{
if (t)
{
if (t->firstchild) ClearCSTree(t->firstchild);
if (t->nextsibling) ClearCSTree(t->nextsibling);
free(t);
t = NULL;
}
}
void DestoryCSTree(CSTree t)
{
}
bool EmptyCSTree(CSTree t)
{
return t == NULL;
}
bool CreateCSTree(CSTree &t)
{
char ch;
scanf("%c", &ch);
if (ch == '#') t = NULL;
else
{
t = (CSNode*)malloc(sizeof(CSNode));
if (t == NULL) return false;
t->data = ch;
CreateCSTree(t->firstchild);
CreateCSTree(t->nextsibling);
}
return true;
}
int CSTreeDegree(CSTree t)
{
int i = 0, j = 0, max = -1, temp;
CSTree Q[100];
if (t != NULL)
{
max = 0;
Q[j++] = t->firstchild;
while (i < j)
{
temp = 0;
while (Q[i])
{
temp++;
if (Q[i]->firstchild) Q[j++] = Q[i]->firstchild;
Q[i] = Q[i]->nextsibling;
}
if (temp > max) max = temp;
i++;
}
}
return max;
}
int CSTreeDepth(CSTree t)
{
int row = 0, max;
SqStack *st;
CSTree temp;
if (t != NULL)
{
InitStack(st);
Push(st, t);
row = max = 1;
while (!EmptyStack(st))
{
GetTop(st, temp);
while (temp->firstchild)
{
Push(st, temp->firstchild);
max++;
if (row < max) row = max;
GetTop(st, temp);
}
Pop(st, temp);
if (temp->nextsibling) Push(st, temp->nextsibling);
else
{
while (!EmptyStack(st))
{
Pop(st, temp);
max--;
if (temp->nextsibling)
{
Push(st, temp->nextsibling);
break;
}
}
}
}
}
return row;
}
ElemType CSRoot(CSTree t)
{
if (t != NULL) return t->data;
else return '\0';
}
ElemType CSTreeValue(CSTree t, int i)
{
int j = 0, k= 0, count = 0;
CSTree Q[100];
if (t != NULL && i > 0)
{
Q[k++] = t;
while (j < k)
{
while (Q[j])
{
count++;
if (count == i) return Q[j]->data;
if (Q[j]->firstchild) Q[k++] = Q[j]->firstchild;
Q[j] = Q[j]->nextsibling;
}
}
j++;
}
return '\0';
}
CSTree OrderCS(CSTree t, ElemType e)
{
int i = 0, j = 0, count = 0;
CSTree Q[100];
if (t != NULL)
{
Q[j++] = t;
while (i < j)
{
while (Q[i] && Q[i]->data != e)
{
if (Q[i]->firstchild) Q[j++] = Q[i]->firstchild;
Q[i] = Q[i]->nextsibling;
}
if (Q[i] && Q[i]->data == e) return Q[i];
i++;
}
}
return NULL;
}
bool CSAssign(CSTree t, ElemType e, ElemType value)
{
CSNode* p = OrderCS(t, e);
if (p != NULL)
{
p->data = value;
return true;
}
return false;
}
ElemType CSChildValue(CSTree t, ElemType e, int order)
{
int i = 0, j = 0, count = -1;
CSTree Q[100];
if (t != NULL)
{
Q[j++] = t;
while (i < j)
{
while (Q[i] && Q[i]->data != e)
{
if (Q[i]->firstchild) Q[j++] = Q[i]->firstchild;
Q[i] = Q[i]->nextsibling;
}
if (Q[i] && Q[i]->data == e) break;
i++;
}
if (i < j)
{
count = 0;
if (Q[i]->firstchild)
{
Q[i] = Q[i]->firstchild;
while (Q[i])
{
count++;
if (count == order) return Q[i]->data;
Q[i] = Q[i]->nextsibling;
}
}
}
}
return '\0';
}
ElemType SiblingCS(CSTree t, ElemType e, int mark)
{
int i = 0, j = 0, m = 0, n = 0;
CSTree Q[100];
ElemType key[100] = {};
if (t != NULL && t->data != e)
{
Q[j++] = t;
key[n++] = t->data;
while (i < j)
{
while (Q[i])
{
if (Q[i]->firstchild)
{
Q[j++] = Q[i]->firstchild;
key[n++] = Q[i]->firstchild->data;
}
if (mark == 0)
{
if (Q[i]->data == e && Q[i]->data == key[m]) return '\0';
if (Q[i]->nextsibling && Q[i]->nextsibling->data == e) return Q[i]->data;
}
else
{
if (Q[i]->data == e && Q[i]->nextsibling) return Q[i]->nextsibling->data;
}
Q[i] = Q[i]->nextsibling;
}
i++;
m++;
}
}
return '\0';
}
CSNode* CSChildSeat(CSTree t, ElemType e, int i)
{
ElemType temp;
CSNode* p = NULL;
temp = CSChildValue(t, e, i);
if (temp) p = OrderCS(t, temp);
return p;
}
int ChildCount(CSTree t, ElemType p)
{
int i = 0, j = 0, count = -1;
CSTree Q[100];
if (t)
{
Q[j++] = t;
while (i < j)
{
while (Q[i] && Q[i]->data != p)
{
if (Q[i]->firstchild) Q[j++] = Q[i]->firstchild;
Q[i] = Q[i]->nextsibling;
}
if (Q[i] && Q[i]->data == p) break;
i++;
}
if (i < j)
{
count = 0;
if (Q[i]->firstchild)
{
Q[i] = Q[i]->firstchild;
while (Q[i])
{
count++;
Q[i] = Q[i]->nextsibling;
}
}
}
}
return count;
}
bool InsertCSTree(CSTree T, ElemType e, int i, CSTree t)
{
int j, k0;
CSNode* p, * q;
k0 = ChildCount(t, e);
if (k0 < 0 || i<0 || i>k0 + 1) return false;
if (i == 0) j = k0 + 1;
else j = i;
if (j == 1)
{
p = OrderCS(t, e);
t->nextsibling = p->firstchild;
p->firstchild = t;
}
else {
q = CSChildSeat(t, e, j - 1);
t->nextsibling = q->nextsibling;
q->nextsibling = t;
}
return true;
}
bool DeleteCSTree(CSTree t, ElemType e, int i)
{
ElemType tmp;
CSNode *p, *q;
if (i == 1)
{
p = OrderCS(t, e);
if (!p) return false;
q = p->firstchild->nextsibling;
p->firstchild->nextsibling = NULL;
ClearCSTree(p->firstchild);
p->firstchild = q;
}
else
{
p = CSChildSeat(t, e, i - 1);
if (!p) return false;
q = p->nextsibling->nextsibling;
p->nextsibling->nextsibling = NULL;
ClearCSTree(p->nextsibling);
p->nextsibling = q;
}
return true;
}
void LevelOrder(CSTree t)
{
int i = 0, j = 0;
CSTree Q[100];
if (t) Q[j++] = t;
while (i < j)
{
while (Q[i])
{
printf("%c ", Q[i]->data);
if (Q[i]->firstchild) Q[j++] = Q[i]->firstchild;
Q[i] = Q[i]->nextsibling;
}
i++;
}
}
void PreOrder(CSTree t)
{
if (t)
{
printf("%c ", t->data);
PreOrder(t->firstchild);
PreOrder(t->nextsibling);
}
}
void InOrder(CSTree t)
{
if (t)
{
InOrder(t->firstchild);
printf("%c ", t->data);
InOrder(t->nextsibling);
}
}
int main()
{
CSNode* t = NULL;
InitCSTree(t);
printf("输入:");
CreateCSTree(t);
printf("\n前序遍历树:");
PreOrder(t);
printf("\n中序遍历树:");
InOrder(t);
printf("\n层次遍历树:");
LevelOrder(t);
printf("\n树的根结点为:%c", CSRoot(t));
printf("\n树的度为:%d", CSTreeDegree(t));
printf("\n树共有:%d层", CSTreeDepth(t));
return 0;
}
运行结果