#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#define MaxSize 15
#define Inf 10000  //无穷大
bool visited[MaxSize];
static int sn=-1;
typedef int ElemType;## 结构体//单链表
typedef struct LNode{ElemType data;struct LNode *next;
}LNode,*LinkList;//双链表
typedef struct DNode{int data;struct DNode *prior,*next;
}DNode,*DLinklist;//二叉树孩子表示法
typedef struct BiNode{char data;BiNode *lchild,*rchild;
}BiNode,*BiTree;//树的孩子表示法
typedef struct CTreeNode{int vnum;//图中结点编号 struct CTreeNode *child[MaxSize];int cnum;//孩子个数
}*CTree,CTNode; //图邻接矩阵表示法
typedef struct {char Vex[MaxSize];//顶点集 int Edge[MaxSize][MaxSize];//边级  无权图不存在边是0,存在是1,对角线是0;有全图不存在边是∞,存在边是权值,对角线是0 int vexnum,arcnum;//当前顶点个数和边集
}MGraph;//图的邻接表表示法
//边结点
typedef struct ArcNode{int adjvex;//指向顶点编号struct ArcNode *next;//指向下一条弧的指针
//  int weight;//权值信息
}ArcNode; //顺序存储顶点结点
typedef struct VNode{char data;ArcNode *first;//第一条边结点
}VNode,AdjList[MaxSize]; //存储图的邻接表
typedef struct {AdjList adjlist;//顶点顺序表;int vexnum,arcnum;//顶点个数,边个数;
}LGraph; //栈
typedef struct{int top;//=-1;ElemType elem[MaxSize];
}Stack; //队列
typedef struct Queue{int count;//=0;ElemType elem[MaxSize];//int front=0,rear=0;int front,rear;
}Queue;
typedef struct Flink{char num[10];char name[10];int score;Flink *next;
}*FLink,Flnode;void Qsort(int a[],int m,int n);
//快速排序  最好:nlogn,最坏:n方,平均:nlogn;空间:nlogn;最坏情况:有序,不稳定 //注意在素组最后的无穷大虚拟记录,来确保从左到右循环的终止,而且要在进入函数之前定义好 void Bubble(int a[],int n);
//冒泡排序  最好:n 最坏:n方  平均:n方; 空间:1;稳定;最坏情况:逆序,适用于基本有序 注意flag使用(在排序是没发生交换则有序退出) void Insertsort(int a[],int n);
//直接插入排序  最好:n  最坏:n方  平均:n方  空间:1;稳定  最坏情况:逆序,适用于基本有序 要移动元素
void ZBInsert(int a[],int n);//折半插入排序  最好:n  最坏:n方  平均:n方  空间:1;稳定   只能用于顺序表 比较次数与初始状态无关 void Shellsort(int a[],int n);
//希尔排序 最好:--  最坏:n方  平均:n  空间1;不稳定 性能与选取的分组长度序列有关一般选d/2 void Ssort(int a[],int n);
//直接选择排序  最好: n方  最坏:n方 平均:n方  空间  1;不稳定  性能(比较次数和时间复杂度)与初始状态无关 void BuildMaxHeap(int a[],int len);//建堆 void AdjustDown(int a[],int k,int len);//调整堆void Heapsort(int a[],int len);//堆排序   最好:nlogn 最坏:nlogn 平均:nlogn 空间:1;不稳定   性能(比较次数和时间复杂度)与初始状态无关void Merge(int a[],int p,int q,int n,int b[]);
//两个序列的合并  i第一个序列的起始地址,j是第二个序列的起始地址,n是合并好的序列的起始地址 void Mpass(int a[],int n,int L,int b[]);
//一趟合并算法   n是序列总长度,L是每次合并相邻子序列的长度 void Msort(int a[],int n,int b[]);
//二路归并排序   最好:nlogn  最坏: nlogn 平均:nlogn 空间:n;  稳定  性能与初始状态无关 void CreatLGraph(LGraph &G);//建图(邻接表)
void PrintLGraph(LGraph G);//输出图
void BFS(LGraph G,int v);//广度优先遍历
void BFSMinpath(LGraph G,int v);//广度优先遍历求无权图最短路径(建立的距离数组d,每次遍历到更新距离)
bool BFSIstree(LGraph G,int v);//广度优先遍历判断图是否为一棵树 (判断visted数组若出现冲突则存在环)
void DFS(LGraph G,int v);//深度优先遍历(递归)(要定义全局标记数组visited)
void dfs(LGraph G,int v);//深度优先遍历(非递归)
void ddfs(LGraph G,int i,int j,int d[],int n);
void FindPath(LGraph G,int u,int v,int k,int path[]);//深度优先遍历找所有路径(定义全局变量访问数组visited,path为路径数组,k为路径上结点的次序)
void InDegree(LGraph G,int result[]);//遍历邻接表计算图中各顶点的入度
void VList(LGraph G,LGraph VG);//创建图的逆邻接表
void BGraphTree(LGraph G,CTree &T,int v);//创建图的层序遍历生成树
void Floyed(LGraph G,int dis[MaxSize][MaxSize]);//弗洛伊德算法求图中任意两点间的最短路径 void CreatBiTree(BiTree &bt);//二叉树创建(递归先序)
void PreOrder(BiTree bt);//先序递归遍历
void InOrder(BiTree bt);//中序递归遍历
void PostOrder(BiTree bt);//后序递归遍历
void FPreOrder(BiTree bt);//先序非递归遍历
void FInOrder(BiTree bt);//中序非递归遍历
void FPostOrder(BiTree bt);//后序非递归遍历
void LevelOrder(BiTree bt);//层序遍历
void BtHeight(BiTree bt,int &h);//递归求树高
void Presum(BiTree bt,int &q);//递归先序求和
void BtSwap(BiTree bt);//递归交换左右子树
void BtDelete(BiTree bt);//递归删除树,释放空间
BiNode *CommonAncestor(BiTree bt,BiNode *p,BiNode *q);//递归判断最近的公共祖先
void Common(BiTree bt,BiNode *p,BiNode *q,BiNode **r);
BiNode* Ancestor(BiTree bt,BiNode *p);//递归找到所有祖先
bool Isson(BiTree T,BiNode *u,BiNode *v);//递归判断u是否为v的祖先
BiTree piCreate(char pre[],char in[],int pl,int pr,int il,int ir);//根据先序和中序创建二叉树
int LHeight(BiTree bt);//层序遍历求树高
int LWidth(BiTree bt);//层序遍历求树宽
int LLnodecount(BiTree bt);//层序求二叉树叶子or单分支or双分支节点or独生叶节点个数
void IsBalance(BiTree bt,int &b,int &h);//判断二叉树是否平衡,b为1平衡,h为高度
void ReLevel(BiTree bt);//从上到下,从右到左层序遍历二叉树
void BiString(BiTree &bt,char s[]);//真题210问题(红皮书35) 正向
BiTree RBiString(char a[],int n); //逆向
BiTree DBiString(char a[]);//递归
bool Push(Stack &S,ElemType e);//入栈
ElemType Pop(Stack &S);//出栈
bool EnQueue(Queue &Q,ElemType e);//入队
ElemType DeQueue(Queue &Q);//出队bool InitList(LinkList &L);//带头节点的单链表初始化
bool InitDlist(DLinklist &L);//带头结点双链表初始化
LinkList List_TailInsert(LinkList &L);//尾插法建立链表
LinkList List_HeadInsert(LinkList &L);//头插法建立链表
void creat(DLinklist &L);//带头结点的双链表创建
bool ListInsert(LinkList &L,int n,ElemType e);//插入节点
bool InsertNextNode(LNode *p,ElemType e);//后插操作
LNode *LocateElem(LinkList L,ElemType e);//按值查找
LNode *GetElem(LinkList L,int i);//按位查找
int Length(LinkList L);//求表长
void Del(LinkList &L,int x);//删除结点
bool InsertNextDNode(DNode *p,DNode *s);//双链表后插操作
void PrintList(LinkList L);//输出链表
bool ListDelete(LinkList &L,int i);//按位序删除
LinkList Reverse(LinkList &L);//就地逆置
int Search_k(LinkList &L,int k);//找到倒数k个元素
LNode *IsCommon(LinkList p,LinkList q);//判断是否两个链表相交
bool Insert(LinkList &L,int n,int e);//在第n个位置插入值为e的结点
void LInsertSort(LinkList &L);//链表直接插入排序
void exchange(LinkList &L,LNode *p);// 2001计学  1.交换链表结点
LinkList List_TailInsert_1(LinkList &L,LNode* &p,int a);void QSort(int a[],int m, int n){if(m>=n) return;  //递归出口!!! int i=m;int j=n+1;int temp;while(i<j){i++;while(a[i]<a[m]) i++;j--;while(a[j]>a[m]) j--;if(i<j){temp=a[i];a[i]=a[j];a[j]=temp;}}temp=a[j];a[j]=a[m];a[m]=temp;for(int q=0;q<5;q++)printf("%d",a[q]);printf("\n"); QSort(a,m,j-1);QSort(a,j+1,n);
}void Bubble (int a[],int n){int i,j,temp;bool flag;for(i=n-1;i>0;i--){flag=false;for(j=0;j<i;j++){if(a[j]>a[j+1]){temp=a[j];a[j]=a[j+1];a[j+1]=temp;flag=true;}}          printf("第%d趟",n-i);for(int q=0;q<n;q++)printf("%d",a[q]); printf("\n");                  if (flag ==false)  return ;//表明本趟没有发生交换 }}void InsertSort(int a[],int n ){int i,j,temp;for( i=1;i<n;i++) { //从第二个 待插入依次和前面一个比较 如果大则直接下一个元素 如果小则往前找 if(a[i]<a[i-1]){temp=a[i];for( j=i-1;j>=0&&a[j]>temp;j--){  //从后往前找到第一个比待插入小的 插在它后面 a[j+1]=a[j];}a[j+1]=temp;      //插到比待插入值小的元素的后面 }}for(int q=0;q<n;q++){printf("%d",a[q]);   }}void BinInsertSort(int a[],int n){int i,j,temp,low,high,mid;for(i=1;i<n;i++){    if(a[i]<a[i-1]){         //待插入的数跟左边的数比较如果比左边的大则继续下一个 如果小则继续往左边折半找 low=0,high=i-1;temp=a[i];while(low<=high){mid=(low+high)/2;if(temp<a[mid])high=mid-1;else low=mid+1;        //找到相等元素时放右边保持稳定性  }for(j=i-1;j>=low;j--)    //最终插入的位置在low a[j+1]=a[j];a[low]=temp; }}for(int q=0;q<n;q++){printf("%d",a[q]);}
}
//和直接插入排序相比,前后记录位置的增量为dk不是1 a[0] 暂存单元不是哨兵
void ShellSort(int a[],int n){int i,j,dk,temp;for( dk=n/2;dk>=1;dk=dk/2){for( i=dk;i<n;++i){           //     在各组步长为dk的进行希尔排序 if(a[i]<a[i-dk]){temp=a[i];for( j=i-dk;j>=0&& temp<a[j];j-=dk)   //在直接插入排序 a[j+dk]=a[j];a[j+dk]=temp ;}}} for(int q=0;q<n;q++)printf("%d",a[q]);}void SSort(int a[],int n){int i,j,temp;for(i=n-1;i>0;i--){ int max= i;  //n-1趟比较   从后往前排序 for(j=0;j<i;j++){  //每一趟选择一个最大的 与最后一个交换位置 if(a[j]>a[max])max=j;}if(max!=i){temp=a[i];a[i]=a[max];a[max]=temp;}}for(int q=0;q<n ;q++)printf("%d", a[q]);
}void BuildMaxHeap(int a[],int n){   //建堆 for(int i=n/2;i>=0;i--){Adjustdown(a,i,n);}
}
void Adjustdown(int a[],int k,int n){  //调整堆 int temp=a[k];for(int i=2*k;i<n;i*=2){if(k==0) i=1;   //k=0 则是第一个结点它的孩子为1if(i<n-1&&a[i]<a[i+1])i++;          //i指向孩子中较大的那一个if(a[k]>a[i]) break;else{a[k]=a[i];k=i;} a[k]=temp;} }void HeapSort(int a[],int n){ //堆排序x BuildMaxHeap(a,n);  // 建立大根堆for(int i=n-1;i>0;i--){   //从后往前依次重建堆int temp=a[0];a[0]=a[i];a[i]=temp;Adjustdown(a,0,i-1); } for(int q=0;q<n;q++)printf("%d",a[q]);
}//图//建图void CreatLGraph(LGraph &G){printf("输入顶点数和边数:\n");scanf("%d %d",&G.vexnum,&G.arcnum);printf("输入顶点名称:\n");getchar();for(int i=0;i<G.vexnum;i++){scanf("%c",&G.adjlist[i].data);   //建立顶点集合G.adjlist[i].first=NULL; }printf("输入边坐标信息:\n");for(int i=0;i<G.arcnum;i++){int x,y;   scanf("%d %d",&x,&y);ArcNode *p= (ArcNode*)malloc(sizeof(ArcNode));p->adjvex=y;p->nextarc=G.adjlist[x].first;G.adjlist[x].first=p;  // 头插法
//          ArcNode *q=(ArcNode *)malloc(sizeof(ArcNode));
//          q->adjvex=x;
//          q->nextarc=G.adjlist[y].first;
//          G.adjlist[y].first=q;     //无向图 }}void PrintLGraph(LGraph G){ArcNode * p ;for(int i =0;i<G.vexnum;i++){p=G.adjlist[i].first;printf("结点:%c",G.adjlist[i].data);while(p!=NULL){
//          printf("结点:%c 权值:%d\n",G.adjlist[p->adjvex].data,p->weight);   //带权图 p=p->nextarc;}printf("\n");}
}void dfs(LGraph G ,int v){int Stack[MAXSIZE];int top=-1;   //初始化 for(int i =0;i<G.vexnum;i++){visited[i]=false;}            //初始化访问数组Stack[++top]=v;  //进栈 visited[v]=true;
//  printf("%c",G.adjlist[v].data);while(top!=-1){ArcNode * p ;int i=Stack[top--];  //出栈 printf("%c",G.adjlist[i].data);for(p=G.adjlist[i].first;p!=NULL;p=p->nextarc){if(! visited[p->adjvex]){Stack[++top]=p->adjvex;visited[p->adjvex]=true;}}}
}void bfs(LGraph G ,int v){int Queue[MAXSIZE];int front=-1,rear=-1; // 初始化for(int i=0;i<G.vexnum;i++){visited[i]=false;} printf("%c",G.adjlist[v].data);Queue[++rear]=v;visited[v]=true;while(front!=rear){int p=Queue[++front];ArcNode * k;for(k=G.adjlist[p].first;k!=NULL;k=k->nextarc){if(!visited[k->adjvex]){Queue[++rear]=k->adjvex;visited[k->adjvex]=true;printf("%c",G.adjlist[k->adjvex].data);  //输出顶点 }}}
}void DFS(LGraph G ,int v){printf("%c",G.adjlist[v].data);visited[v]=true;ArcNode *p;for(p=G.adjlist[v].first;p!=NULL;p=p->nextarc){if(!visited[p->adjvex])DFS(G,p->adjvex);}} void FindPath(LGraph G ,int u,int v,int d,int path[]){d++;path[d]=u;visited[u]=true;if(u==v){for(int i=1;i<=d;i++){printf("%c",G.adjlist[path[i]].data);}}ArcNode *p;for(p=G.adjlist[u].first;p!=NULL;p=p->nextarc){if(!visited[p->adjvex]){visited[p->adjvex]=true;FindPath(G,p->adjvex,v,d,path);}}visited[u]=false;}void InDegree(LGraph G,int Degree[]){for(int i=0;i<MAXSIZE;i++) Degree[i]=0;  //初始化一位数组for(int i=0;i<G.vexnum;i++){for(ArcNode *p=G.adjlist[i].first;p!=NULL;p=p->nextarc) {Degree[p->adjvex]++;}   } for(int q=0;q<G.vexnum;q++){printf("%d",Degree[q]);}
} void BFSMinpath(LGraph G,int v){int Queue[MAXSIZE];int front=-1,rear=-1;int d[MAXSIZE]={0};d[v]=0;visited[v]=true;Queue[++rear]=v;while(front!=rear){int temp=Queue[++front];for(ArcNode *p=G.adjlist[temp].first;p!=NULL;p=p->nextarc){if(!visited[p->adjvex]){visited[p->adjvex]=true;Queue[++rear]=p->adjvex;d[p->adjvex]=d[temp]+1;}}}for(int i=0;i<G.vexnum;i++){printf("结点:%c 最短距离: %d\n",G.adjlist[i].data,d[i]);}
}bool BFSIStree(LGraph G,int v){int Queue[MAXSIZE];int front=-1,rear=-1;visited[v]=true;printf("%c",G.adjlist[v].data);Queue[++rear]=v;while(front!=rear){int temp=Queue[++front];for(ArcNode * p =G.adjlist[temp].first;p!=NULL;p=p->nextarc){if(!visited[p->adjvex]){printf("%c",G.adjlist[p->adjvex].data);visited[p->adjvex];Queue[++rear]=p->adjvex;}elsereturn false;   //如果顶点访问过则是有回路 }}return true;
}bool DFSIStree(LGraph &G){   // 无向图int Vnum=0,Enum=0;int vis[]={0};DFSTree(G,0,Vnum,Enum,vis);  //递归if(Vnum==G.vexnum && Enum== 2*(G.vexnum -1)){  //深度遍历完一次 得到n个结点 和n-1条边则为一棵树 return true;} else return false;}void DFSTree(LGraph G,int v,int Vnum,int Enum,int  vis[]){visited[v]=true;Vnum++;for(ArcNode *p=G.adjlist[v].first;p!=NULL;p=p->nextarc){Enum++;if(!visited[p->adjvex]){printf("%c",G.adjlist[p->adjvex].data);DFSTree(G,p->adjvex,Vnum,Enum,vis);}}
}void Converse(LGraph G ,LGraph &VG){VG.vexnum=G.vexnum;VG.arcnum=G.arcnum;for(int i=0;i<VG.vexnum;i++){VG.adjlist[i].first=NULL;VG.adjlist[i].data=G.adjlist[i].data;  //初始化 }for(int i=0;i<G.vexnum;i++){for(ArcNode *p=G.adjlist[i].first;p!=NULL;p=p->nextarc){ArcNode * t=(ArcNode *)malloc (sizeof(ArcNode));t->adjvex=i;t->nextarc=VG.adjlist[p->adjvex].first;VG.adjlist[p->adjvex].first=t;  //头插法 建立逆邻接表 }} }//建立图的层次遍历生成树
void BGraphTree(LGraph G, CTree &T,int v ){CTree Queue[MAXSIZE];  //建立树形结构的队列int front =-1,rear=-1;root =(CTNode *)malloc(sizeof(CTNode)) ; //建立根节点root->vnum=v;visited[v]=true;Queue[++rear]=root;  //树形结构入队 while(front!=rear){CTNode * t=Queue[++front];for(ArcNode *p=G.adjlist[t->vnum].first;p!=NULL;p=p->nextarc){if(visited[p->adjvex]){visited[p->adjvex]=true;CTNode * q=(CTNode *)malloc (sizeof(CTNode ));  //建立其孩子结点q->vnum=p->adjvex;t->child[t->cnum++]=q;Queue[++rear]=q;}}}
}void Floyed(LGraph G,int dis[MAXSIZE]{MAXSIZE}){for(int i=0;i<G.vexnum;i++){for(int j=0;j<G.vexnum;j++){dis[i][j]=0;    //初始化二维数组 }}for(int i=0;i<G.vexnum;i++){  //把权值存入数组 for(ArcNode *p=G.adjlist[i].first;p!=NULL;p=p->nextarc){dis[i][p->adjvex]=p->weight;}for(int j=0;j<G.vexnum;j++){if(i!=j && dis[i][j]==0){dis[i][j]=Inf;  //设为无穷大 }}}for(int k=0;k<G.vexnum;k++){  //k表示绕过第k个顶点的运算  for(int i=0;i<G.vexnum;i++){for(int j=0;j<G.vexnum;j++){if(dis[i][k]!=Inf && dis[k][j]!=Inf && dis[i][j]>dis[i][k]+dis[k][j]){ //如果i和j之间存在第k个点且路径之和小于原来路径则重新赋值 dis[i][j]=dis[i][k]+dis[k][j];   }}}}
}bool TopologicalSort(LGraph G){   //拓扑排序判断是否存在拓扑序列 若是则返回true 若不是则存在环 //用栈暂存入度为0的顶点int Stack[MAXSIZE];int top=-1;for(int i=0;i<G.vexnum;i++){if(indegree[i]==0){Stack[++top]=i;    //把入度为0的顶点入栈 }} int count=0;  //记录已经输出的顶点数while(top!=-1 ){i=Stack[top--];printf("%d",i);// 输出顶点 count ++; for(ArcNode * p =G.adjlist[i].first;p!=NULL;p=p->nextarc){if(--indegree[p->adjvex]==0){Stack[++top]=p->adjvex;   //顶点i指向的所有顶点入度-1 并且将入度减为0的顶点入栈 }}} if(count<G.vexnum)return false;   //排序失败 存在回路else return true;   //成功
}void CreatBiTree(BiTree &bt){char a;scanf("%c",a);if(a == '*')  {bt=NULL;}else{bt = (BiNode *)malloc (sizeof(BiNode));bt->data=a;CreatBiTree(bt->lchild);CreatBiTree(bt->rchild);}
}//----------------树------------
//样例
//先序:ABD*G***CEH**I**F**
//中序:DGBAHEICF
//后序:GDBHIEFCA
//层序: ABCDEFGHI
void postpath(BiTree bt,char c){BiTree stack[10];int top=-1;BiNode *p=bt,*r;while(top!=-1||p!=NULL){if(p!=NULL){stack[++top]=p;r=p;p=p->lchild;if(r->data=='I') break;}else{p=stack[top];if(p->rchild!=NULL&&p->rchild!=r){p=p->rchild;}else{r=p;top--;// printf("%c",p->data);p=NULL;}}}for(int i=0;stack[i]!=NULL;i++){printf("%c",stack[i]->data);}
}
void Pre(BiTree bt,int i){BiNode *p=bt;if(p==NULL) return;printf("值:%c   层数%d:\n",bt->data,i);Pre(p->lchild,i+1);Pre(p->rchild,i+1);
}
int wid(BiTree bt){BiTree Queue[10];int front=-1,rear=-1,last=0,wide=0,max=1;BiNode *p=bt;Queue[++rear]=p;while(front!=rear){p=Queue[++front];if(p->lchild!=NULL) {Queue[++rear]=p->lchild;wide++;}if(p->rchild!=NULL) {Queue[++rear]=p->rchild;wide++;}if(front==last){last=rear;if(max<wide) max=wide;wide=0;}}return max;
}//int main(){
//  BiTree bt;
//  BiNode *q,*p,*r;
//  char c='H';
//  //bt=(BiNode *)malloc(sizeof(BiNode));bt->data='A';
//  CreatBiTree(bt);char c='I';postpath(bt,c);
//  //int h,b;
//  //BtSwap(bt);
//  //BtDelete(bt);
//  //bt=NULL;
//  //printf("%c",bt->data);
//  //char s[99];
//  //scanf("%s",s);
//  //int i=wid(bt);
//  //printf("%c",bt->data);
//  //bt=DBiString(s);
//  //printf("%c",bt->data);
//  //LevelOrder(bt);
//  //printf("宽度:%d",i);
//  //ReLevel(bt);
//  //IsBalance(bt,h,b);
//  PreOrder(bt,q,'H');PreOrder(bt,p,'F');
//  p=Ancestor(bt,q);Common(bt,p,q,r); printf("\n%c  %c   %c",q->data,p->data,r->data);
//  //printf("\n");
//  //FInOrder(bt);
//  //printf("\n");FPostOrder(bt,c);
//  //printf("\n");
//  //printf("%d %d",h,b);
//  //L=List_TailInsert(L);
//  //ListDelete(L,2);
//  //Reverse(L);PrintList(bt);
//  return 0;
//}
//树--------
//二叉树创建(递归先序)
//ABD*G***CEH**I**F**
//222*2***222**2**2**
void CreatBiTree(BiTree &bt){char a;scanf("%c",&a);if(a=='*') {bt=NULL;}//输入*结束else{bt=(BiNode *)malloc(sizeof(BiNode));bt->data=a;CreatBiTree(bt->lchild);CreatBiTree(bt->rchild); }
}
//先序递归遍历
void PreOrder(BiTree bt){if(bt==NULL) return;printf("%c",bt->data);PreOrder(bt->lchild);PreOrder(bt->rchild);
}
//先序求和
void Presum(BiTree bt,int &q){if(bt==NULL) return ;q+=(bt->data-'0');Presum(bt->lchild,q);Presum(bt->rchild,q);
//  return bt->data+a+b-'0';
}
//111*1***111**1**1**
//中序递归遍历
void InOrder(BiTree bt){if(bt==NULL) return;InOrder(bt->lchild);printf("%c",bt->data);//InOrder(bt->rchild);
}
//后序递归遍历
void PostOrder(BiTree bt){if(bt==NULL) return;PostOrder(bt->lchild);PostOrder(bt->rchild);printf("%c",bt->data);
}
//递归求树高
void BtHeight(BiTree bt,int &h){BiNode *p=bt;int lh=0,rh=0;if(p==NULL) h=0;else{BtHeight(p->lchild,lh);BtHeight(p->rchild,rh);  h=lh>rh?lh+1:rh+1;    }// int lh=BtHeight(p->lchild);
//  int rh=BtHeight(p->rchild);
//  if(lh>rh) return lh+1;
//  else return rh+1;
}
//判断二叉树是否平衡,b平衡因子,0为不平衡,1为平衡,h为高度
/*思想:后序递归判断 每个结点: 1.若这个结点为空,高度h=0,b=1;  //2.若这个结点没有孩子,则h=1,b=1;3.若这个结点有左子树或右子树,那么h=max{rh+1,lh+1}(较高的子树高度+1);如果左右子树的高度差大于1(不平衡):b=0;如果左右子树的高度差小于等于1(大树平衡)且左右子树也都平衡(rb==1&&lb==1):b=1;否则b=0;
*/
void IsBalance(BiTree bt,int &b,int &h){//b,h 要带出来 BiNode *p=bt;int rh=0,lh=0,rb=0,lb=0;if(p==NULL){h=0;b=1;}
//  else if(p->lchild==NULL&&p->rchild==NULL){
//      h=1;
//      b=1;
//  }else{IsBalance(p->lchild,lb,lh);//传参是lb,lh,即本次递归的b和h;实际上的运算是lb和lh在运算,有使用了引用传参 IsBalance(p->rchild,rb,rh);//所以,lb和lh的值会被带出来 h=(lh>rh?lh+1:rh+1);if(abs(lh-rh)>1) b=0;else{if(lb==1&&rb==1) b=1;else b=0;}}
}
//递归交换左右子树
void BtSwap(BiTree bt){BiNode *p=bt,*temp;if(p){BtSwap(p->lchild);BtSwap(p->rchild);temp=p->lchild;p->lchild=p->rchild;p->rchild=temp;} else return;
}
//递归删除树,释放空间
void BtDelete(BiTree bt){if(bt){BtDelete(bt->lchild);BtDelete(bt->rchild);free(bt);   }bt=NULL;
}
//层序遍历
void LevelOrder(BiTree bt){BiTree BQueue[MaxSize];if(bt==NULL) return;int front=-1;int rear=-1; BQueue[++rear]=bt;while(front!=rear){printf("%c",BQueue[++front]->data);if(BQueue[front]->lchild!=NULL)BQueue[++rear]=BQueue[front]->lchild;if(BQueue[front]->rchild!=NULL)BQueue[++rear]=BQueue[front]->rchild;}
}
//层序遍历求树高
int LHeight(BiTree bt){BiTree BQueue[MaxSize];BiNode *p=bt;int front=-1,rear=-1,level=0,last=0;//level层数,last表示当前队列中最后一层的最后一个结点位置 BQueue[++rear]=p;while(front!=rear){p=BQueue[++front];if(p->lchild!=NULL)BQueue[++rear]=p->lchild;if(p->rchild!=NULL)BQueue[++rear]=p->rchild;if(front==last){//对 头到最后位置时,这一层结点的所有孩子结点都入队,level++;   //即下一层的结点都入队,更新下一层的最后位置, 对头指针遍历到 下一层,更新 层  数last=rear;}}return level;
}
//层序遍历求树宽
int LWidth(BiTree bt){BiTree BQueue[MaxSize];int front=-1,rear=-1,level=1,width=0,last=0,max=1;BiNode *p=bt;BQueue[++rear]=p;while(front!=rear){p=BQueue[++front];if(p->lchild!=NULL){BQueue[++rear]=p->lchild; width++;} if(p->rchild!=NULL){BQueue[++rear]=p->rchild;  width++;} if(front==last){last=rear;if(max<width) max=width;printf("第%d层的宽度为:%d\n",++level,width);width=0;}}return max;
}
//层序求二叉树叶子or单分支or双分支or独生叶节点个数
int LLnodecount(BiTree bt){BiTree BQueue[MaxSize];int front=-1,rear=-1,count=0;BiNode *p=bt;BQueue[++rear]=p;//叶子结点
//  while(front!=rear){
//      p=BQueue[++front];
//      if(p->lchild==NULL&&p->rchild==NULL) count++;
//      if(p->lchild) BQueue[++rear]=p->lchild;
//      if(p->rchild) BQueue[++rear]=p->rchild;
//  } //单分支结点
//  while(front!=rear){
//      p=BQueue[++front];
//      if((p->lchild==NULL&&p->rchild!=NULL)||(p->lchild!=NULL&&p->rchild==NULL)) count++;
//      if(p->lchild) BQueue[++rear]=p->lchild;
//      if(p->rchild) BQueue[++rear]=p->rchild;
//  }//双分支结点
//  while(front!=rear){
//      p=BQueue[++front];
//      if(p->lchild!=NULL&&p->rchild!=NULL) count++;
//      if(p->lchild) BQueue[++rear]=p->lchild;
//      if(p->rchild) BQueue[++rear]=p->rchild;
//  }//独生叶节点 while(front!=rear){p=BQueue[++front];if(p->lchild==NULL&&p->rchild!=NULL)if(p->rchild->lchild==NULL&&p->rchild->rchild==NULL) count++;if(p->lchild!=NULL&&p->rchild==NULL)if(p->lchild->lchild==NULL&&p->lchild->rchild==NULL) count++;if(p->lchild) BQueue[++rear]=p->lchild;if(p->rchild) BQueue[++rear]=p->rchild;}return count;
}
//从上到下,从右到左层序遍历二叉树
void ReLevel(BiTree bt){BiTree BQueue[MaxSize];int front=-1,rear=-1,last=0;BiTree BStack[MaxSize];int top=-1;BiNode *p=bt;BQueue[++rear]=p;while(rear!=front){p=BQueue[++front];BStack[++top]=p;if(p->lchild!=NULL)BQueue[++rear]=p->lchild;if(p->rchild!=NULL)BQueue[++rear]=p->rchild;if(last==front){last=rear;while(top>-1)printf("%c",BStack[top--]->data);}}
} //先序非递归遍历
void FPreOrder(BiTree bt){//if(bt) return;BiTree TStack[MaxSize];int top=-1;BiNode *p=bt;//注意判断条件是结点或栈不为空,若只判断栈空时,先序递归回到根结点是栈为空,且右子树存在,这样就访问不了右子树。 while(top!=-1||p){//p不空,左子树不空,访问左子树,p空,栈里有元素时,出栈栈顶元素,访问右子树,p空栈空结束 if(p){printf("%c",p->data);TStack[++top]=p;p=p->lchild;}else{p=TStack[top--];p=p->rchild;}        }
}
//非递归中序遍历
void FInOrder(BiTree bt){BiTree TStack[MaxSize];int top=-1;BiNode *p=bt;//判断条件与先序一样 while(top!=-1||p){if(p){TStack[++top]=p;p=p->lchild;}else{p=TStack[top--];printf("%c",p->data);p=p->rchild;}}
}
//后序非递归遍历
void FPostOrder(BiTree bt){
//  printf("%c",c);BiTree TStack[MaxSize];int top=-1;BiNode *p=bt,*r=NULL;//r用来标记访问过的上一个结点 while(top!=-1||p!=NULL){//栈里每个元素都是当前遍历结点的祖先 if(p!=NULL){//遍历到树的最左下方 //   if(p->data=='I') break;TStack[++top]=p;p=p->lchild;}else{//左边到头后回到上一层但不访问,接着访问右子树 p=TStack[top];if(p->rchild!=NULL&&p->rchild!=r){//右子树不为空且没被访问过,若为空或被访问过是从下往上回来的过程 p=p->rchild;TStack[++top]=p;//每次遍历到新结点都要入栈 p=p->lchild;//在递归遍历左子树 }else{//左右子树都为空,或左右子树都被访问过回到上一层 p=TStack[top--];printf("%c",p->data);r=p;//标记被访问过 p=NULL;//出栈回到上一层,若p不为空讲重复访问 }}
//          for(int i=0;i<1;i++)
//              printf("%c",TStack[0]->data);
//              printf("\n");}for(int i=0;TStack[i]!=NULL;i++)printf("%c",TStack[i]->data);
//printf("1");
}//链表------------------
//带头节点的单链表初始化
bool InitList(LinkList &L){L=(LNode *)malloc(sizeof(LNode));if(L=NULL) return false;//内存已满L->next=NULL;return true;}
/*不带头节点的初始化(头指针)
bool InitList(LinkList &L){L=null;return true;}
*/
//带头结点双链表初始化
bool InitDlist(DLinklist &L){L=(DNode *)malloc(sizeof(DNode));if(L==NULL) return false;//内存不足L->prior=NULL;L->next=NULL;return true;
}
//判空(带头结点)
bool Empty(LinkList L){return L->next==NULL;
}
bool DEmpty(DLinklist L){return L->next==NULL;
}
//插入节点
bool ListInsert(LinkList &L,int n,ElemType e){if(n<1) return false;LNode *p;int j=0;//头节点看作第零个p=L; while(p!=NULL&&j<n-1){//找到第n-1个位置p=p->next; j++;  } if(p==NULL) return false;LNode *s=(LNode *)malloc(sizeof(LNode));s->data=e;s->next=p->next;p->next=s;return true;
}
//删除结点
void Del(LinkList &L,int x){LNode* p=L->next,*pre=L;while(p){if(p->data!=x){pre=p;p=p->next;}else{pre->next=p->next;free(p);p=pre->next;}  }
}
//后插操作
bool InsertNextNode(LNode *p,ElemType e){if(p==NULL) return false;LNode *s=(LNode *)malloc(sizeof(LNode));s->data=e;s->next=p->next;p->next=s;return true;
}
//双链表后插操作
bool InsertNextDNode(DNode *p,DNode *s){//把s插到p后面 if(p==NULL||s==NULL) return false;s->next=p->next;if(p->next!=NULL)//如果p后有后继节点p->next->prior=s;s->prior=p;p->next=s;return true;
}
bool DeleteDNode(DNode *p,DNode *s){if(p==NULL||s==NULL) return false;DNode *q=p->next;p->next=q->next;if(q==NULL) return false;if(q->next!=NULL)q->next->prior=p;free(q);
}
//前插操作
bool InsertPriorNode(LNode *p,LNode *s){if(p==NULL||s==NULL) return false;s->next=p->next;p->next=s;ElemType temp=p->data;p->data=s->data;s->data=temp;return true;
}
//按位序删除
bool ListDelete(LinkList &L,int i){if(i<1) return false;LNode *p;int j=0;//头节点看作第零个p=L; while(p!=NULL&&j<i-1){//找到第n-1个位置p=p->next; j++; } if(p==NULL||p->next==NULL) return false;LNode *q=p->next;printf("删除节点值为:%d\n",q->data);p->next=q->next;free(q);return true;
}
//删除指定结点
bool DeleteNode(LNode *p){if(p==NULL) return false;LNode *q=p->next;p->data=q->data;p->next=q->next;free(q);return true;
}
//按位查找
//LNode *GetElem(LinkList L,int i){
//  if(i<0) return false;
//  LNode *p;
//  int j=0;
//  p=L;
//  while(p!=NULL&&j<i){
//      p=p->next;
//      j++;
//  }
//  return p;
//}
//按值查找
LNode *LocateElem(LinkList L,ElemType e){LNode *p=L->next;while(p!=NULL||p->data!=e)p=p->next;return p;
}
//求表长
int Length(LinkList L){int len=0;LNode *p=L;while(p->next!=NULL){p=p->next;len++;}return len;
}
//尾插法建立链表
LinkList List_TailInsert(LinkList &L){int i;L=(LNode *)malloc(sizeof(LNode));LNode *s,*r=L;scanf("%d",&i);while(i!=9999){s=(LNode *)malloc(sizeof(LNode));s->data=i;r->next=s;r=s;scanf("%d",&i);}r->next=NULL;return L;
}
//头插法建立链表
LinkList List_HeadInsert(LinkList &L){int i;L=(LNode *)malloc(sizeof(LNode));LNode *s;L->next=NULL;scanf("%d",&i);while(i!=9999){s=(LNode *)malloc(sizeof(LNode));s->data=i;s->next=L->next;L->next=s;scanf("%d",&i);}return L;
}
//创建双链表
void creat(DLinklist &L){InitDlist(L);for(int i=0;i<6;i++){DNode *p=(DNode *)malloc(sizeof(DNode));int a;scanf("%d",&a);p->data=a;InsertNextDNode(L,p);}
}
//输出链表
void PrintList(LinkList L){while(L->next!=NULL){printf("%d ",L->next->data);L=L->next;}printf("\n");
}
//就地逆置
//LinkList Reverse(LinkList &L){
//  if(L==NULL) return false;
//  LNode *p=L->next;
//  while(p->next!=NULL){
//      LNode *temp=p->next;//保存结点
//      p->next=temp->next;//断开要动节点,并连接后面节点
//      temp->next=L->next;//将断开节点从头插入
//      L->next=temp;
//  }
//  return L;
//}
//找到倒数k个元素
int Search_k(LinkList L,int k){LNode *p=L,*q=L;if(q==NULL||p==NULL) return 0;while(k--)q=q->next;while(q!=NULL){q=q->next;p=p->next;}if(p==L) return 0;printf("%d\n",p->data);return 1;
}
//判断是否两个链表相交
LNode *IsCommon(LinkList p,LinkList q){//先遍历两个链表的长度int plen=0,qlen=0,alen=0,tag=0;//tag=1,p长,tag=0,q长; LNode *tp=p;LNode *tq=q;while(tp!=NULL||tq!=NULL){if(tp!=NULL) {plen++;tp=tp->next;}if(tq!=NULL) {qlen++;tq=tq->next;}}if(plen>=qlen){alen=plen-qlen;tag=1;}else{alen=qlen-plen;tag=0;}//长的先走长度之差步 if(tag==1){while(alen--)p=p->next;while(qlen--){p=p->next;q=q->next;if(p->data==q->data) return p;}}else{while(alen--)q=q->next; while(plen--){p=p->next;q=q->next;if(p->data==q->data) return p;}}return NULL;
}
//在第n个位置插入值为e的结点
bool Insert(LinkList &L,int n,int e){LNode *pre=L,*p=L->next;int i=1;while(i<n&&p){pre=p;p=p->next;i++; }if(i==n){LNode *s=(LNode*)malloc(sizeof(LNode));s->data=e;s->next=pre->next;pre->next=s;return true;}else return false;
}
/*1 2 3 4 5 9999
9 8 7 3 4 5 9999*///层序中序创建
//BTNode* CreateBTree(ElementType level[], ElementType in[], int l1, int r1, int l2, int r2){
//  if (l2 > r2){
//      return NULL;
//  }
//  else{
//      BTNode* bt = (BTNode*)malloc(sizeof(BTNode));
//
//      int i, j;//分别指向level和in中数组的元素
//      int flag = 0;
//
//      //寻找根结点,若level中第一个与in中元素匹配的即为根结点
//      for (i = l1; i <= r1; ++i)
//      {
//          for (j = l2; j <= r2; ++j)
//          {
//              if (level[i] == in[j])
//              {
//                  flag = 1;
//                  break;
//              }
//          }
//          if (flag == 1)
//              break;
//      }
//
//      bt->data = level[i];//曾经写错过,写成了level[j],j指向的是in中的元素,应改为in[j]
//      bt->lchild = CreateBTree(level, in, l1 + 1, r1, l2, j - 1);
//      bt->rchild = CreateBTree(level, in, l1 + 1, r1, j + 1, r2);
//  }
//      return bt;
//  }

排序 链表 图 二叉树算法相关推荐

  1. 关于单链表,二叉树,图,查找和排序的软件编程

    课程名称:计算机软件 使用软件:devcpp 注意:这里列出了关于单链表,二叉树,图,查找和排序的编程,全部程序由博主一人编写,会有瑕疵,谨慎使用. 1.单链表 要求:(1)建立单向链表,表长任意: ...

  2. 【LeetCode-面试算法经典-Java实现】【109-Convert Sorted List to Binary Search Tree(排序链表转换成二叉排序树)】...

    [109-Convert Sorted List to Binary Search Tree(排序链表转换成二叉排序树)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 ...

  3. python处理mysql数据结构_python环境下使用mysql数据及数据结构和二叉树算法(图)...

    python环境下使用mysql数据及数据结构和二叉树算法(图): 1 python环境下使用mysql 2使用的是 pymysql库 3 开始-->创建connection-->获取cu ...

  4. python 拓扑排序 dfs bfs_图遍历算法之DFS/BFS

    在计算机科学, 图遍历(Tree Traversal,也称图搜索)是一系列图搜索的算法, 是单次访问树结构类型数据(tree data structure)中每个节点以便检查或更新的一系列机制.图遍历 ...

  5. Leetcode 129求根节点到叶节点数字之和、104二叉树的最大深度、8字符串转换整数(atoi)、82删除排序链表中的重复元素II、204二分查找、94二叉树的中序遍历、144二叉树的前序遍历

    Top1:Leetcode 129求根节点到叶节点数字之和 官方题解:https://leetcode.cn/problems/sum-root-to-leaf-numbers/solution/qi ...

  6. python实现mysql二叉树_python环境下使用mysql数据及数据结构和二叉树算法(图)...

    python环境下使用mysql数据及数据结构和二叉树算法(图): 1 python环境下使用mysql 2使用的是 pymysql库 3 开始-->创建connection-->获取cu ...

  7. 图论算法—图的拓扑排序介绍和Kahn算法原理解析以及Java代码的实现

    详细介绍了图的拓扑排序的概念,然后介绍了求拓扑序列的算法:Kahn算法的原理,最后提供了基于邻接矩阵和邻接表的图对该算法的Java实现. 阅读本文需要一定的图的基础,如果对于图不是太明白的可以看看这篇 ...

  8. 图 相关算法~从头学算法【广搜、 深搜、 拓扑排序、 并查集、 弗洛伊德算法、迪杰斯特拉算法】

    图的相关主流算法主要有: 广度优先搜索 深度优先搜索 拓扑排序 并查集 多源最短路径(弗洛伊德算法) 单源最短路径(迪杰斯特拉算法) 其中呢,最基本的是前两种,也就是平时常用的广搜和深搜,本文中将概要 ...

  9. 链表排序---迭代版本归并算法 + [leetcode]148. 排序链表

    前言: 对于链表来说,排序首选应该是归并算法 维基百科上有归并算法的迭代版本和递归版本 基于数组实现的. https://zh.wikipedia.org/wiki/%E5%BD%92%E5%B9%B ...

最新文章

  1. HarmonyOS 修改App 的name
  2. 除了Tapd,还有哪些好用的项目管理工具,适用于100+人的大中型团队?
  3. java垃圾回收system_java应用性能调优之详解System的gc垃圾回收方法
  4. Resin禁止目录访问
  5. 25 个 Java 机器学习工具和库
  6. python漏洞检测脚本_URL重定向漏洞,python打造URL重定向漏洞检测脚本
  7. 快速排序的原理以及Java代码
  8. 解决配置linux环境每次重新连接都需要bash ~/.bashrc的问题
  9. 在matlab下实现TDOA定位算法性能仿真
  10. .net c#购物车模块分析
  11. linux 文件同步脚本,Linux rsync同步文件脚本
  12. XCode应该是从11.4开始支持Sandbox
  13. SPSS 随机区组秩和检验
  14. 激活windows错误代码 0x80072F8F
  15. zigbee CC2530 系列教程 8 AD采集内部温度实验
  16. Filebeat Filter - Dissect/DNS Reverse
  17. 迅雷磁盘缓存设置过高会影响其它网络应用软件的速度
  18. linux格式化为fat,linux下把u盘格式化成 FAT32的例子
  19. OpenCV2:特征匹配及其优化
  20. BlockingQueue 详解

热门文章

  1. Stackoverflow热门问题(七)-为什么printf在遇到新行时才清空缓冲区,而不是调用后立即清空?
  2. R语言中利用jiebaR包实现中文分词
  3. html菜单三条横线,Word上怎么制作就三条横线的表格?
  4. 课堂 教程 小希与阿树漫画 前端
  5. WebRTC中音频能量计算
  6. 用DW制作图文混排网页
  7. Java中使用StringUtils需要导入的maven依赖
  8. java打印等腰三角形和倒立等腰三角形
  9. 制造业信息化领域,采用迈特 MIt PDM/PLM3.8作为集成支撑平台 与UG、CATIA、PRO/E、SOLIDEDGE、SOLIDWORKS、MDT等三维CAD软件和常用二维CAD软件集成
  10. 在华硕笔记本(X43B)上安装Debian6声卡驱动