排序 链表 图 二叉树算法

本文深入探讨了数据结构中的链表、二叉树、图的遍历方法,包括广度优先搜索(BFS)、深度优先搜索(DFS)及其在求解最短路径问题上的应用。此外,详细介绍了多种排序算法,如快速排序、冒泡排序、插入排序、希尔排序、堆排序。同时,通过实例展示了图的邻接矩阵和邻接表表示,以及层次遍历生成树的方法。这些基础知识对于理解计算机科学至关重要。
摘要由CSDN通过智能技术生成
#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 则是第一个结点它的孩子为1
		if(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;
				
			}
			else
			  return 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;
//	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值