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