1.二叉树的构建、遍历和完全二叉树的判断
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MaxSize 100
using namespace std;
typedef char ElemType;
typedef struct node {
ElemType data;
struct node* lchild;
struct node* rchild;
}BTNode;
//实例化二叉树
void BT_Create(BTNode*& b, const char* str) {
BTNode* St[MaxSize], * p=NULL;
int top = -1 , k , j = 0;
char ch;
b = NULL;
ch = str[j];
//str未结束时循环
while (ch != '\0') {
switch (ch) {
case '(':top++; St[top] = p; k = 1; break;//处理左子树
case ')':top--; break;//处理完毕一个子树
case ',':k = 2; break;//开始处理右子树(括号中‘,’右边的是右子树,左边是左子树)
default:p = (BTNode*)malloc(sizeof(BTNode));
p->data = ch;
p->lchild = p->rchild = NULL;//对该小枝叉进行初始化
if (b == NULL)
b = p;//若b树为空,则将p设为b的root节点
else {
switch (k) {
case 1:St[top]->lchild = p; break;
case 2:St[top]->rchild = p; break;
}
}
}
j++;
ch = str[j];
}
}
void BT_Destory(BTNode* &b) {
if (b != NULL) {
BT_Destory(b->lchild);
BT_Destory(b->rchild);
free(b);
}
}
BTNode* BT_FindNode(BTNode* b, ElemType x) {
BTNode* p;
if (b == NULL) {
return NULL;
}
else if (b->data == x)
return b;
else {
p = BT_FindNode(b->lchild, x);
if (p != NULL)
return p;
else
return BT_FindNode(b->rchild, x);
}
}
BTNode* BT_LchildNode(BTNode* b) {
return b->lchild;
}
BTNode* BT_RchildNode(BTNode* b) {
return b->rchild;
}
int BT_Height(BTNode* b) {
int lchildh, rchildh;
if (b == NULL)
return 0;
else {
lchildh = BT_Height(b->lchild);
rchildh = BT_Height(b->rchild);
return 1 + max(rchildh, lchildh);
}
}
void BT_Display(BTNode* b) {
if (b != NULL) {
printf("%c", b->data);
if (b->lchild != NULL || b->rchild != NULL) {
printf("(");
BT_Display(b->lchild);
if (b->rchild != NULL)
printf(",");
BT_Display(b->rchild);
printf(")");
}
}
}
//测试
/*
int main()
{
BTNode* b, * p, * lp, * rp;
printf("创建二叉树:\n");
BT_Create(b,"A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))");
printf("输出二叉树:\n");
BT_Display(b);
printf("\n");
printf("H节点:\n");
p = BT_FindNode(b, 'H');
if (p != NULL) {
lp = BT_LchildNode(p);
if (lp != NULL)
printf("lchild:%c", lp->data);
else printf("lchild is NULL ");
printf("\n");
rp = BT_RchildNode(p);
if (rp != NULL)
printf("rchild:%c", rp->data);
else printf("rchild is NULL ");
}
printf("\n");
printf("the BT_Height is :%d\n", BT_Height(b));
printf("free the BT\n");
BT_Destory(b);
return 0;
}
*/
//二叉树的几种遍历算法
//先序遍历递归
void PreOrder(BTNode* b) {
if (b != NULL) {
printf("%c", b->data);
PreOrder(b->lchild);
PreOrder(b->rchild);
}
}
//先序遍历非递归
void PreOrder1(BTNode* b) {
BTNode* St[MaxSize], * p;
int top = -1;
if (b != NULL) {
top++;
St[top] = b;
while (top > -1) {
//中
p = St[top];
top--;
printf("%c", p->data);
//右
if (p->rchild != NULL) {
top ++ ;
St[top] = p->rchild;
}
//左
if (p->lchild != NULL) {
top++;
St[top] = p->lchild;
}
}
printf("\n");
}
//用数组St[MaxSize]存遍历过的节点
//因为是按顺序栈来存,因此进栈顺序为中->右->左,出栈后得正常的前序序列
}
//中序遍历递归
void InOrder(BTNode* b) {
if (b != NULL) {
//前->中->后
InOrder(b->lchild);
printf("%c", b->data);
InOrder(b->rchild);
}
}
//中序遍历非递归
void InOrder1(BTNode* b) {
BTNode* St[MaxSize], * p;
int top = -1;
if (b != NULL) {
p = b;
while (top > -1 || p != NULL) {
while (p != NULL) {
top++;
St[top] = p;
p = p->lchild;
}
if (top > -1) {
p = St[top];
top--;
printf(" % c", p->data);
p = p->rchild;
}
}
printf("\n");
}
}
//后序遍历递归
void PostOrder(BTNode* b) {
if (b != NULL) {
PostOrder(b->lchild);
PostOrder(b->rchild);
printf("%c", b->data);
}
}
//后序遍历非递归
void PostOrder1(BTNode* b) {
BTNode* St[MaxSize],*p;
int top = -1;
bool flag;
if (b != NULL) {
do {
while (b != NULL) {
top++;
St[top] = b;
b = b->lchild;
}
p = NULL;
flag = true;
while (top != -1 && flag) {
b = St[top];
if (b->rchild == p) {
printf("%c", b->data);
top--;
p = b;
}
else {
b = b->rchild;
flag = false;
}
}
}while (top != -1);
printf("\n");
}
}
//层序遍历
void TravLevel(BTNode* b) {
BTNode* Qu[MaxSize];
int front=0, rear=0;
if (b != NULL)printf("%c", b->data);
rear++;
Qu[rear] = b;
while(rear!=front){
front = (front + 1) % MaxSize;
b = Qu[front];
if(b->lchild!=NULL){
printf("%c", b->lchild->data);
rear = (rear + 1) % MaxSize;
Qu[rear] = b->rchild;
}
if (b->rchild != NULL) {
printf("%c", b->rchild->data);
rear = (rear + 1) % MaxSize;
Qu[rear] = b->rchild;
}
}
printf("\n");
}
//测试
/*
int main()
{
BTNode* b;
BT_Create(b,"A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))");
printf("二叉树b:\n");
BT_Display(b);
printf("\n");
printf("层次遍历:\n");
printf("先序遍历:\n");
printf("递归算法:\n"); PreOrder(b); printf("\n");
printf("非递归:\n"); PreOrder1(b); printf("\n");
printf("中序遍历:\n");
printf("递归算法:\n");InOrder(b); printf("\n");
printf("非递归:\n"); InOrder1(b); printf("\n");
printf("后序遍历:\n");
printf("递归算法:\n"); PostOrder(b); printf("\n");
printf("非递归:\n"); PostOrder1(b); printf("\n");
BT_Destory(b);
return 0;
}
*/
//判断二叉树是否为完全二叉树
bool Full_TravLevel(BTNode* b) {
BTNode* Qu[MaxSize];
int front = 0, rear = 0;
int t = 0, depth = BT_Height(b);
bool flag = true;
if (b != NULL)printf("%c", b->data);
rear++;
Qu[rear] = b;
t++;
while (rear != front) {
t++;
front = (front + 1) % MaxSize;
b = Qu[front];
if (b->lchild != NULL) {
printf("%c", b->lchild->data);
rear = (rear + 1) % MaxSize;
Qu[rear] = b->lchild;
if ((b->rchild == NULL) && t < (int)pow(2, (depth - 1)))
return false;
}
if (b->rchild != NULL) {
printf("%c", b->rchild->data);
rear = (rear + 1) % MaxSize;
Qu[rear] = b->rchild;
}
if ((b->lchild == NULL || b->rchild == NULL) && t < depth - 1) {
return false;
}
if (b->lchild == NULL && b->rchild != NULL)
return false;
}
printf("\n");
return flag;
}
2.图的基本算法和遍历(DFS/BFS)
#include <stdio.h>
#include <malloc.h>
#define INF 32767
#define MAXV 100
typedef char InfoType;
typedef struct {
int no;//顶点编号
InfoType info;//顶点其他信息
}VertexType;//顶点类型
typedef struct {
int edges[MAXV][MAXV];//邻接矩阵数组
int n, e;//顶点数,边数
VertexType vexs[MAXV];//存放顶点信息
}MatGraph;//完整的图邻接矩阵类型
typedef struct ANode {
int adjvex;//该边的邻接点编号
struct ANode* nextarc;//指向下一条边的指针
int weight;//该边的相关信息,如权值
}ArcNode;//边节点类型
typedef struct Vnode {
InfoType info;//顶点其他信息
int count;//存放顶点入度,仅仅用于拓扑排序
ArcNode* firstarc;//指向第一条边
}VNode;//邻接表头节点类型
typedef struct {
VNode* adjlist[MAXV];//邻接表头节点数组
int n, e;//图中顶点数n和边数e
}AdjGraph;//完整的图邻接表类型
void G_CreateMat(MatGraph& g, int A[MAXV][MAXV], int n, int e) {
int i, j;
g.n = n; g.e = e;
for (i = 0; i < g.n; i++)
for (j = 0; j < g.e; j++)
g.edges[i][j] = A[i][j];
}
void DispMat(MatGraph g) {
int i, j;
for ( i = 0; i < g.n; i++) {
for (j = 0; j < g.e; j++)
if (g.edges[i][j] != INF)
printf("%4d", g.edges[i][j]);
else printf("%4s", "INF");
printf("\n");
}
}
//邻接表
void CreateAdj(AdjGraph*& G, int A[MAXV][MAXV], int n, int e) {
int i, j;
ArcNode* p;
G = (AdjGraph *)malloc(sizeof(AdjGraph));
for (i = 0; i < n; i++)
G->adjlist[i]->firstarc = NULL;
for (i = 0; i < n; i++)
for (j = n - 1; j >= 0; j--)
if (A[i][j] != 0 && A[i][j] != INF) {
p = (ArcNode*)malloc(sizeof(ArcNode));
p->adjvex = j;
p->weight = A[i][j];
p->nextarc = G->adjlist[i]->firstarc;
G->adjlist[i]->firstarc = p;
}
G->n = n;
G->e = e;
}
void DispAdj(AdjGraph* G) {
ArcNode* p;
for (int i = 0; i < G->n; i++) {
p = G->adjlist[i]->firstarc;
printf("%3d:", i);
while (p != NULL) {
printf("%3d[%d]->",p->adjvex,p->weight);
p = p->nextarc;
}
printf("^\n");
}
}
void DestoryAdj(AdjGraph*& G) {
ArcNode* pre, * p;
for(int i=0;i<G->n;i++){
pre = G->adjlist[i]->firstarc;
if (pre != NULL) {
p = pre->nextarc;
while (p != NULL) {
free(pre);
pre = p;
p = p->nextarc;
}
free(pre);
}
}
free(G);
}
int visited[MAXV];
void DFS(AdjGraph* G, int v) {
ArcNode* p;
printf("%3d", v); visited[v] = 1;
p = G->adjlist[v]->firstarc;
while (p != NULL) {
if (visited[p->adjvex] == 0)
DFS(G, p->adjvex);
p = p->nextarc;
}
}
//测试
/*
int main()
{
MatGraph g;
AdjGraph* G;
int A[MAXV][MAXV] = {
{0,5,INF,7,INF,INF},{INF,0,4,INF,INF,INF},
{8,INF,0,INF,INF,9},{INF,INF,5,0,INF,6},
{INF,INF,INF,5,0,INF},{3,INF,INF,INF,1,0}
};
int n = 6, e = 10;
G_CreateMat(g, A, n, e);
printf("(1)图的邻接矩阵:\n"); DispMat(g);
CreateAdj(G, A, n, e);
printf("(2)图的邻接表:\n"); DispAdj(G);
printf("(3销毁图的邻接表\n)");
DestoryAdj(G);
return 1;
}
*/
//DFS和BFS
int visited[MAXV];
void DFS(AdjGraph* G, int v) {
ArcNode* p;
printf("%3d", v); visited[v] = 1;
p = G->adjlist[v]->firstarc;
while (p != NULL) {
if (visited[p->adjvex] == 0)
DFS(G, p->adjvex);
p = p->nextarc;
}
}
void DFS1(AdjGraph* G, int v) {
ArcNode* p;
int St[MAXV];
int top = -1,w,x,i;
for (i = 0; i < G->n; i++)
visited[i] = 0;
printf("%3d", v);
visited[v] = 1;
top++; St[top] = v;
while (top > -1) {
x = St[top];
p = G->adjlist[x]->firstarc;
while (p != NULL) {
w = p->adjvex;
if(visited[w]==0){
printf("%3d", w);
visited[w] = 1;
top++;
St[top] = w;
break;//退出循环处理栈顶的顶点
}
p = p->nextarc;
}
if (p == NULL)top--;
}
printf("\n");
}
void BFS(AdjGraph* G, int v) {
ArcNode* p;
int queue[MAXV], front = 0, rear = 0;//定义环形队列并进行初始化
int visited[MAXV];//定义存放顶点的访问标志的数组
int w,i;
for (i = 0; i < G->n; i++) {
visited[i] = 0;//访问数组标志初始化
}
printf(" % 3d", v);//输出被访问顶点的编号
visited[v] = 1;//置已访问标记
rear = (rear + 1) % MAXV;
queue[rear] = v;//v进队
while (front != rear) {
front = (front + 1) % MAXV;
w = queue[front];//出队并赋值给w
p = G->adjlist[w]->firstarc;//找顶点w的第一个相邻点
while (p != NULL) {
if (visited[p->adjvex] == 0) {//若相邻点未被访问
printf("%3d", p->adjvex);//访问该相邻点
visited[p->adjvex] = 1;//置已访问标记
rear = (rear + 1) % MAXV;//该顶点进队
queue[rear] = p->adjvex;
}
p = p->nextarc;//找下一个相邻点
}
}
printf("\n");
}
//测试
/*
int main() {
AdjGraph* G;
int A[MAXV][MAXV] = {
{0,5,INF,7,INF,INF},{INF,0,4,INF,INF,INF},
{8,INF,0,INF,INF,9},{INF,INF,5,0,INF,6},
{INF,INF,INF,5,0,INF},{3,INF,INF,INF,1,0}
};
int n = 6, e = 10;
CreateAdj(G, A, n, e);
printf("图G的邻接表:\n");
DispAdj(G);
printf("从顶点0开始的DFS:\n");
DFS(G, 0); printf("\n");//递归
printf("从顶点0开始的DFS1:\n");
DFS1(G, 0); printf("\n");//非递归
printf("从顶点0开始的BFS:\n");
BFS(G, 0);
DestoryAdj(G);
return 1;
}
*/