数据结构伪C代码:6.树和二叉树
来源:互联网 发布:javascript文献书籍 编辑:程序博客网 时间:2024/05/16 19:00
//---------------二叉树的顺序链表表示----------------#define MAX_TREE_SIZE 100 //二叉树的最大结点数typedef TElemType SqBiTree[MAX_TREE_SIZE]; //0号单元存储根结点SqBiTree bt;//---------------二叉树的二叉链表存储表示------------typedef struct BiTNode{ TElemType data; struct BiTNode *lchild,*rchild; //左右孩子指针}BiTNode,*BiTree;//算法6.1status PreOrderTraverse(BiTree T,status (*visit)(TElemType e)){//采用二叉链表存储结构,visit是对数据元素操作的应用函数//先序遍历二叉树T的递归算法,对每个数据元素调用函数visit// status PrintElement(TElemType e){ //输出元素e的值// printf(e);// return ok;// } if(T){ if(visit(T->data)) if(PreOrderTraverse(T->lchild,visit)) if(PreOrderTraverse(T->rchild,visit)) return ok; return error; } else return ok;}//算法6.2status InOrderTraverse(BiTree T,status (*visit)(TElemType e)){//中序遍历二叉树T的非递归算法,对每个数据元素调用visit InitStack(S); Push(S,T); //根指针进栈 while(!StackEmpty(S)){ while(!GetTop(S,p)&&p) //向左走到尽头 Push(S,p->lchild); Pop(S,p); //空指针退栈 if(!StackEmpty(S)){ //访问结点,向右一步 Pop(S,p); if(!visit(p->data)) return error; Push(S,p->rchild); } } return ok;}//算法6.3status InOrderTraverse(BiTree T,status (*visit)(TElemType e)){//中序遍历二叉树T的非递归算法,对每个数据元素调用visit InitStack(S); p=T; while(p||!StackEmpty(S)){ if(p){ //根指针进栈,遍历左子树 Push(S,p); p=p->lchild; } else{ //根指针退栈,访问根结点,遍历右子树 Pop(S,p); if(!visit(p->data)) return error; p=p->rchild; } } return ok;}//算法6.4status CreateBiTree(BiTree &T){//按先序次序输入二叉树中结点的值(一个字符),空格字符表示空树//构造二叉链表表示的二叉树T scanf(&ch); if(ch==' ') T=NULL; else{ if(!(T=(BiTNode *)malloc(sizeof(BiTNode)))) exit (overflow); T->data=ch; //生成根节点 CreateBitTree(T->lchild); //构造左子树 CreateBitTree(T->rchild); //构造右子树 } return ok;}//------------------二叉树的二叉线索存储表示------------------typedef enum PointerTag{Link,Thread}; //Link==0: 指针,Thread==1: 线索typedef struct { TElemType data; struct BiThrNode *lchild,*rchild; //左右孩子指针 PointerTag LTag,RTag; //左右标志}BiThrNode,*BiThrTree;//算法6.5status InOrderTraverse_Thr(BiThrTree T,status(*visit)(TElemType e)){//T指向头结点,头结点的左链lchild指向根结点,可参见线索化算法//中序遍历二叉树T的非递归算法,对每个数据元素调用visit p=T->lchild; //p指向根结点 while(p!=T){ //空树或遍历结束时,p==T while(p->Ltag==Link) p=p->lchild; if(!visit(p->data)) return error; while(p->Rtag==Thread&&p->rchild!=T){ p=p->rchild; visit(p->data); } p=p->rchild; } return ok;}//算法6.6status InOrderThreading(BiThrTree &Thrt,BiThrTree T){//中序遍历二叉树T,并将其中序线索化,Thrt指向头结点 if(!(Thrt=(BiThrTree)malloc(sizeof(BiThrNode)))) exit(overflow); //建立头结点 Thrt->LTag=Link; Thrt->RTag=Thread; Thrt->rchild=Thrt; //右指针回指 if(!T) Thrt->lchild=Thrt; //若二叉树为空,则左指针回指 else{ Thrt->lchild=T; pre=Thrt; InThreading(T); //中序遍历进行中序线索化 //最后一个结点线索化 pre->rchild=Thrt; pre->RTag=Thread; // Thrt->rchild=pre; } return ok; }//算法6.7void InThreading(BiThrTree p){ if(p){ InThreading(p->lchild); //左子树线索化 if(!p->lchild){ //前驱线索 p->LTag=Thread; p->lchild=pre; } if(!pre->rchild){ //后继线索 pre->RTag=Thread; pre->rchild=p; } pre=p; //保持pre指向p的前驱 InThreading(p->rchild); //右子树线索化 }}//---------------树的双亲表存储表示-------------------#define MAX_TREE_SIZE 100typedef struct PTNode{ //结点结构 TElemType data; int parent; //双亲位置域}PTNode;typedef struct { //树结构 PTNode nodes[MAX_TREE_SIZE]; int r,n; //根的位置和结点数}PTree;//--------------树的孩子链表存储表示-------------------typedef struct CTNode{ //孩子结点 int child; struct CTNode *next;}*ChildPtr;typedef struct{ TElemType data; ChildPtr firstchild; //孩子链表头指针}CTBox;typedef struct{ CTBox nodes[MAX_TREE_SIZE]; int n,r; //结点数和根的位置}CTree;//------------树的二叉链表(孩子-兄弟)存储表示-----------typedef struct CSNode{ ElemType data; struct CSNode *firstchild,*nextsibling;}CSNode,*CSTree;//---------------ADT MFSet------------------------typedef PTree MFSet;//算法6.8int find_mfset(MFSet S,int i){//找集合S中i所在子集的根 if(i<1||i>S.n) return -1;//i不属于S中任一子集 for(j=i;S.nodes[j].parent>0;j=S.nodes[j].parent); return j;}//算法6.9status merge_mfset(MFSet &S,int i,int j){//S.nodes[i]和S.nodes[j]分别为S的互不相交的两个子集Si和Sj的根结点//求并集SiUSj if(i<1||i>S.n||j<1||j>S.n) return error; S.nodes[i].parent=j; return ok;}//算法6.10void mix_mfset(MFSet &S,int i,int j){//S.nodes[i]和S.nodes[j]分别为S的互不相交的两个子集Si和Sj的根结点//求并集SiUSjif(i<1||i>S.n||j<1||j>S.n) return error;if(S.nodes[i].parent>S.nodes[j].parent){ //Si所含成员数比Sj少 S.nodes[j].parent+=S.nodes[i].parent; S.nodes[i].parent=j;}else{ S.nodes[i].parent+=S.nodes[j].parent; S.nodes[j].parent=i;}return ok;}//算法6.11int fix_mfset(MFSet &S,int i){//确定i所在子集,并将从i至根路径上所有结点都变成根的孩子结点 if(i<1||i>S.n) return -1; //i不是S中任一子集的成员 for(j=i;S.nodes[j].parent>0;j=S.nodes[j].parent); for(k=i;k!=j;k=t){ t=S.nodes[k].parent; S.nodes[k].parent=j; } return j;}//------------------赫夫曼树和赫夫曼编码的存储表示-----------------typedef struct{ unsigned int weight; unsigned int parent,lchild,rchild;}HTNode,*HuffmanTree; //动态分配数组存储赫夫曼树typedef char **HuffmanCode; //动态分配数组存储赫夫曼编码表//算法6.12void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n){//w存放n个字符的权值(均>0),构造赫夫曼树HT,并求出n个字符的赫夫曼编码HC if(n<=1) return; m=2*n-1; HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));//0号单元未用 for(p=HT,i=1;i<=n;i++,p++,w++) *p={*w,0,0,0}; for(;i<=m;i++,p++) *p={0,0,0,0}; for(i=n+1;i<=n;i++){ //建赫夫曼树 //在HT[1...i-1]选择parent为0且weight最下的两个结点,其序号分别为s1和s2 Select(HT,i-1,s1,s2); HT[s1].parent=i; HT[s2].parent=i; HT[i].lchild=s1; HT[i].rchild=s2; HT[i].weight=HT[s1].weight+HT[s2].weight; } //--------从叶子到根逆向求每个字符的赫夫曼编码-------------------- HC=(HuffmanCode)malloc((n+1)*sizeof(char *));//分配n个字符编码的头指针向量 cd=(char *)malloc(n*sizeof(char)); //分配求编码的工作空间 cd[n-1]="\n"; //编码结束符 for(i=1;i<=n;i++){ //逐个字符求赫夫曼编码 start=n-1; //编码结束符位置 for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent) //从叶子到根逆向求编码 if(HT[f].lchild==c) cd[--start]="0"; else cd[--start]="1"; HC[i]=(char *)malloc((n-start)*sizeof(char)); //为第i个字符编码分配空间 strcpy(HC[i],&cd[start]); //从cd复制编码(串)到HC } free(cd); //释放工作空间}//算法6.13//-----------------无栈非递归遍历赫夫曼树,求赫夫曼编码--------------HC=(HuffmanCode)malloc((n+1)*sizeof(char *));p=m;cdlen=0;for(i=1;i<=m;i++) HT[i].weight=0; //遍历赫夫曼树时用作结点状态标志 while(p){ if(HT[p].weight==0){ //向左 HT[p].weight=1; if(HT[p].lchild!=0){ p=HT[p].lchild; cd[cdlen++]="0"; } else if(HT[p].rchild==0){//登记叶子结点的字符的编码 HC[p]=(char *)malloc((cdlen+1)*sizeof(char)); cd[cdlen]="\0"; strcpy(HC[p],cd); } } else if(HT[p].weight==1){ //向右 HT[p].weight=2; if(HT[p].rchild!=0){ p=HT[p].rchild; cd[cdlen++]="1"; } else{ //HT[p].weight==2,退回 HT[p].weight=0; p=HT[p].parent; cdlen--; //退到父结点,编码长度减1 } } }//算法6.14void PowerSet(int i,int n){//求含n个元素的集合A的幂集(A);进入函数时已对A重前i-1个元素做了取舍处理//现从第i个元素起进行取舍处理。若i>n,则求得幂集的一个元素,并输出之。//初始调用:PowerSet(1,n); if(i>n) 输出幂集的一个元素; else{ 取第i个元素; PowerSet(i+1,n); 舍第i个元素; PowerSet(i+1,n); }}//算法6.15void GetPowerSet(int i,List A,List &B){//线性表A表示集合A,线性表B表示幂集(A)的一个元素//局部量k为进入函数时表B的当前长度;第一次调用本函数时,B为空表,i=1 if(i>ListLength(A)) Output(B); //输出当前B值,即(A)的一个元素 else{ GetElem(A,i,x); k=ListLength(B); ListInsert(B,k+1,x); GetPowerSet(i+1,A,B); ListDelete(B,k+1,x); GetPowerSet(i+1,A,B); }}//算法6.16void Trial(int i,int n){//进入本函数时,在n*n棋盘前i-1行已放置了互不攻击的i-1个棋子//现从第i行起继续为后续棋子选择合适位置//当i>n时,求得一个合法布局,输出之 if(i>n) 输出棋盘的当前布局; //n为4时,即为4皇后问题 else for(j=1;j<=n;j++){ 在第i行第j列放置一个棋子; if(当前布局合法) Trial(i+1,n); 移走第i行第j列的棋子; }}
0 0
- 数据结构伪C代码:6.树和二叉树
- 数据结构伪C代码:栈和队列
- 《数据结构(C语言版)》- 树和二叉树
- 数据结构(C++)--二叉树
- 二叉树(数据结构 c++)
- 【数据结构】二叉树(c++)
- 数据结构伪C代码:5.数组和广义表
- 数据结构代码补全-C版-二叉树及其应用
- c语言-数据结构-二叉树-生成、遍历代码
- 数据结构---二叉树(C#)
- 数据结构-二叉树 链式 c
- C语言-数据结构-二叉树
- 数据结构--二叉树(C++)
- 数据结构伪C代码:2.线性表
- 数据结构伪C代码:4.串
- 数据结构伪C代码:7.图
- 数据结构伪C代码:9.查找
- 数据结构(C语言版)摘录--树和二叉树
- 文件无法删除的解决办法
- 自定义基于 jQuery 的 tableUI 插件(基偶行颜色交替,活动行变色)
- java线程管理利器:java.util.current的用法举例
- NYOJ 678 最小K个数之和
- 关联工厂和公司的对应关系表以及本位币获取
- 数据结构伪C代码:6.树和二叉树
- test
- test
- 温控风扇的代码(开源) 新手写代码
- 开张--数据结构及算法的种类简单总结
- 迪蒙网贷系统:一切黑客都是纸老虎
- linux下安装一些的编译的安装apache 、nginx、php常出现的错误
- 中国P2P成全球最大市场 亟待监管与规范
- 索菲亚·阿莫鲁索 不良女青年的“逆袭”