#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>
#define MaxSize 100
#define N 20
typedef char VertexType;
typedef int EdgeType;
typedef struct LNODE
{
int data;
struct LNODE * next;
}LNODE, *LinkList; // definition of the LinkList
typedef struct StackNode
{
int data;
int top;
int bottom;
}StackNode, *Stack; // definition of the Stack
typedef struct CTNode
{
int data;
struct CTNode *lchild;
struct CTNode *rchild;
}CTNode, *BiTree; // definition of the CT tree
typedef struct CSNode
{
char data;
struct CSNode* firstchild;
struct CSNode* nextsibling;
}CSNode, *BinTree; // definition of the CS tree
typedef struct QueueNode
{
BiTree *queue; //一个将来用作数组名的指针变量queue
int front;
int rear;
}QueueNode, *MatrixQueue; // definition of the queue
typedef struct MGraph
{
int vexnum, arcnum;//当前定点数和弧的数量
VertexType Vex[N]; //存定点第一个数组
EdgeType Edge[N][N]; //存边第一个数组
}MGraph; // Matrix Graph
typedef struct ArcNode
{
int adjvex; //边对应节点的下标
int weigth; //用于存储权值
struct ArcNode * nextarc; //链域,指向下一个邻接点 (边向顶点方向移动)
}ArcNode; //边表节点
typedef struct VNode
{
VertexType data; //存储顶点数据的信息
ArcNode *firstarc; //定点表对应边表的头指针 (顶点向边方向移动)
}VNode,AdjList[N]; //顶点表节点
typedef struct ALGraph
{
AdjList adjlist;
int vexnum;
int arcnum;
}ALGraph ,*AGraph; //宏观定义邻接表的大节点类型
typedef struct
{
VertexType vex[N];
EdgeType edge[N][N];
int vexnum, arcnum;
}MarixGraph;
LinkList createlist();
bool traverse_list(LinkList);
int length_of_the_list(LinkList);
void insert_elem(LinkList, int);
void Bubble_sort_list(LinkList);
void dele_elem(LinkList);
MatrixQueue init_q(MatrixQueue);
bool IsEmpty_q(MatrixQueue);
bool IsFull_q(MatrixQueue);
void enqueue(MatrixQueue, BiTree);
BiTree dequeue(MatrixQueue, BiTree);
void traverse_q(MatrixQueue);
BiTree create_tree(BiTree);
void Pretraverse_tree(BiTree);
void Midtraverse_tree(BiTree);
void Postraverse_tree(BiTree);
void Leveltraverse_tree(BiTree);
void Levelorder_sealed(BiTree);
int getheight(BiTree);
int BT_depth1(BiTree,int);
int Height(BiTree);
void CreateAdjListGraph(AGraph);
void PrintAdjListGraph(AGraph);
bool visited[MaxSize];
void BFS(AGraph,int);
void DFS(AGraph, int);
void SelectSort(LinkList);
void selectsort(LinkList);
void HeapSort(LinkList);
void ShellSort(LinkList);
void GetLongestPath(BiTree T, char currentpath[], int ¤tlength, char maxpath[], int &maxlength);
//main function content
void main()
{
CTNode K;
BiTree n = create_tree(&K); //这里有时候用直接空值变量会好点,有时候用取地址不报错
//Pretraverse_tree(n);
//Midtraverse_tree(n);
//Postraverse_tree(n);
//Leveltraverse_tree(n);
//Levelorder_sealed(n);
//int k=getheight(n);
//printf("%d\n",k);
//ALGraph G;
//CreateAdjListGraph(&G);
//PrintAdjListGraph(&G);
//LinkList a = createlist();
//selectsort(a);
//printf("\n");
//traverse_list(a);
char currentpath[N], maxpath[N];
int currentlength = 0, maxlength = 0;
GetLongestPath(n, currentpath, currentlength, maxpath, maxlength);
for (int i = 0; i <= maxlength; i++)
{
printf("%c ",maxpath[i]);
}
printf("\n");
}
//Linklist
LinkList createlist()
{
LinkList L, T;
int len, tmp;
printf("请输入链表的长度:\n");
scanf_s("%d", &len);
L = (LinkList)malloc(sizeof(LNODE));//作为一个头动态游标;指针不停地动,指向需要的地方。
T = L; //作为一个尾动态游标(尾指针T),精髓就在于这个尾巴是一个虚拟的尾巴,不是加在头结点后面的实体节点。
T->next = NULL;
for (int i = 1; i <= len; i++)
{
printf("请输入第%d个元素的值:\n", i);
scanf_s("%d", &tmp);
LinkList pBody = (LinkList)malloc(sizeof(LNODE));
pBody->data = tmp;
pBody->next = NULL;
/* **********************************************************************************************************/
T->next = pBody;// T->next:T访问它指向的当前节点的指针域的内容,指针域内容指向第二个节点。
T = pBody;//新生成的节点当做现在的尾节点(新节点的地址发送到尾指针T中,这样T就可以继续指向新节点了)
/* **********************************************************************************************************/
} //尾游标增加过一个节点之后当然需要移动位置,从而继续增加第二个节点,移动位置就是新节点的地址赋值给尾游标。
return L;
} //《尾插法实现单链表的创建》 2018.7.24
int length_of_the_list(LinkList K)
{
int length = 0;
LinkList cat = K->next;
while (cat->next != NULL)//利用尾指针指向的那个元素的指针域为null来判断是否游到表尾
{
length++;
cat = cat->next;//单链表顺序遍历的核心思想,从一个未知的虚拟地址空间cat开始,cat指向的那个不虚拟的实体里存放的下一个实体的地址
}
return length + 1;
}
void insert_elem(LinkList tiger, int m)
{
int i = 0;
LinkList snake = tiger->next; //遍历的时候要分情况
LinkList pBody = (LinkList)malloc(sizeof(LNODE));
pBody->data = 500;
for (i; i < m - 1; ++i)
{
snake = snake->next;
}
pBody->next = snake->next;
snake->next = pBody;
}
void dele_elem(LinkList lion)
{
int n;
LinkList fish = lion->next;
LinkList tmp = (LinkList)malloc(sizeof(LNODE));
printf("x后面的元素将被删除,请输入x:");
scanf_s("%d", &n);
for (int i = 0; i < n - 1; ++i)//假设要删除第一个元素后面的元素,那么一次都不需要循环,游标默认停留在第一个元素那,指向第一个元素。
{
fish = fish->next;
}
fish->next = fish->next->next;//单次覆盖即可达到目的。 把第三个节点的地址存放到第一个节点指针域中去就行了
}
void Bubble_sort_list(LinkList panda)
{
int i, j;
int k = length_of_the_list(panda);
LinkList bear = panda->next;
LinkList bear1 = bear;
LinkList eagle=(LNODE *)malloc(sizeof(LNODE));
printf("冒泡排序过后的元素依次为:\n");
for (i = 0; i < k; i++)
{
for (j = 0; j < k - 1; j++)
{
if (bear->data > bear->next->data)
{
eagle->data = bear->data;
bear->data = bear->next->data;
bear->next->data = eagle->data;
}
bear = bear->next;
}
bear = bear1;//从头开始计算,要不然bear游到了末尾就没法回头了
}
}
bool traverse_list(LinkList head)
{
LinkList p = head->next;
while (p)
{
printf("%d ",p->data);
p = p->next;
}
return true;
}
//Queue
MatrixQueue init_q(MatrixQueue m) //数组初始化
{
m->queue = (BiTree *)malloc(sizeof(CTNode)*MaxSize);
m->front = 0;
m->rear = 0;
return m;
}
bool IsFull_q(MatrixQueue s)
{
if ((s->rear + 1) % MaxSize == s->front)
return true;
else
return false;
}
bool IsEmpty_q(MatrixQueue m)
{
if (m->rear == m->front)
return true;
else
return false;
}
void enqueue(MatrixQueue c, BiTree val)
{
if (!IsFull_q(c))
{
c->queue[c->rear] = val;
c->rear = (c->rear + 1) % MaxSize;
}
else
printf("enqueue failure! \n");
}
BiTree dequeue(MatrixQueue d, BiTree val)
{
if (!IsEmpty_q(d))
{
val = d->queue[d->front];
d->front = (d->front + 1) % MaxSize;
return val;
}
else
{
printf("queue is full \n");
}
}
void traverse_q(MatrixQueue k)
{
int i = k->front;
while (i != k->rear)
{
printf("%d\n", k->queue[i]);
i = (i + 1) % MaxSize;
}
}
//CT Binary Tree
BiTree create_tree(BiTree t)
{
char ch;
scanf_s("%c", &ch, sizeof(ch));
if (ch == ' ')
{
t = NULL;
}
else
{
t = (BiTree)malloc(sizeof(CTNode));
t->data = ch;
t->lchild = create_tree(t->lchild);
t->rchild = create_tree(t->rchild);
}
return t;
}
void Pretraverse_tree(BiTree P)
{
int top = 0;
CTNode *stack[N]; //又是因为直接写Bitree会出问题,写成这种原类型的形式比较好
while (P || top != 0)
{
if (P != NULL)
{
printf("%c", P->data); //cat非空,打印cat
stack[++top] = P; // 保存好cat 准备下一步深入底层
P = P->lchild; //cat游标进入左孩子,上面的信息由当前数组栈的top下表所指向
}
else
{
P = stack[top--]->rchild;//你发现没有,top始终不会沉底,始终比cat高一层
}
}
printf("先序遍历结束!\n");
}
void Midtraverse_tree(BiTree dog)
{
char ch;
scanf_s("%c", &ch, sizeof(ch));
int top = 0;
CTNode *stack[N];
while (dog || top != 0)
{
if (dog != NULL)
{
stack[++top] = dog;
dog = dog->lchild;
}
else
{
printf("%c", stack[top]->data);
dog = stack[top--]->rchild;
}
}
printf("中序遍历结束!\n");
}
void Postraverse_tree(BiTree puma)
{
int top = -1;
int flag[N];
CTNode * stack[N];
while (puma || top != -1)
{
if (puma != NULL)
{
stack[++top] = puma;
flag[top] = 0;
puma = puma->lchild;
}
else if (flag[top] == 0)//puma游标所指的节点虽然是空的,但是此节点左孩子已被访问
{
puma = stack[top]->rchild;
flag[top] = 1;
}
else
{
printf("%c", stack[top--]->data);
}
}
printf("后序遍历结束!\n");
}
void Leveltraverse_tree(BiTree eagle)
{
BiTree queue[N];
int rear = 0;
int front = 0;
queue[rear = (rear + 1) % N] = eagle;
while (rear>front)//这里有一个数学原理:就是说这个函数使用的队列不可能造成循环,是竖直线性结构rear一定不会在front后面
{
printf("%c", queue[front = (front + 1) % N]->data);
if (queue[front]->lchild != NULL)
{
queue[rear = (rear + 1) % N] = queue[front]->lchild;
}
if (queue[front]->rchild != NULL)
{
queue[rear = (rear + 1) % N] = queue[front]->rchild;
}
}
printf("非封装形式层次遍历结束\n");
}
void Levelorder_sealed(BiTree dragon)
{
CTNode val; //这里直接用BiTree val会报错,堆栈指针使用错误,用原类型然后取地址就可以
QueueNode k;
MatrixQueue S = init_q(&k); //这里也是,直接使用queue A=null 就会报错
enqueue(S, dragon);
while (!IsEmpty_q(S))
{
BiTree p = dequeue(S, &val);
printf("%c", p->data);
if (p->lchild != NULL)
{
enqueue(S, p->lchild);
}
if (p->rchild != NULL)
{
enqueue(S, p->rchild);
}
}
printf("封装形式层次遍历结束!\n"); //2018年12月7日 15:06:31 搞定了,花了两天多时间!!!!!
}
void getwidth(BinTree girl)
{
BinTree g = girl;
BinTree queue[N];
int front = 0;
int rear = 0;
int level = 0;
int count_of_level = 0;
queue[++rear] = g; count_of_level++;
while (rear != front)
{
if (queue[rear]->nextsibling != NULL)
{
queue[++rear] = g->nextsibling;
count_of_level++;
}
else
{
level++;
}
}
}
int getheight(BiTree m)
{
BiTree queue[N];
int front = 0, rear = 0, level = 0, last = 1;
queue[++rear] = m;
level++;
while (front < rear)
{
front++;
if (queue[front]->lchild)
{
queue[++rear] = queue[front]->lchild;
}
if (queue[front]->rchild)
{
queue[++rear] = queue[front]->rchild;
}
if (front==last)
{
last = rear; //第一行为1个元素自动赋值,当第一行遍历完成之后第二行所有元素其实已经被rear记录过了,这个总的值
level++; //放在last里记录一下就可以了。两个都在动,第几个车站是上一辆车经过并且停留过的要记录一下
}
}
return level;
}
int BT_depth1(BiTree T, int depth)
{
int max1 = 0;//树高
if (T)
{
if (T->lchild)
BT_depth1(T->lchild, depth + 1);
if (T->rchild)
BT_depth1(T->rchild, depth + 1);
}
if (depth>max1)
max1 = depth;
return depth;
}
void GetLongestPath(BiTree T, char currentpath[], int ¤tlength, char maxpath[], int &maxlength) //实时的长度放在currentlength里面存放
{
if (T)
{
if (T->lchild == NULL && T->rchild == NULL) //只需要触底的时候比一下现在实时的长度即可,不用比较高度,否则就变成了层序遍历问题,会复杂化。
{
currentpath[currentlength] = T->data;
if (currentlength > maxlength)
{
for (int i = 0; i <=currentlength; i++) //currentpath[]用递归方法,实时跟踪每一条路径的数组, maxpath[]:最长路径存放的数组,会不断刷新
{
maxpath[i] = currentpath[i];
}
maxlength = currentlength; //其实最长的长度+1就是树的高度,因为长度是由高度累加起来的,由边组成的。
}
}
else
{
currentpath[currentlength++] = T->data; //如果没有触底,那么很简单,直接入队,放在数组里存着,放在一个纯线性结构里面可以保存一路上遇到的所有节点的值。
GetLongestPath(T->lchild,currentpath,currentlength,maxpath,maxlength);//进入递归层之后是可以带着上一层的数值进行计算的,这一层要花不少时间,左孩子访问完了之后一直返回到第一层
GetLongestPath(T->rchild, currentpath, currentlength, maxpath, maxlength);//每次递归访问玩之后多加了一个节点???要减掉?????
currentlength--;
}
}
}
int Height(BiTree T)
{
if (T == NULL) return 0;
else
{
int m = Height(T->lchild); //递归求高度
int n = Height(T->rchild);
return (m > n) ? (m + 1) : (n + 1);
}
}
//Graph
void CreateAdjListGraph(AGraph G)
{
ArcNode *e;//将用边之属性将内存分配之
printf("please input the number of the Vertex:");
scanf_s("%d", &G->vexnum);
getchar();/*吃掉回车*/
printf("please input the number of the Arc:");
scanf_s("%d", &G->arcnum);
getchar();/*吃掉回车*/
for (int i = 0; i < G->vexnum;i++) //创建G.vexnum个定点
{
printf("input the node data(char):");
scanf_s("%c",&G->adjlist[i].data,sizeof(VertexType));
getchar();/*吃掉回车*/
G->adjlist[i].firstarc = NULL;
}
for (int m = 0; m < G->arcnum; m++) //创建G.arcnum个边
{
int k, j, w; //通过相邻两个节点的下标和他们之中的边的权重来创建一个无向图
printf("请输入相邻两个节点以及他们之间无向权重(三个整数):");
scanf_s("%d %d %d",&k,&j,&w);
e = (ArcNode *)malloc(sizeof(ArcNode));
e->adjvex = j; //边对应的点的下标
e->weigth = w; //边的权重
e->nextarc = G->adjlist[j].firstarc; //边的下一条边的地址是点表中首节点的地址
G->adjlist[k].firstarc = e;//分配一块内存给e,把e这个实际的节点挂到adjlist数组相应元素的指针域中
// 另一个节点要和上一个连上去
e = (ArcNode *)malloc(sizeof(ArcNode));
e->adjvex = k;
e->weigth = w;
e->nextarc = G->adjlist[k].firstarc;//通过边表节点建立两个相连的节点之间的关系
G->adjlist[j].firstarc = e;
}
}
void PrintAdjListGraph(AGraph G)
{
for (int i = 0; i < G->vexnum; i++) //遍历总次数=顶点数
{
ArcNode *p = G->adjlist[i].firstarc;
printf("Vertex节点内部数据域的值是:%c\n",G->adjlist[i].data);
while (p)
{
printf("第%d号顶点的权重值是:",p->adjvex);
printf("%d",p->weigth);
p = p->nextarc;
}
printf("\n");
}
printf("\n");
}
void BFS(AGraph G, int v) //
{
// ArcNode *p;
// MatrixQueue Q;
// init_q(Q);
// printf("%c",G->adjlist[p->adjvex].data);
// visited[v] = true;
// //enqueue(Q,v);
// while (!IsEmpty_q(Q))
// {
// //dequeue(Q,v);
// p = G->adjlist[v].firstarc;
// while (p)
// {
// if (!visited[p->adjvex])
// printf("%c", G->adjlist[p->adjvex].data);
// visited[p->adjvex] = true;
// enqueue(Q, p->adjvex);
// }
// p = p->nextarc;
// }
//
}
void DFS(AGraph G, int v)
{
// ArcNode *p;
// printf("%c", G->adjlist[p->adjvex].data);
// visited[v] = true;
// p = G->adjlist[v].firstarc;
// while (p)
// {
// if (!visited[v])
// {
// DFS(G,p->adjvex);
// }
// p = p->nextarc;
// }
}
//Search and Sort
void SelectSort(LinkList head)
{
LinkList p, q, r, tmp, S[N];
p = head->next; q = p; r = head;
int i =0, min = 0, minvalue = p->data;
while (q->next)
{
while (p)
{
S[i] = p;//每次重头到尾一次遍历,找到目前最小的值,把其节点的地址放入S【min】中保存
if (S[i]->data < minvalue)
{
minvalue = S[i]->data;//通过数组下标可以找到最小值对应节点在链表的位置
min = i; //printf(" \n running... %d %d ", min, S[i]->data);
}
i++;
p = p->next; //printf(" \n GTX460 %d %d %d", i, min, S[min]->data);
} //printf("S[%d]=%d \n", min,S[min]->data);
if (min == 0)
{
printf("jump!\n"); //如果最小值就存在于最前面的节点,那么是不用调整的,只需要将所有指针瞬移一格,然后把i和min重置为0,最新的最小值更新为这个节点下面一格节点的值即可
}
else if(q->next==S[min]) // 如果这个节点的值不是最小的,但是和最小节点相邻,那么只需要将这两个相邻节点指针互换位置即可
{
q->next = S[min]->next;
S[min]->next = q;
r->next = S[min];
}
else // 如果这个节点的值不是最小的,也不和最小的节点相邻,那么调整他们整体的位置(至少三个节点以上的调整)
{
tmp = q->next;
q->next = S[min]->next; //这里有可能是空值赋给了q的指针域
S[min - 1]->next = q; //printf("hello\n"); exit(-1);
S[min]->next = tmp;
r->next = S[min];
}
r = r->next; q = r->next; p = q;
i = min = 0; minvalue = p->data; //printf("current minnum is :%d\n", r->data); printf("next head is :%d\n", p->data); //exit(-1);
}
}
void selectsort(LinkList head)
{
int tmp;
LinkList p = head->next, q =NULL;
for (p; p; p = p->next)
{
q = p->next;
for (q; q; q = q->next)
{
if (p->data > q->data)
{
tmp = q->data;
q->data = p->data;
p->data = tmp;
}
}
}
}
void HeapSort(LinkList)
{
}
void ShellSort(LinkList)
{
}
bool TopologicalSort(AGraph G)
{
MatrixQueue a=NULL;
init_q(a);
for (int i = 0; i < G->vexnum; i++)
{
}
return true;
}
the code above is based on the compiler microsoft VisioStudio 2015
i will show the Mac Xcode version code here:
//
// main.cpp
// X21
//
// Created by novigard on 3/2/19.
// Copyright © 2019 novigard. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MaxSize 100
#define N 20
typedef char VertexType;
typedef int EdgeType;
typedef struct LNODE
{
int data;
struct LNODE * next;
}LNODE, *LinkList; // definition of the LinkList
typedef struct StackNode
{
int data;
int top;
int bottom;
}StackNode, *Stack; // definition of the Stack
typedef struct CTNode
{
int data;
struct CTNode *lchild;
struct CTNode *rchild;
}CTNode, *BiTree; // definition of the CT tree
typedef struct CSNode
{
char data;
struct CSNode* firstchild;
struct CSNode* nextsibling;
}CSNode, *BinTree; // definition of the CS tree
typedef struct QueueNode
{
BiTree *queue; //一个将来用作数组名的指针变量queue
int front;
int rear;
}QueueNode, *MatrixQueue; // definition of the queue
typedef struct MGraph
{
int vexnum, arcnum;//当前定点数和弧的数量
VertexType Vex[N]; //存定点第一个数组
EdgeType Edge[N][N]; //存边第一个数组
}MGraph; // Matrix Graph
typedef struct ArcNode
{
int adjvex; //边对应节点的下标
int weigth; //用于存储权值
struct ArcNode * nextarc; //链域,指向下一个邻接点 (边向顶点方向移动)
}ArcNode; //边表节点
typedef struct VNode
{
VertexType data; //存储顶点数据的信息
ArcNode *firstarc; //定点表对应边表的头指针 (顶点向边方向移动)
}VNode,AdjList[N]; //顶点表节点
typedef struct ALGraph
{
AdjList adjlist;
int vexnum;
int arcnum;
}ALGraph ,*AGraph; //宏观定义邻接表的大节点类型
typedef struct
{
VertexType vex[N];
EdgeType edge[N][N];
int vexnum, arcnum;
}MarixGraph;
LinkList createlist();
bool traverse_list(LinkList);
int length_of_the_list(LinkList);
void insert_elem(LinkList, int);
void Bubble_sort_list(LinkList);
void dele_elem(LinkList);
MatrixQueue init_q(MatrixQueue);
bool IsEmpty_q(MatrixQueue);
bool IsFull_q(MatrixQueue);
void enqueue(MatrixQueue, BiTree);
BiTree dequeue(MatrixQueue, BiTree);
void traverse_q(MatrixQueue);
BiTree create_tree(BiTree);
void Pretraverse_tree(BiTree);
void Midtraverse_tree(BiTree);
void Postraverse_tree(BiTree);
void Leveltraverse_tree(BiTree);
void Levelorder_sealed(BiTree);
int getheight(BiTree);
int BT_depth1(BiTree,int);
int Height(BiTree);
void CreateAdjListGraph(AGraph);
void PrintAdjListGraph(AGraph);
bool visited[MaxSize];
void BFS(AGraph,int);
void DFS(AGraph, int);
void SelectSort(LinkList);
void selectsort(LinkList);
void HeapSort(LinkList);
void ShellSort(LinkList);
void GetLongestPath(BiTree T, char currentpath[], int ¤tlength, char maxpath[], int &maxlength);
//main function content
int main()
{
CTNode M;
printf("hello russul\n");
BiTree B = create_tree(&M); //这里有时候用直接空值变量会好点,有时候用取地址不报错
Leveltraverse_tree(B);
//char currentpath[N], maxpath[N];
//int currentlength = 0, maxlength = 0;
//GetLongestPath(n, currentpath, currentlength, maxpath, maxlength);
/*for (int i = 0; i <= maxlength; i++)
{
printf("%c ",maxpath[i]);
}*/
}
//Linklist
LinkList createlist()
{
LinkList L, T;
int len, tmp;
printf("请输入链表的长度:\n");
scanf("%d", &len);
L = (LinkList)malloc(sizeof(LNODE));//作为一个头动态游标;指针不停地动,指向需要的地方。
T = L; //作为一个尾动态游标(尾指针T),精髓就在于这个尾巴是一个虚拟的尾巴,不是加在头结点后面的实体节点。
T->next = NULL;
for (int i = 1; i <= len; i++)
{
printf("请输入第%d个元素的值:\n", i);
scanf("%d", &tmp);
LinkList pBody = (LinkList)malloc(sizeof(LNODE));
pBody->data = tmp;
pBody->next = NULL;
/* **********************************************************************************************************/
T->next = pBody;// T->next:T访问它指向的当前节点的指针域的内容,指针域内容指向第二个节点。
T = pBody;//新生成的节点当做现在的尾节点(新节点的地址发送到尾指针T中,这样T就可以继续指向新节点了)
/* **********************************************************************************************************/
} //尾游标增加过一个节点之后当然需要移动位置,从而继续增加第二个节点,移动位置就是新节点的地址赋值给尾游标。
return L;
} //《尾插法实现单链表的创建》 2018.7.24
int length_of_the_list(LinkList K)
{
int length = 0;
LinkList cat = K->next;
while (cat->next != NULL)//利用尾指针指向的那个元素的指针域为null来判断是否游到表尾
{
length++;
cat = cat->next;//单链表顺序遍历的核心思想,从一个未知的虚拟地址空间cat开始,cat指向的那个不虚拟的实体里存放的下一个实体的地址
}
return length + 1;
}
void insert_elem(LinkList tiger, int m)
{
int i = 0;
LinkList snake = tiger->next; //遍历的时候要分情况
LinkList pBody = (LinkList)malloc(sizeof(LNODE));
pBody->data = 500;
for (i; i < m - 1; ++i)
{
snake = snake->next;
}
pBody->next = snake->next;
snake->next = pBody;
}
void dele_elem(LinkList lion)
{
int n;
LinkList fish = lion->next;
printf("x后面的元素将被删除,请输入x:");
scanf("%d", &n);
for (int i = 0; i < n - 1; ++i)//假设要删除第一个元素后面的元素,那么一次都不需要循环,游标默认停留在第一个元素那,指向第一个元素。
{
fish = fish->next;
}
fish->next = fish->next->next;//单次覆盖即可达到目的。 把第三个节点的地址存放到第一个节点指针域中去就行了
}
void Bubble_sort_list(LinkList panda)
{
int i, j;
int k = length_of_the_list(panda);
LinkList bear = panda->next;
LinkList bear1 = bear;
LinkList eagle=(LNODE *)malloc(sizeof(LNODE));
printf("冒泡排序过后的元素依次为:\n");
for (i = 0; i < k; i++)
{
for (j = 0; j < k - 1; j++)
{
if (bear->data > bear->next->data)
{
eagle->data = bear->data;
bear->data = bear->next->data;
bear->next->data = eagle->data;
}
bear = bear->next;
}
bear = bear1;//从头开始计算,要不然bear游到了末尾就没法回头了
}
}
bool traverse_list(LinkList head)
{
LinkList p = head->next;
while (p)
{
printf("%d ",p->data);
p = p->next;
}
return true;
}
//Queue
MatrixQueue init_q(MatrixQueue m) //数组初始化
{
m->queue = (BiTree *)malloc(sizeof(CTNode)*MaxSize);
m->front = 0;
m->rear = 0;
return m;
}
bool IsFull_q(MatrixQueue s)
{
if ((s->rear + 1) % MaxSize == s->front)
return true;
else
return false;
}
bool IsEmpty_q(MatrixQueue m)
{
if (m->rear == m->front)
return true;
else
return false;
}
void enqueue(MatrixQueue c, BiTree val)
{
if (!IsFull_q(c))
{
c->queue[c->rear] = val;
c->rear = (c->rear + 1) % MaxSize;
}
else
printf("enqueue failure! \n");
}
BiTree dequeue(MatrixQueue d, BiTree val)
{
if (!IsEmpty_q(d))
{
val = d->queue[d->front];
d->front = (d->front + 1) % MaxSize;
return val;
}
else
{
printf("queue is full \n");
}
return 0;
}
void traverse_q(MatrixQueue k)
{
int i = k->front;
while (i != k->rear)
{
printf("%d\n", k->queue[i]);
i = (i + 1) % MaxSize;
}
}
//CT Binary Tree
BiTree create_tree(BiTree t)
{
char ch;
scanf("%c",&ch);
if (ch == ' ')
{
t = NULL;
}
else
{
t = (BiTree)malloc(sizeof(CTNode));
t->data = ch;
t->lchild = create_tree(t->lchild);
t->rchild = create_tree(t->rchild);
}
return t;
}
void Pretraverse_tree(BiTree P)
{
int top = 0;
CTNode *stack[N]; //又是因为直接写Bitree会出问题,写成这种原类型的形式比较好
while (P || top != 0)
{
if (P != NULL)
{
printf("%c", P->data); //cat非空,打印cat
stack[++top] = P; // 保存好cat 准备下一步深入底层
P = P->lchild; //cat游标进入左孩子,上面的信息由当前数组栈的top下表所指向
}
else
{
P = stack[top--]->rchild;//你发现没有,top始终不会沉底,始终比cat高一层
}
}
printf("先序遍历结束!\n");
}
void Midtraverse_tree(BiTree dog)
{
char ch;
scanf("%c", &ch);
int top = 0;
CTNode *stack[N];
while (dog || top != 0)
{
if (dog != NULL)
{
stack[++top] = dog;
dog = dog->lchild;
}
else
{
printf("%c", stack[top]->data);
dog = stack[top--]->rchild;
}
}
printf("中序遍历结束!\n");
}
void Postraverse_tree(BiTree puma)
{
int top = -1;
int flag[N];
CTNode * stack[N];
while (puma || top != -1)
{
if (puma != NULL)
{
stack[++top] = puma;
flag[top] = 0;
puma = puma->lchild;
}
else if (flag[top] == 0)//puma游标所指的节点虽然是空的,但是此节点左孩子已被访问
{
puma = stack[top]->rchild;
flag[top] = 1;
}
else
{
printf("%c", stack[top--]->data);
}
}
printf("后序遍历结束!\n");
}
void Leveltraverse_tree(BiTree eagle)
{
BiTree queue[N];
int rear = 0;
int front = 0;
queue[rear = (rear + 1) % N] = eagle;
while (rear>front)//这里有一个数学原理:就是说这个函数使用的队列不可能造成循环,是竖直线性结构rear一定不会在front后面
{
printf("%c", queue[front = (front + 1) % N]->data);
if (queue[front]->lchild != NULL)
{
queue[rear = (rear + 1) % N] = queue[front]->lchild;
}
if (queue[front]->rchild != NULL)
{
queue[rear = (rear + 1) % N] = queue[front]->rchild;
}
}
printf("非封装形式层次遍历结束\n");
}
void Levelorder_sealed(BiTree dragon)
{
CTNode val; //这里直接用BiTree val会报错,堆栈指针使用错误,用原类型然后取地址就可以
QueueNode k;
MatrixQueue S = init_q(&k); //这里也是,直接使用queue A=null 就会报错
enqueue(S, dragon);
while (!IsEmpty_q(S))
{
BiTree p = dequeue(S, &val);
printf("%c", p->data);
if (p->lchild != NULL)
{
enqueue(S, p->lchild);
}
if (p->rchild != NULL)
{
enqueue(S, p->rchild);
}
}
printf("封装形式层次遍历结束!\n"); //2018年12月7日 15:06:31 搞定了,花了两天多时间!!!!!
}
void getwidth(BinTree girl)
{
BinTree g = girl;
BinTree queue[N];
int front = 0;
int rear = 0;
int level = 0;
int count_of_level = 0;
queue[++rear] = g; count_of_level++;
while (rear != front)
{
if (queue[rear]->nextsibling != NULL)
{
queue[++rear] = g->nextsibling;
count_of_level++;
}
else
{
level++;
}
}
}
int getheight(BiTree m)
{
BiTree queue[N];
int front = 0, rear = 0, level = 0, last = 1;
queue[++rear] = m;
level++;
while (front < rear)
{
front++;
if (queue[front]->lchild)
{
queue[++rear] = queue[front]->lchild;
}
if (queue[front]->rchild)
{
queue[++rear] = queue[front]->rchild;
}
if (front==last)
{
last = rear; //第一行为1个元素自动赋值,当第一行遍历完成之后第二行所有元素其实已经被rear记录过了,这个总的值
level++; //放在last里记录一下就可以了。两个都在动,第几个车站是上一辆车经过并且停留过的要记录一下
}
}
return level;
}
int BT_depth1(BiTree T, int depth)
{
int max1 = 0;//树高
if (T)
{
if (T->lchild)
BT_depth1(T->lchild, depth + 1);
if (T->rchild)
BT_depth1(T->rchild, depth + 1);
}
if (depth>max1)
max1 = depth;
return depth;
}
void GetLongestPath(BiTree T, char currentpath[], int ¤tlength, char maxpath[], int &maxlength) //实时的长度放在currentlength里面存放
{
if (T)
{
if (T->lchild == NULL && T->rchild == NULL) //只需要触底的时候比一下现在实时的长度即可,不用比较高度,否则就变成了层序遍历问题,会复杂化。
{
currentpath[currentlength] = T->data;
if (currentlength > maxlength)
{
for (int i = 0; i <=currentlength; i++) //currentpath[]用递归方法,实时跟踪每一条路径的数组, maxpath[]:最长路径存放的数组,会不断刷新
{
maxpath[i] = currentpath[i];
}
maxlength = currentlength; //其实最长的长度+1就是树的高度,因为长度是由高度累加起来的,由边组成的。
}
}
else
{
currentpath[currentlength++] = T->data; //如果没有触底,那么很简单,直接入队,放在数组里存着,放在一个纯线性结构里面可以保存一路上遇到的所有节点的值。
GetLongestPath(T->lchild,currentpath,currentlength,maxpath,maxlength);//进入递归层之后是可以带着上一层的数值进行计算的,这一层要花不少时间,左孩子访问完了之后一直返回到第一层
GetLongestPath(T->rchild, currentpath, currentlength, maxpath, maxlength);//每次递归访问玩之后多加了一个节点???要减掉?????
currentlength--;
}
}
}
int Height(BiTree T)
{
if (T == NULL) return 0;
else
{
int m = Height(T->lchild); //递归求高度
int n = Height(T->rchild);
return (m > n) ? (m + 1) : (n + 1);
}
}
//Graph
void CreateAdjListGraph(AGraph G)
{
ArcNode *e;//将用边之属性将内存分配之
printf("please input the number of the Vertex:");
scanf("%d", &G->vexnum);
getchar();/*吃掉回车*/
printf("please input the number of the Arc:");
scanf("%d", &G->arcnum);
getchar();/*吃掉回车*/
for (int i = 0; i < G->vexnum;i++) //创建G.vexnum个定点
{
printf("input the node data(char):");
scanf("%c",&G->adjlist[i].data);
getchar();/*吃掉回车*/
G->adjlist[i].firstarc = NULL;
}
for (int m = 0; m < G->arcnum; m++) //创建G.arcnum个边
{
int k, j, w; //通过相邻两个节点的下标和他们之中的边的权重来创建一个无向图
printf("请输入相邻两个节点以及他们之间无向权重(三个整数):");
scanf("%d %d %d",&k,&j,&w);
e = (ArcNode *)malloc(sizeof(ArcNode));
e->adjvex = j; //边对应的点的下标
e->weigth = w; //边的权重
e->nextarc = G->adjlist[j].firstarc; //边的下一条边的地址是点表中首节点的地址
G->adjlist[k].firstarc = e;//分配一块内存给e,把e这个实际的节点挂到adjlist数组相应元素的指针域中
// 另一个节点要和上一个连上去
e = (ArcNode *)malloc(sizeof(ArcNode));
e->adjvex = k;
e->weigth = w;
e->nextarc = G->adjlist[k].firstarc;//通过边表节点建立两个相连的节点之间的关系
G->adjlist[j].firstarc = e;
}
}
void PrintAdjListGraph(AGraph G)
{
for (int i = 0; i < G->vexnum; i++) //遍历总次数=顶点数
{
ArcNode *p = G->adjlist[i].firstarc;
printf("Vertex节点内部数据域的值是:%c\n",G->adjlist[i].data);
while (p)
{
printf("第%d号顶点的权重值是:",p->adjvex);
printf("%d",p->weigth);
p = p->nextarc;
}
printf("\n");
}
printf("\n");
}
void BFS(AGraph G, int v) //
{
// ArcNode *p;
// MatrixQueue Q;
// init_q(Q);
// printf("%c",G->adjlist[p->adjvex].data);
// visited[v] = true;
// //enqueue(Q,v);
// while (!IsEmpty_q(Q))
// {
// //dequeue(Q,v);
// p = G->adjlist[v].firstarc;
// while (p)
// {
// if (!visited[p->adjvex])
// printf("%c", G->adjlist[p->adjvex].data);
// visited[p->adjvex] = true;
// enqueue(Q, p->adjvex);
// }
// p = p->nextarc;
// }
//
}
void DFS(AGraph G, int v)
{
// ArcNode *p;
// printf("%c", G->adjlist[p->adjvex].data);
// visited[v] = true;
// p = G->adjlist[v].firstarc;
// while (p)
// {
// if (!visited[v])
// {
// DFS(G,p->adjvex);
// }
// p = p->nextarc;
// }
}
//Search and Sort
void SelectSort(LinkList head)
{
LinkList p, q, r, tmp, S[N];
p = head->next; q = p; r = head;
int i =0, min = 0, minvalue = p->data;
while (q->next)
{
while (p)
{
S[i] = p;//每次重头到尾一次遍历,找到目前最小的值,把其节点的地址放入S【min】中保存
if (S[i]->data < minvalue)
{
minvalue = S[i]->data;//通过数组下标可以找到最小值对应节点在链表的位置
min = i; //printf(" \n running... %d %d ", min, S[i]->data);
}
i++;
p = p->next; //printf(" \n GTX460 %d %d %d", i, min, S[min]->data);
} //printf("S[%d]=%d \n", min,S[min]->data);
if (min == 0)
{
printf("jump!\n"); //如果最小值就存在于最前面的节点,那么是不用调整的,只需要将所有指针瞬移一格,然后把i和min重置为0,最新的最小值更新为这个节点下面一格节点的值即可
}
else if(q->next==S[min]) // 如果这个节点的值不是最小的,但是和最小节点相邻,那么只需要将这两个相邻节点指针互换位置即可
{
q->next = S[min]->next;
S[min]->next = q;
r->next = S[min];
}
else // 如果这个节点的值不是最小的,也不和最小的节点相邻,那么调整他们整体的位置(至少三个节点以上的调整)
{
tmp = q->next;
q->next = S[min]->next; //这里有可能是空值赋给了q的指针域
S[min - 1]->next = q; //printf("hello\n"); exit(-1);
S[min]->next = tmp;
r->next = S[min];
}
r = r->next; q = r->next; p = q;
i = min = 0; minvalue = p->data; //printf("current minnum is :%d\n", r->data); printf("next head is :%d\n", p->data); //exit(-1);
}
}
void selectsort(LinkList head)
{
int tmp;
LinkList p = head->next, q =NULL;
for (p; p; p = p->next)
{
q = p->next;
for (q; q; q = q->next)
{
if (p->data > q->data)
{
tmp = q->data;
q->data = p->data;
p->data = tmp;
}
}
}
}
void HeapSort(LinkList)
{
}
void ShellSort(LinkList)
{
}
bool TopologicalSort(AGraph G)
{
MatrixQueue a=NULL;
init_q(a);
for (int i = 0; i < G->vexnum; i++)
{
}
return true;
}