数据结构之树

来源:互联网 发布:各专业软件大全 编辑:程序博客网 时间:2024/06/05 17:43

//对树的一些基本操作应按照处理森林的思想去理解,树是只有一棵树的森林#include<iostream>#include<malloc.h>using namespace std;#define QSIZE 20typedef char ElemType;typedef struct CSNode{ElemType data;CSNode *pFchild;CSNode *pNsibling;}CSNode, *CSTree;typedef struct Queue{CSTree *pBase;int Front;int Rear;}Queue;void InitQueue(Queue &Q){Q.pBase = new CSTree[QSIZE];Q.Front = 0;Q.Rear = 0;}void DestroyQueue(Queue &Q){delete[]Q.pBase;Q.Front = 0;Q.Rear = 0;}void ClearQueue(Queue &Q){Q.Front = 0;Q.Rear = 0;}bool QueueFull(Queue Q){if ((Q.Rear + 1) % QSIZE == Q.Front)return true;elsereturn false;}bool QueueEmpty(Queue Q){if (Q.Front == Q.Rear)return true;elsereturn false;}bool EnQueue(Queue &Q, CSTree e){if (QueueFull(Q))return false;else{Q.pBase[Q.Rear] = e;Q.Rear = (Q.Rear + 1) % QSIZE;return true;}}bool DeQueue(Queue &Q, CSTree &e){if (QueueEmpty(Q))return false;else{e = Q.pBase[Q.Front];Q.Front = (Q.Front + 1) % QSIZE;return true;}}bool GetHead(Queue Q, CSTree &e){if (QueueEmpty(Q))return false;else{e = Q.pBase[Q.Front];return true;}}#define STACKSIZE 10#define SIZEADD 5typedef CSTree SElemType;typedef struct Stack{SElemType *pBase;SElemType *pTop;int Stacksize;}Stack;void InitStack(Stack &S){S.pBase = new SElemType[STACKSIZE];S.pTop = S.pBase;S.Stacksize = STACKSIZE;}void DestroyStack(Stack &S){delete[]S.pBase;S.pBase = NULL;S.pTop = NULL;S.Stacksize = 0;}void ClearStack(Stack &S){S.pTop = S.pBase;}bool StackEmpty(Stack S){if (S.pBase == S.pTop)return true;elsereturn false;}int StackLength(Stack S){return S.pTop - S.pBase;}void VisitS(SElemType e){cout << e->data << " ";}void Push(Stack &S, SElemType e){if (S.pTop - S.pBase >= S.Stacksize){S.pBase = (SElemType *)realloc(S.pBase, (SIZEADD + STACKSIZE)*sizeof(SElemType));S.pTop = S.pBase + S.Stacksize;S.Stacksize += SIZEADD;}*S.pTop++ = e;}bool Pop(Stack &S){if (StackEmpty(S))return false;--S.pTop;return true;}bool GetTop(Stack S, SElemType &e){if (StackEmpty(S))return false;else{e = *(S.pTop - 1);return true;}}void StackDePrint(Stack S){SElemType *p = S.pTop;if (StackEmpty(S))return;while (p>S.pBase){--p;VisitS(*p);}cout << endl;}void StackAsPrint(Stack S){SElemType *p = S.pBase;if (StackEmpty(S))return;while (p < S.pTop){VisitS(*p);++p;}cout << endl;}void InitTree(CSTree &T){T = NULL;}void CreateTree(CSTree &T){ElemType array[20];CSTree p, p1;Queue Q;int i, l;InitQueue(Q);printf("请输入根结点(字符型,空格为空): ");cin >> array[0];if (array[0])// 非空树{T = new CSNode;// 建立根结点T->data = array[0];T->pNsibling = NULL;//只是一棵树EnQueue(Q, T);while (!QueueEmpty(Q)){DeQueue(Q, p);printf("请按长幼顺序输入结点%c的所有孩子: ", p->data);gets_s(array);l = strlen(array);if (l > 0){p->pFchild = new CSNode; // 建立长子结点p1 = p->pFchild;p1->data = array[0];for (i = 1; i < l; ++i){p1->pNsibling = new CSNode;// 建立下一个兄弟结点EnQueue(Q, p1);p1 = p1->pNsibling;p1->data = array[i];}p1->pNsibling = NULL;//最后一个兄弟}elsep->pFchild = NULL;}}elseT = NULL;}void DestroyTree(CSTree &T){if (T){if (T->pFchild)DestroyTree(T->pFchild);if (T->pNsibling)DestroyTree(T->pNsibling);delete T;T = NULL;}}#define ClearTree DestroyTreebool TreeEmpty(CSTree T){if (T)return false;elsereturn true;}int TreeDepth(CSTree T){CSTree p;int depth, max = 0;if (!T)return 0;else if (!(T->pFchild))return 1;else{for (p = T->pFchild; p; p = p->pNsibling){depth = TreeDepth(p);if (depth > max)max = depth;}return max + 1;}}ElemType Value(CSTree p){return p->data;}void VisitT(ElemType e){cout << e;}ElemType Root(CSTree T){if (T)return Value(T);elsereturn NULL;}CSTree GetPoint(CSTree T, ElemType e){Queue Q;CSTree p;InitQueue(Q);if (T){EnQueue(Q, T);while (!QueueEmpty(Q)){DeQueue(Q, p);if (p->data == e)return p;if (p->pFchild)EnQueue(Q, p->pFchild);if (p->pNsibling)EnQueue(Q, p->pNsibling);}}return NULL;}bool Assign(CSTree &T, ElemType cur, ElemType e){CSTree p;if (T){p = GetPoint(T, cur);if (p){p->data = e;return true;}}return false;}CSTree GetParent(CSTree T, ElemType e){CSTree p, t;Queue Q;InitQueue(Q);if (T){if (Value(T) == e)//先处理根节点return NULL;EnQueue(Q, T);while (!QueueEmpty(Q)){DeQueue(Q, p);if (p->pFchild){if (p->pFchild->data == e)//再处理根节点第一个孩子return p;t = p;p = p->pFchild;EnQueue(Q, p);while (p->pNsibling)//最后处理根节点的其他孩子(除长子){p = p->pNsibling;if (Value(p) == e)return t;EnQueue(Q, p);}}}}}CSTree GetLeftChild(CSTree T, ElemType e){CSTree f;f = GetPoint(T, e);if (f && f->pFchild)return f->pFchild;elsereturn NULL;}CSTree GetRightSibling(CSTree T, ElemType e){//只处理相邻的第一个兄弟CSTree f;f = GetPoint(T, e);if (f&&f->pNsibling)return f->pNsibling;elsereturn NULL;}bool InsertChild(CSTree &T, CSTree p, int i, CSTree c){ // 初始条件: 树T存在,p指向T中某个结点,1≤i≤p所指结点的度+1,非空树c与T不相交// 操作结果: 插入c为T中p结点的第i棵子树// 因为p所指结点的地址不会改变,故p不需是引用类型int j;if (T) // T不空{if (i == 1) // 插入c为p的长子{c->pNsibling = p->pFchild; // p的原长子现是c的下一个兄弟(c本无兄弟)p->pFchild = c;}else // 找插入点{p = p->pFchild; // 指向p的长子j = 2;while (p&&j<i){p = p->pNsibling;++j;}if (j == i) // 找到插入位置{c->pNsibling = p->pNsibling;p->pNsibling = c;//c做p的相邻右兄弟}else // p原有孩子数小于i-1return false;}return true;}else // T空return false;}bool DeleteChild(CSTree &T, CSTree p, int i){ // 初始条件: 树T存在,p指向T中某个结点,1≤i≤p所指结点的度// 操作结果: 删除T中p所指结点的第i棵子树// 因为p所指结点的地址不会改变,故p不需是引用类型CSTree b;int j;if (T) // T不空{if (i == 1) // 删除长子{b = p->pFchild;p->pFchild = b->pNsibling; // p的原次子现是长子b->pNsibling = NULL;//断绝长子与次子的关系DestroyTree(b);}else // 删除非长子{p = p->pFchild; // p指向长子j = 2;while (p&&j<i){p = p->pNsibling;++j;}if (j == i) // 找到第i棵子树{b = p->pNsibling;p->pNsibling = b->pNsibling;//p的右兄弟更新为b的右兄弟b->pNsibling = NULL;//断绝待删除孩子和紧挨该孩子的右兄弟的关系DestroyTree(b);}else // p原有孩子数小于ireturn false;}return true;}elsereturn false;}void PreOrder(CSTree T){//树先根遍历(森林先序遍历)if (T){//按照森林先序遍历思想理解VisitT(Value(T));PreOrder(T->pFchild);PreOrder(T->pNsibling);}}void PostOrderPrint(CSTree T){ // 后根遍历孩子-兄弟二叉链表结构的树TCSTree p;if (T){if (T->pFchild)// 有长子{PostOrderPrint(T->pFchild);// 后根遍历长子子树(处理长子)p = T->pFchild->pNsibling; // p指向长子的下一个兄弟while (p){//处理长子的所有兄弟也就是处理根除了长子之外的所有儿子PostOrderPrint(p);// 后根遍历下一个兄弟子树p = p->pNsibling;// p指向再下一个兄弟}}VisitT(Value(T)); // 最后访问根结点}}void LevelOrderPrint(CSTree T){// 层序遍历孩子-兄弟二叉链表结构的树TCSTree p;Queue Q;InitQueue(Q);if (T){VisitT(Value(T));// 先访问根结点EnQueue(Q, T);// 入队根结点的指针while (!QueueEmpty(Q))// 队不空{DeQueue(Q, p); // 队头出队if (p->pFchild)// 有长子{p = p->pFchild;VisitT(Value(p));EnQueue(Q, p);while (p->pNsibling)//有下一个兄弟{p = p->pNsibling;VisitT(Value(p));// 访问下一个兄弟EnQueue(Q, p); // 入队兄弟结点的指针}}}}}void OutPathPrint(CSTree T, Stack &S){//森林思想while (!T)//每一次循环处理完一棵树;如果是树的话,只一次循环;如果是森林,有几棵树则循环几次{Push(S, T);//当前树的根结点入栈if (!T->pFchild)//如果当前结点无儿子,该结点必为叶子结点StackAsPrint(S);elseOutPathPrint(T->pFchild, S);//对其长子结点进行递归处理Pop(S);//长子结点出栈T = T->pNsibling;//寻找下一个兄弟(如果是树的话,且第一循环则根结点的右指针域为空,整个函数处理完毕)}}int main(void){Stack S;CSTree T;InitStack(S);InitTree(T);CreateTree(T);LevelOrderPrint(T);OutPathPrint(T, S);return(0);}

0 0
原创粉丝点击