DateConflict
#include <stdio.h>
/*
step1:将图的结点按照结点度的大小进行递减排序(相同度的节点次序没有要求)
step2:用第一种颜色对第一个节点进行着色,并按照节点排序,对与前面着色
点不邻接的每一个节点进行上色
step:用第二种颜色重复步骤2,直到没有剩余的颜色
课程编号={1, 2, 3, 4, 5, 6, 7, 8, 9}
冲突课程R={(2, 8), (9, 4), (2, 9), (2, 1), (2, 5), (6, 2), (5, 9), (5, 6), (5, 4), (7, 5), (7, 6), (3, 7), (6, 3)}
*/
#define VERTEX_NUM 9
typedef int ElemType;
typedef struct {
ElemType VertexArray[VERTEX_NUM];
int AdjMatrix[VERTEX_NUM][VERTEX_NUM];
}AM_GRAPH;
//创建邻接矩阵
void Create_AdjMatrix(AM_GRAPH* pGraphMatrix, ElemType vertex[]) {
for (int i = 0;i < VERTEX_NUM;i++) {
pGraphMatrix->VertexArray[i] = vertex[i];
}
for (int i = 0;i < VERTEX_NUM;i++) {
for (int j = 0;j < VERTEX_NUM;j++) {
pGraphMatrix->AdjMatrix[i][j] = 0;
}
}
char *pStr[] = {
"2,8","9,4","2,9","2,1","2,5",
"6,2","5,9","5,6","5,4","7,5",
"7,6","3,7","6,3"
};
//假定顶点只有一个个位数
for (int k = 0;k < 13;k++) {
int i = *(pStr[k]) - '1';
int j = *(pStr[k] + 2) - '1';
pGraphMatrix->AdjMatrix[i][j] = 1;
pGraphMatrix->AdjMatrix[j][i] = 1;
}
}
void ShowMatrix(AM_GRAPH* pGraphMatrix) {
for (int i = 0;i < VERTEX_NUM;i++) {
for (int j = 0;j < VERTEX_NUM;j++) {
printf("%d ", pGraphMatrix->AdjMatrix[i][j]);
}
printf("\n");
}
}
#define TRUE 1
#define FALSE 0
int degree[VERTEX_NUM] = { 0 };//记录每一个顶点的度的数目
//最坏的情况,每一个节点独立着色
char *color[VERTEX_NUM] = {
"赤","橙","黄","绿","青","蓝","紫"
};
//设计一个颜色的辅助数据结构,用来标记颜色是否使用
struct ColorNode {
int used;//表示是否当前的这个颜色是否已经被使用,0:没有使用
int rear;//顶点集合的指针
int node[VERTEX_NUM];//同色顶点的集合
}ColorSet[VERTEX_NUM] = { {0,0,0,0} };
//找当前度最大的节点
//输入的是degree数组
//输出的是当前最大度的节点下标
int FindMax(int a[]) {
int i, value, index;
value = -1;
index = 0;
for (i = 0;i < VERTEX_NUM;i++) {
if (value < a[i]) {
value = a[i];
index = i;
}
}
a[index] = -1;//清楚当前的最大值,
return index;//index是寻找的角标
}
//判断输入的k节点,能否加入已经存在的colorSet集合中
//输入的i是第i种颜色,k是当前的待扫描的节点
//返回值1是可以加入colorset,0不可以
int judge(int i, int k, AM_GRAPH *pGraphMatrix) {
int p, q, m;
p = 0;//用来表示当前颜色节点中下标为p的节点
q = ColorSet[i].rear;// q表示了当前第i种颜色有几个节点
//首先要判断一下在k节点和p节点中,不存在冲突关系
m = ColorSet[i].node[p];
while (pGraphMatrix->AdjMatrix[k][m] == 0 && p != ColorSet[i].rear) {
p++;
m = ColorSet[i].node[p];
}
if (p == q)
return 1;//说明p的扫描恰好等于第i种颜色的最后一个,这说明在当前的第i种颜色中,当前的k不予任何一个已经作了第i中颜色的节点冲突
return 0;
}
//WP方法
void WelshPowell(AM_GRAPH* pGraphMatrix) {
int i, k;
int colorPtr;
//计算顶点的度
for (i = 0;i < VERTEX_NUM;i++) {
for (int j = 0;j < VERTEX_NUM;j++) {
if (i != j && pGraphMatrix->AdjMatrix[i][j]) {
degree[i]++;
}
}
}
//扫描得到度最大的节点
for (int j = 0;j < VERTEX_NUM;j++) {
//寻找度最大的节点
k = FindMax(degree);
colorPtr = 0;
//假定一下ColorPtr所对应颜色已经被用
if (ColorSet[colorPtr].used == 1) {
//就要扫描colorPtr对应的分量颜色,能不能把当前的k节点加入
while (!judge(colorPtr, k, pGraphMatrix))
colorPtr++;
}
//colorPtr一定停在了k可以加入的颜色行里
ColorSet[colorPtr].node[ColorSet[colorPtr].rear++] = k;
if (ColorSet[colorPtr].used == 0) {
ColorSet[colorPtr].used = 1;
}
}
//输出同色节点
for (int j = 0;j < VERTEX_NUM;j++) {
if (ColorSet[j].used == 1) {
printf("%s:", color[j]);
}
for (int k = 0;k < ColorSet[j].rear;k++) {
printf("%d ", ColorSet[j].node[k] + 1);
}
printf("\n");
}
}
int main(void) {
ElemType vertex[] = { 0,1,2,3,4,5,6,7,8 };
AM_GRAPH myGraph;
Create_AdjMatrix(&myGraph, vertex);
ShowMatrix(&myGraph);
WelshPowell(&myGraph);
getchar();
return 0;
}
GenTree
//Prim算法
#define VERTEX_NUM 6
#define MAX 32767 //沒有联通,此时权值定位32767
int AdjMatrix[VERTEX_NUM][VERTEX_NUM] = {
{MAX,6,1,5,MAX,MAX},
{6,MAX,5,MAX,3,MAX},
{1,5,MAX,5,6,4},
{5,MAX,5,MAX,MAX,2},
{MAX,3,6,MAX,MAX,6},
{MAX,MAX,4,2,6,MAX}
};
//传入的参数v表示从第v个节点开始构建候选集合
void prim(int v) {
int i, j;//循环变量
int k;//k用来标记,访问节点的角标,其中0角标对应A节点
struct set
{
int startNode[VERTEX_NUM];
int endNode[VERTEX_NUM];
int value[VERTEX_NUM];
}edgeSet;//候选边集
int Visited[VERTEX_NUM] = { 0 };//表示节点是否都已经访问过了
int min;//候选边集中的最小权值
for (i = 0;i < VERTEX_NUM;i++) {
if (i != v) {
//现在只要不是传入的开始节点,那么我就将候选边集
//全部设成从v到i
edgeSet.startNode[i] = v;
edgeSet.endNode[i] = i;
edgeSet.value[i] = AdjMatrix[v][i];//v,i不能反,因为根据定义[v,i]对应就是从
//v到i的权值
}
}
//到了此处,说明构建从v到i的所有候选边集合构建完成了
edgeSet.startNode[v] = v;
edgeSet.endNode[v] = v;
edgeSet.value[v] = MAX;
//我假定,我传入的是从0开始
//i表示对从1开始,所有对应的角标的节点,都穷举一遍
//从而保证,只要在联通的过程中,和对应节点相关的最小权值边一定在集合中
for (i = 1;i < VERTEX_NUM;i++) {//i是对应的节点角标
min = MAX;
//在候选边集合中,我们要查找没有加入当前顶点,且权值最小的
//k是临时记录变量,它在j的for循环中,找到当前节点相关权值最小的终点
//角标
for (j = 0;j < VERTEX_NUM;j++) {
if (edgeSet.value[j] < min&& Visited[j] == 0) {
min = edgeSet.value[j];
k = j;// 记录最小权值的终节点角标位置
}
}
//将k加入下一轮的初始顶点
Visited[k] = 1;
//每一轮选过之后,我们就把当前可以确定的边信息输出
if(min !=MAX){
printf("(%c,%c)[%d]==>", edgeSet.startNode[k] + 'A', k + 'A', min);
}
//调整k成为下一轮的候选边的初始顶点
for (j = 0;j < VERTEX_NUM;j++) {
if (AdjMatrix[j][k] < edgeSet.value[j] && j != v) {
edgeSet.value[j] = AdjMatrix[j][k];
edgeSet.startNode[j] = k;
}
}
}
}
int main() {
prim(0);
getchar();
return 0;
}
//Krukal
//#include <stdio.h>
//#define VERTEX_NUM 6
////建立一个边集数组
//typedef struct {
// char start_vex;//起点
// char end_vex;//终点
// int weight;//权重
// int single;//当前边是否可以加入,0为初值,1为加入
//}EdgeStruct;
////只要按权值有序排放在EdgeStruct[]数组中
////双亲节点数组
//
//
//void Kruskal(EdgeStruct EdgeSet[], int edge_num, int vertex_num) {
// int parent[VERTEX_NUM];//记录各个顶点的根,负值表示本集合中的节点个数
//
// int i, k;
// int num = 0;
// int v1Root, v2Root;
// int LRoot, SRoot;//LRoot表示大集合的根,SRoot表示小集合的根
//
// char LVertex, SVertex;
//
// for (i = 0;i < vertex_num;i++)
// parent[i] = -1;
//
// i = 0;k = 0;
// while (k < edge_num && num < vertex_num) {
// //查找start_vex的根v1Root
// v1Root = (EdgeSet[k].start_vex - 'A');//角标0存的是A的节点
// while (parent[v1Root] >= 0)
// v1Root = parent[v1Root];
// //查找end_vex的根v2Root
// v2Root = (EdgeSet[k].end_vex - 'A');
// while (parent[v2Root] >= 0)
// v2Root = parent[v2Root];
//
// //将s集合合并到L集合中
// if (parent[v1Root] <= parent[v2Root]) {
// LRoot = v1Root;
// SRoot = v2Root;
// LVertex = EdgeSet[k].start_vex;
// SVertex = EdgeSet[k].end_vex;
// }
// else {
// LRoot = v2Root;
// SRoot = v1Root;
// LVertex = EdgeSet[k].end_vex;
// SVertex = EdgeSet[k].start_vex;
// }
//
// printf("%c,%c", EdgeSet[k].start_vex, EdgeSet[k].end_vex);
// if (v1Root != v2Root) {
// //start-Vex和end_vex属于不同的根,合并
// parent[LRoot] += parent[SRoot];
// parent[SRoot] = LRoot;
// EdgeSet[k].single = 1;
// num++;
// }
// for (i = 0;i < vertex_num;i++)
// printf("%4d", parent[i]);
// printf("\n");
// k++;
// }
//}
//int main(void) {
// EdgeStruct EdgeSet[10] = {
// {'A','C',1,0},{'D','F',2,0},{'B','E',3,0},{'C','F',4,0},{'A','D',5,0},
// {'B','C',5,0},{'C','D',5,0},{'A','B',6,0},{'C','E',6,0},{'E','F',6,0}
// };
// Kruskal(EdgeSet, 10, 6);
// printf("\nKruskal算法得到的最小生成树序列\n");
// for (int i = 0;i < 10;i++) {
// if (EdgeSet[i].single == 1) {
// printf("(%c,%c) %d==>", EdgeSet[i].start_vex, EdgeSet[i].end_vex, EdgeSet[i].weight);
// }
// }
// getchar();
// return 0;
//}
GraphArray
//临接矩阵存储法
#include <stdio.h>
#include <stdlib.h>
#define VERTEX_NUM 64
typedef struct {
char VertexArray[VERTEX_NUM];//顶点数组
int AdjMatrix[VERTEX_NUM][VERTEX_NUM];//邻接矩阵
int VertexNum, EdgeNum;
}AM_GRAPH;
//邻接表结构
typedef struct AdjNode {
int adjvex;//邻接点
struct AdjNode* next;
}AL_AdjNode;
//邻接表顶点结构
typedef struct {
int vertex;
AdjNode* link;
}AL_VexNode;
//总的邻接表结构
typedef struct {
AL_VexNode VexList[VERTEX_NUM];
int VexNumber;
int ArcNumer;//边的数量
}AL_Graph_LKTable;
int main(void) {
int Num = 5;
int EdgeNum = 6;
AM_GRAPH myGraph;
char chVertext[] = { 'a','b','c','d','e' };
for(int i=0;i<5;i++){
myGraph.VertexArray[i] = chVertext[i];
}
//首先初始化一下邻接矩阵
for (int i = 0;i < 5;i++) {
for (int j = 0;j < 5;j++) {
myGraph.AdjMatrix[i][j] = 0;
}
}
int tempIn, tempOut;
//获得边,从而完善邻接矩阵
//有6条边,所以我们循环6次就可以了
for (int k = 0;k < 6;k++) {
printf("请输入以下邻接节点的角标,每一行是一个节点\n");
scanf("%d", &tempIn);
scanf("%d", &tempOut);
myGraph.AdjMatrix[tempIn][tempOut] = 1;
myGraph.AdjMatrix[tempOut][tempIn] = 1;
}
for (int i = 0;i < 5;i++) {
for (int j = 0;j < 5;j++) {
printf("%d ",myGraph.AdjMatrix[i][j]);
}
printf("\n");
}
AL_VexNode VexList[5] = { 0,NULL };
int j;
AL_AdjNode *Ptr, *nextPtr;
//i是逐行扫描邻接矩阵,然后根据矩阵中的i,j为1确定有边的关系
//将j作为角标放入邻接表
//二维数组的遍历
for (int i = 0;i < 5;i++) {
VexList[i].vertex = i;
VexList[i].link = NULL;
j = 0;
while (j < 5) {
if (myGraph.AdjMatrix[i][j] != 0) {
Ptr = (AL_AdjNode*)malloc(sizeof(AL_AdjNode));
Ptr->adjvex = j;
Ptr->next = NULL;
if (VexList[i].link == NULL) {
VexList[i].link = Ptr;
nextPtr = Ptr;
}
else {
nextPtr->next = Ptr;
nextPtr = Ptr;
}
}
j++;
}
}
//打印一下邻接矩阵
/*for (int i = 0;i < 5;i++) {
for (int j = 0;j < 5;j++) {
printf("请输入以下邻接节点的角标,每一行是一个节点\n");
scanf("%d", &tempIn);
scanf("%d", &tempOut);
myGraph.AdjMatrix[i][j] = 1;
myGraph.AdjMatrix[j][i] = 1;
}
}*/
getchar();
getchar();
return 0;
}
GrapTravel
//BFSDFSLK
#include <stdio.h>
#include <stdlib.h>
#define VertexNum 8
struct Node
{
int Vertex;//邻接顶点的数据
struct Node* pNext;
};
typedef struct Node* Graph;
struct Node Head[VertexNum];//顶点数组
int Visited[VertexNum] = { 0 };//查找记录
void DFS(int Vertex)
{
Graph Pointer;//节点声明
Visited[Vertex] = 1;
printf("%d==>", Vertex+1);
Pointer = Head[Vertex].pNext;
while (Pointer != NULL) {
if (Visited[Pointer->Vertex] == 0)
DFS(Pointer->Vertex);
Pointer = Pointer->pNext;
}
}
////////////////////////////////Begin BFS
#define QueueMax 10
int Queue[QueueMax] = { 0 };
int Front = -1;
int Rear = -1;
//入队
int Enqueue(int Vertex) {
if (Rear >= QueueMax)
return -1;
else {
Rear++;//队尾指针后移
Queue[Rear] = Vertex;//存入节点值
return 1;
}
}
//出队
int Dequeue() {
if(Front == Rear){
return -1;//队列空
}
else {
Front++;
return Queue[Front];
}
}
void BFS(int Vertex) {
Graph Pointer;
Enqueue(Vertex);
Visited[Vertex] = 1;
printf("%d==>", Vertex + 1);
while (Front != Rear) {
Vertex = Dequeue();
Pointer = Head[Vertex].pNext;
while (Pointer != NULL)
{
if (Visited[Pointer->Vertex] == 0) {
Enqueue(Pointer->Vertex);
Visited[Pointer->Vertex] = 1;
printf("%d==>", Pointer->Vertex + 1);
}
Pointer = Pointer->pNext;
}
}
}
////////////////////////////////End BFS
//建立邻接表
void Create_LK_Graph(int Vertex1, int Vertex2) {
Graph Pointer;//节点指针
Graph NewPointer;//新节点指针
NewPointer = (Graph)malloc(sizeof(struct Node));
if (NewPointer != NULL) {
NewPointer->Vertex = Vertex2;
NewPointer->pNext = NULL;
Pointer = &(Head[Vertex1]);//pointer指针设为节点数组的首节点
while (Pointer->pNext != NULL) {
Pointer = Pointer->pNext;
}
Pointer->pNext = NewPointer;
}
}
int main(void) {
int Node[20][2] = {
{1,2},{2,1},{1,3},{3,1},{2,4},
{4,2},{2,5},{5,2},{3,6},{6,3},
{3,7},{7,3},{4,8},{8,4},{5,8},
{8,5},{6,8},{8,6},{7,8},{8,7}
};
for (int i = 0;i < VertexNum;i++) {
Head[i].Vertex = i;
Head[i].pNext = NULL;
}
for (int i = 0;i < 20;i++) {
Create_LK_Graph(Node[i][0]-1, Node[i][1]-1);
}
//DFS(0);
BFS(0);
getchar();
return 0;
}
//BFSDFSMatrix
//#include <stdio.h>
///*
//根据走迷宫的引论,我们发现,我们可以从一个顶点开始,辐射状的
//优先遍历其周围较广的区域。
//这个就好比树的层次遍历,辅助数据结构是一个队列。
//所谓广度的思想提炼:
//以图的一个顶点V开始,由近至远,依次访问和V有关的(路径相同的)顶点。
//为了“先被访问的顶点的邻接点”先于“后被访问的顶点的邻接点”被访问
//需要设置队列进行存储.
//Step1:顶点V入队
//Step2: 当队列不为空的时候,我们不断寻找需要遍历的节点《----
// 出队头顶点v,访问头顶点并标记头顶点v已被访问 |
// 查找头顶点v的第一个邻接点w
// 如果v的w没有被访问,那么w入队 |
// 继续查找 ---
//*/
//
//#define VertexNum 8
//int AdjMatrix[VertexNum][VertexNum] = { 0 };
//void Create_AdjMatrix() {
// char *pStr[] = {
// "1,2","1,3","2,4","2,5","3,6",
// "3,7","4,8","5,8","6,8","7,8"
// };
//
// for (int k = 0;k < 10;k++) {
// int i = *(pStr[k]) - '1';
// int j = *(pStr[k] + 2) - '1';
// AdjMatrix[i][j] = 1;
// AdjMatrix[j][i] = 1;
// }
//}
//
///////BFS
//int color[VertexNum];//访问标识数组,防止回环(重复访问)
//struct Queue
//{
// int queue[VertexNum];
// int start;
// int end;
//}MyQueue;
//
//void BFS(int Graph[][VertexNum], int n) {
// int j;
// MyQueue.queue[MyQueue.end++] = 0;//节点0入队
// color[0] = 1;//访问第一个节点,标识已经访问了
//
// while (MyQueue.end != MyQueue.start) {
// for (j = 0;j < n;j++) {
// if (Graph[MyQueue.start][j] && !color[j]) {
// //j与队列中的节点start相通,且没有被访问
// color[j] = 1;
// MyQueue.queue[MyQueue.end++] = j;
// }
// }
// //利用队列先进先出的特点,在while中,逐个逐层输出节点
// printf("%d ", MyQueue.queue[MyQueue.start++] + 1);
// }
//}
///*
//访问顶点V,并将其表示为已经访问过的
//从v的未被访问的邻接点中选取一个w,从w再开始深度优先
//重复上述步骤,直至所有的路径都被访问过。
//由于没有规定访问邻接点的顺序,深度优先序列不唯一
//*/
//int Visited[VertexNum] = { 0 };
//void DFS(int i) {
// int j;
// printf("%d ", i + 1);
// Visited[i] = 1;
// for (j = 0;j < VertexNum;j++) {
// if ((AdjMatrix[i][j]) && (!Visited[j]))
// DFS(j);
// }
//}
//int main(void) {
// Create_AdjMatrix();
// BFS(AdjMatrix, 8);
// printf("\n");
// DFS(0);
// getchar();
// return 0;
//}
PathOpt
////Dijkstra算法
//#include <stdio.h>
//#define VERTEX_NUM 20
//#define MAX 32767
//
//typedef struct {
// int AdjMatrix[VERTEX_NUM][VERTEX_NUM];
// int VexNum, ArcNum;
//}AM_GRAPH;
//
//void Dijkstra(AM_GRAPH g, int v0);
//void PPath(int path[], int i, int v0);
//void DisplayPath(int dist[], int path[], int s[], int n, int v0);
//
//void PPath(int path[], int i, int v0) {
// int k = path[i];
// if (k == v0)
// return;
// else
// PPath(path, k, v0);
// printf("%d---", k);
//}
//
//
////dist:权重数组,path:路径数组,s:点的集合,n,顶点数目,v0:初始源点
//
//void DisplayPath(int dist[], int path[], int s[], int n, int v0) {
// int i;
// for (i = 0;i < n;i++) {
// if (s[i] == 1 && i != v0) {
// printf("从%d到%d路径的长度是%d", v0, i, dist[i]);
// printf("\t 路径是:%d---", v0);
// PPath(path, i, v0);
// printf("%d\n",i);
// }
// else {
// printf("从%d到%d不存在路径\n", v0, i);
// }
// }
//}
//
//void Dijkstra(AM_GRAPH g, int v0) {
// int i, j;
// int Dist[VERTEX_NUM];
// int Path[VERTEX_NUM];
// int S[VERTEX_NUM];
// int MinDis;// 距离V0最小的距离值
// int u;//距离当前v0最小的节点
//
// //通过循环,先把当前v0的可达点都记录在了s和path中
// for (i = 0;i < g.VexNum;i++) {
// Dist[i] = g.AdjMatrix[v0][i];
// if (g.AdjMatrix[v0][i] < MAX) {
// Path[i] = v0;
// }
// else {
// Path[i] = -1;
// }
// S[i] = 0;
// }
//
// S[v0] = 1;
//
// for (i = 0;i < g.VexNum;i++) {
// MinDis = MAX;//假定v0的最小距离是MAX
// u = -1;//表示没有对应的节点
//
// //扫描dist,找到对应节点,将可能最小权值节点,
// //通过遍历j推进到了u这个位置
// for (j = 0;j < g.VexNum;j++) {
// if (S[j] == 0 && Dist[j] < MinDis) {
// MinDis = Dist[j];
// u = j;
// }
// }
//
// //如果是max,说明这个点所有的路上都是max,说明他是只有入的,没有出的
// if (MinDis != MAX)
// S[u] = 1;
// else
// break;
//
// //u也可能作为中间节点去看v0到其他点的距离
//
// for (j = 0;j < g.VexNum;j++) {
// //选取不在s中,且与u相连
// if (S[j] == 0 && g.AdjMatrix[u][j] < MAX) {
// if (Dist[j] > Dist[u] + g.AdjMatrix[u][j]) {
// //修改v0到j的距离
// Dist[j] = Dist[u] + g.AdjMatrix[u][j];
// Path[j] = u;//修改j的前继
// }
// }
// }
//
// }
// printf("\n");
// DisplayPath(Dist, Path, S, g.VexNum, v0);
//}
//
//int main(void) {
// int A[VERTEX_NUM][6] = {
// {MAX,MAX,10,MAX,30,100},
// {MAX,MAX,5,MAX,MAX,MAX},
// {MAX,MAX,MAX,50,MAX,MAX},
// {MAX,MAX,MAX,MAX,MAX,10},
// {MAX,MAX,MAX,20,MAX,60},
// {MAX,MAX,MAX,MAX,MAX,MAX}
// };
// AM_GRAPH g;
// g.VexNum = 6;
// g.ArcNum = 8;
// for (int i = 0;i < g.VexNum;i++) {
// for (int j = 0;j < g.VexNum;j++) {
// g.AdjMatrix[i][j] = A[i][j];
// }
// }
//
// int v0 = 1;
// Dijkstra(g, v0);
// getchar();
// return 0;
//}
//Flod
#include <stdio.h>
#define VERTEX_NUM 100
#define MAX 32767
typedef struct {
int AdjMatrix[VERTEX_NUM][VERTEX_NUM];
int VexNum, ArcNum;
}AM_GRAPH;
void PPath(int Path[][VERTEX_NUM], int i, int j) {
int k = Path[i][j];
if (k == -1) {
return;
}
PPath(Path, i, k);
printf("%d-", k);
PPath(Path, k, j);
}
void DisplayPath(int A[][VERTEX_NUM], int Path[][VERTEX_NUM], int n) {
int i, j;
for (i = 0;i < n;i++) {
for(j=0;j<n;j++){
if (A[i][j] == MAX) {
if (i != j) {
printf("%d到%d没有路径\n", i, j);
}
}
else {
printf("从%d到%d路径长度为%d", i, j, A[i][j]);
printf("\t路径是:%d-", i);
PPath(Path, i, j);
printf("%d\n", j);
}
}
}
}
void Flod(AM_GRAPH g) {
int i, j, k;
int Dist[VERTEX_NUM][VERTEX_NUM], Path[VERTEX_NUM][VERTEX_NUM];
//用双重循环首相将邻接矩阵的权值付给初始化的路径矩阵dist
//中间节点路径矩阵Path置为-1
//我们希望得到的是(i,j)节点对的最短路径,所以path应当i,j的二维数组
for (i = 0;i < g.VexNum;i++) {
for (j = 0;j < g.VexNum;j++) {
Dist[i][j] = g.AdjMatrix[i][j];
Path[i][j] = -1;
}
}
//分别以图中的各个节点作为中间节点k,来遍历DIst
for (k = 0;k < g.VexNum;k++) {
for (i = 0;i < g.VexNum;i++) {
for (j = 0;j < g.VexNum;j++) {
//如果经过k的节点是(i,j)节点对距离小,更新之
if (Dist[i][j] > (Dist[i][k] + Dist[k][j])) {
Dist[i][j] = Dist[i][k] + Dist[k][j];
Path[i][j] = k;
}
}
}
}
printf("\n");
DisplayPath(Dist, Path, g.VexNum);
}
int main(void) {
int A[VERTEX_NUM][4] = {
{0,1,MAX,4},
{MAX,0,9,2},
{3,5,0,8},
{MAX,MAX,6,0}
};
AM_GRAPH g;
g.VexNum = 4;
g.ArcNum = 8;
for (int i = 0;i < g.VexNum;i++) {
for (int j = 0;j < g.VexNum;j++) {
g.AdjMatrix[i][j] = A[i][j];
}
}
Flod(g);
getchar();
return 0;
}
TopLogyOrder
//AOV
//#include <stdio.h>
//#define VERTEX_NUM 6
//void Toplogy(int matrix[][VERTEX_NUM]);
////栈
//void initStack(int *stack, int* n) {
// for (int i = 0;i < *n + 1; i++) {
// stack[i] = -1;
// }
// *n = 0;
//}
//
//void push(int * stack, int* n, int elem) {
// stack[*n] = elem;
// (*n)++;
//}
//
//int pop(int* stack, int *n) {
// int temp;
// (*n)--;
// temp = stack[*n];
// stack[*n] = -1;
// return temp;
//}
//
//int isempety(int* stack, int *n) {
// if (*n)
// return 0;
// return 1;
//}
//int stack[VERTEX_NUM + 1];
//
////前驱入度为o的aov网拓扑排序算法
//void Toplogy(int matrix[][VERTEX_NUM]) {
// int indegree[VERTEX_NUM] = { 0 };//入度数组
// int sortorder[VERTEX_NUM] = { 0 };//这是用于存放最后拓扑排序的序列
// int sortordercourse = 0;
//
// int course = VERTEX_NUM + 1;
// initStack(stack, &course);
//
// int count = 0;//表示指示入度为0的顶点个数
// //入度为0的节点入栈
// for (int j = 0;j < VERTEX_NUM;j++) {
// for (int i = 0;i < VERTEX_NUM;i++) {
// indegree[j] += matrix[i][j];
// }
// if (!(indegree[j]))
// push(stack, &course, j);
// }
//
// while (!(isempety(stack, &course))) {
// int tp;
// tp = pop(stack, &course);
// sortorder[sortordercourse++] = tp;
// count++;
// for (int i = 0;i < VERTEX_NUM;i++) {
// //对出栈的顶点所指向的终点节点的入度-1,从而获得新可能的入度为0的节点
// if ((indegree[i] == 1) && (matrix[tp][i] == 1)) {
// push(stack, &course, i);
// }
// indegree[i] -= matrix[tp][i];
// }
// }
//
// if (count == VERTEX_NUM) {
// printf("\n");
// for (int i = 0;i < sortordercourse;i++) {
// printf(" c%d", sortorder[i] + 1);
// }
// }
// else {
// printf("没有获得可以排序的序列");
// }
//}
//int main(void) {
// int mat[VERTEX_NUM][VERTEX_NUM] = {
// {0,1,1,1,0,0},
// {0,0,0,0,0,0},
// {0,1,0,0,1,0},
// {0,0,0,0,1,0},
// {0,0,0,0,0,0},
// {0,0,0,1,1,0}
// };
// Toplogy(mat);
// getchar();
// return 0;
//}
//AOE
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int adjvex;
int w;
struct node * nextedge;
}edgenode;
//定义边集
typedef struct {
int data;//data实际上就是我们的a1,a2,a3,为了方便,我们用1,2,3.。表示
int id;//id是节点表示,方便我们调试用的
edgenode *firstedge;
}vexnode;
void CreateGraph(vexnode* Graph, int vexnumber, int arcnumber) {
int i = 0, j = 0, k = 0;
edgenode* p;
for (i = 0;i < vexnumber;i++) {
Graph[i].id = 0;
Graph[i].firstedge = NULL;
}
for (i = 0;i < vexnumber;i++) {
Graph[i].data = i + 1;
}
int startNode[] = {1,1,2,2,3,3,4,4,5,6};
int endNode[] = {2,3,4,5,4,6,5,6,7,7};
int Weight[] = {3,2,1,8,3,7,4,2,9,10};
for (k = 0;k < arcnumber;k++) {
p = (edgenode*)malloc(sizeof(edgenode));
p->adjvex = endNode[k] - 1;
p->w = Weight[k];
Graph[endNode[k] - 1].id++;
p->nextedge = Graph[startNode[k] - 1].firstedge;
Graph[startNode[k] - 1].firstedge = p;
}
}
/*
1:判断一下,这个图是不是有向无环图,
2:从前向后,算一下最早开始时间
3:从后向前,算一下最晚开始时间
*/
void SearchPath(vexnode* Graph, int vexnumber, int arcnumber) {
int totaltime = 0;
int m = 0;
int i, j, k, t;
int sv[100];//用来记录并存储节点,以便打印关键节点
int front, rear;
int *topology_queue, *vl, *ve, *el, *ee;//el最早开始时间,ee是最晚开始时间
front = rear = -1;
t = 0;
topology_queue = (int*)malloc(2*vexnumber * sizeof(int));
vl = (int*)malloc(2 * vexnumber * sizeof(int));
ve = (int*)malloc(2 * vexnumber * sizeof(int));
el = (int*)malloc(2 * vexnumber * sizeof(int));
ee= (int*)malloc(2 * vexnumber * sizeof(int));
edgenode* p;//p是用来推进邻接表的每一个可达边
for (i = 0;i < vexnumber;i++) {
ve[i] = 0;
}
for (i = 0;i < vexnumber;i++) {
if (Graph[i].id == 0)
topology_queue[++rear] = i;
m++;
}
while (front != rear) {
front++;
j = topology_queue[front];
m++;
p = Graph[j].firstedge;
while (p) {
k = p->adjvex;//k是j的可达边的节点在数组中的对应角标
Graph[k].id--;
if (ve[j] + p->w > ve[k]) {
ve[k] = ve[j] + p->w;
}
if (Graph[k].id == 0) {
topology_queue[++rear] = k;
}
p = p->nextedge;
}
}
if (m < vexnumber) {
printf("本图有回路");
return;
}
totaltime = ve[vexnumber - 1];
//倒退开始
for (i = 0;i < vexnumber;i++) {
vl[i] = totaltime;
}
for (i = vexnumber - 2;i >= 0;i--) {
j = topology_queue[i];
p = Graph[j].firstedge;
while (p) {
k = p->adjvex;
if ((vl[k] - p->w) < vl[j]) {
vl[j] = vl[k] - p->w;
}
p = p->nextedge;
}
}
//输出
printf("起点|终点|最早开始时间|最晚开始时间|差值|是否为关键路径\n");
i = 0;
for (j = 0;j < vexnumber;j++) {
p = Graph[j].firstedge;
while (p) {
k = p->adjvex;
ee[++i] = ve[j];
el[i] = vl[k] - p->w;
printf(" V%d v%d %12d %12d %4d", Graph[j].data, Graph[k].data, ee[i], el[i], el[i] - ee[i]);
if (el[i] == ee[i]) {
printf("\t此弧为关键路径\n");
sv[t] = Graph[j].data;
t++;
}
printf("\n");
p = p->nextedge;
}
}
printf("关键路径\n");
sv[t] = Graph[vexnumber - 1].data;
for (i = 0;i <= t;i++) {
printf("V%d", sv[i]);
if (sv[i] != Graph[vexnumber - 1].data)
printf("--->");
}
printf("总时长%d:", totaltime);
free(topology_queue);
free(el);
free(ee);
free(vl);
free(ve);
}
int main(void) {
int arcnum = 10;
int vexnum = 7;
vexnode* Graph = (vexnode*)malloc(vexnum*sizeof(vexnode));
CreateGraph(Graph, vexnum, arcnum);
SearchPath( Graph, vexnum, arcnum);
free(Graph);
getchar();
return 0;
}
二分查找
//#include <stdio.h>
////传入数组,传入需要查找目标值n,返回所在的角标
////r表示传入数组,n表示数组元素的个数,key表示比对目标
//int BiSearch(int r[], int n, int key) {
// int low = 0;
// int high = n - 1;
// int mid = 0;
// while (low <= high) {
// mid = (low + high + 1) / 2;
// if (r[mid] < key) {
// low = mid + 1;
// }
// else if (r[mid] > key) {
// high = mid - 1;
// }
// else
// return mid;
// }
// return -1;
//}
//int main(void) {
// int arr[] = { 5, 10, 19, 21, 31,
// 37, 42, 48, 50, 55 };
// int pos =BiSearch(arr, 10, 919);
// if (pos != -1) {
// printf("找到了,在%d的位置上", pos);
// }
// else {
// printf("您要查找的目标不在array中");
// }
// getchar();
// return 0;
//}
斐波那契查找
//#include <stdio.h>
//#define MAXSIZE 100
//
//void fib(int *f) {
// f[0] = 1;
// f[1] = 1;
// for(int i=2;i<MAXSIZE;i++){
// f[i] = f[i - 2] + f[i - 1];
// }
//}
//
////r是目标数组,n是数组元素个数,key对比目标
//int Fib_Search(int r[], int n, int key) {
// int i, k = 0;
// int low = 0, high = n - 1, mid = 0;
// int F[MAXSIZE];
//
// fib(F);//构建斐波那契数,一边推进
// while (n > F[k] - 1 && n > 1)
// ++k;
// //通过k的累加,得到了现在的斐波那契数的阶数
//
// //补全斐波那契树
// for (i = n;i < F[k] - 1;i++) {
// r[i] = r[high];
// }
//
// while (low <= high) {
// if (low == high) {
// if (r[low] == key)
// return low;
// else
// return -1;
// }
// mid = low + F[k - 1] - 1;
// if (r[mid] > key) {
// high = mid - 1;
// k = k - 1;
// }
// else {
// if (r[mid] < key) {
// low = mid + 1;
// k = k - 2;
// }
// else {
// if (mid <= high)
// return mid;
// else
// return -1;
// }
// }
// }
// return -1;
//}
//
//
//int main(void) {
// int arr[] = { 5, 10, 19, 21, 31,
// 37, 42, 48, 50, 55 };
// int pos = Fib_Search(arr, 10, 119);
// if (pos != -1)
// printf("您要找的数在%d位置", pos);
// else
// printf("您要找的数不存在");
// getchar();
// return 0;
//}
字典树
//#include <stdio.h>
//#include <stdlib.h>
//#include <string.h>
//#define MAX 26
//
//typedef struct Tree {
// int count;//用来标记该节点是否可以形成一个单词,如果count!=0,那么从根节点到这个节点就可以形成单词
// struct Tree *child[MAX];
//}Node,*Trie_node;
//
////创建Trie树
//Node* CreateTrie() {
// Node* node = (Node*)malloc(sizeof(Node));
// memset(node, 0, sizeof(Node));
// return node;
//}
//
//void inerst_node(Trie_node root, char *str) {
// if (root == NULL || *str == '\0')
// return;
// Node* t = root;
// char*p = str;
//
// while(*p!='\0'){
// if (t->child[*p - 'a'] == NULL) {
// Node* tmp = CreateTrie();
// t->child[*p - 'a'] = tmp;
// }
// t = t->child[*p - 'a'];
// p++;
// }
// t->count++;
//}
//
//void search_str(Trie_node root, char *str) {
// if (NULL == root || *str == '\0') {
// printf("空的你还找什么呢?");
// return;
// }
//
// char *p = str;
// Node*t = root;
//
// while (*p != '\0') {
// if (t->child[*p - 'a'] != NULL) {
// t = t->child[*p - 'a'];
// p++;
// }
// else
// break;
// }
//
// if (*p == '\0') {
// if (t->count == 0)
// printf("该串不在树中,但是该串应当是某个单词的前缀\n");
// else
// printf("该串存在树中\n");
// }
// else
// printf("该串不再树中\n");
//}
//
//int main(void) {
// int i, n;
// char *pStr[] = { "joe","john",
// "johnny",
// "jane",
// "jack",
// };
// Trie_node root = NULL;
// root = CreateTrie();
// for (i = 0;i < 5;i++)
// inerst_node(root, pStr[i]);
//
// search_str(root, "jo");
// search_str(root, "jane");
// search_str(root, "joo");
// getchar();
// return 0;
//}
字符串的BF算法
#include <string.h>
/*
BBC ABCDAB ABCDABCDABDE
搜索词"ABCDABD"
*/
//如果pattern存在org中,那么返回的是首次出现的org的角标
//否则返回的是-1
int index(char strOrg[], char strPattern[]) {
int i = 0, j = 0;//i是用来推进strOrg,j是用来推进strPattern的
int k = -1;//k是用来返回org中的角标的,默认的我们认为不存在
int orgLength = strlen(strOrg);
int patternLength = strlen(strPattern);
int count = 0;
while (i < orgLength && j < patternLength) {
if (strOrg[i] == strPattern[j]) {
//此时,原串不要向下移动,而是从当前位置开始,看是否有匹配的子串存在
i++;
j++;
}
else {
i = i - j + 1;
j = 0;
}
count++;
}
printf("本算法运行了%d次\n", count);
if (j >= patternLength) {
k = i - patternLength;
}
return k;
}
//****************************Beging KMP
#define MAXLENGTH 1024
//部分匹配值的计算
void GetNext(char str[], int next[]) {
int j = 0;
int k = -1;
next[0] = -1;
while (j < strlen(str)) {
if (k == -1 || str[j] == str[k]) {
j++;
k++;
next[j] = k;
}
else
k = next[k];
}
}
int KMPIndex(char strOrg[], char strPattern[]) {
int next[MAXLENGTH], i = 0, j = 0, pos = -1;
GetNext(strPattern, next);//获得patter串中的每一个字符的部分匹配值
int orgLength = strlen(strOrg);
int patternLength = strlen(strPattern);
int count = 0;
while (i < orgLength && j < patternLength) {
if (j == -1 || strOrg[i] == strPattern[j]) {
i++;
j++;
}
else {
j = next[j];
}
count++;
}
printf("本次检索我们一共运行了%d次", count);
if (j >= patternLength) {
pos = i - patternLength;
}
return pos;
}
//****************************END KMP
int main(void) {
//printf("%d ", index("BBC ABCDAB ABCDABCDABDE", "ABCDABD"));
printf("%d ", KMPIndex("BBC ABCDAB ABCDABCDABDE", "ABCDABD"));
getchar();
return 0;
}
堆排序
//#include <stdio.h>
//int ArrarOrg[] = { 49,38,65,97,76,
//13,27,49,55,4 };
//
////建立最大堆
////n表示数组的元素位置,length表示数组长度
//void MaxHeap(int H[], int n, int Length) {
// int l = 2 * n + 1;
// //从数组0开始,和从1开始的左右孩子标志
// int r = 2 * n + 2;
// int max;//l,r,max都是数组角标
//
// int temp;
// if (l<Length && H[l]>H[n])
// max = l;//表示左节点大
// else
// max = n;//根大
//
// if (r<Length && H[r]>H[max])
// max = r;
//
// if (max != n) {
// temp = H[n];
// H[n] = H[max];
// H[max] = temp;
// MaxHeap(H, max, Length);
// }
//
//}
//
//
//void HeapSort(int H[], int length) {
// int i, temp;
// for (i = length / 2;i >= 0;i--) {
// MaxHeap(H, i, length);
// }
// for (i = length - 1;i >= 0;i--) {
// temp = H[0];
// H[0] = H[i];
// H[i] = temp;
// MaxHeap(H, 0, i - 1);
// }
//}
//
//
//int main(void) {
//
// HeapSort(ArrarOrg, 10);
// for (int i = 0;i < 10;i++) {
// printf("%d ", ArrarOrg[i]);
// }
// getchar();
// return 0;
//}
归并排序
//#include <stdio.h>
//#include <stdlib.h>
//int ArrarOrg[] = { 49,38,65,97,76,
//13,27,49,55,4 };
//
//
///*
//代排序的数组SR,存放排序的数组是TR
//m:SR的长度,n是TR的长度
//目标:将SR[i....m]和SR[m+1,...n]归并为有序
//TR[i....n]
//*/
//void Merge(int SR[], int TR[],int i, int m, int n) {
// int j, k;
// for (j = m + 1, k = i;i <= m&& j <= n;k++) {
// if (SR[i] < SR[j])//选择较小的赋值
// TR[k] = SR[i++];
// else
// TR[k] = SR[j++];
// }
// while (i <= m)
// TR[k++] = SR[i++];
// while (j <= n)
// TR[k++] = SR[j++];
//
//}
//
////一趟归并
////SR:待排序数组,TR:暂存空间,n表示原数组个数,t表示子序列长度
//void MSort(int SR[], int TR[], int n, int t) {
// int i = 0, j;
// while (n - i >= 2 * t) {
// //将相邻的两个长度为t的各自有序序列并成一个长度为2t的序列
// Merge(SR, TR, i, i + t - 1, i + 2 * t - 1);
// i = i + 2 * t;
// }
//
// if (n - i > t) {
// Merge(SR, TR, i, i + t - 1, n - 1);
// }
// else {
// //将原先的[i..n-1]拷给新空间[i..n-1]
// for (j = i;j < n;j++) {
// TR[j] = SR[j];
// }
// }
//}
//
////N表示原数组的长度
//void TMSort(int arr[], int N) {
// int t = 1;
// int *pArr = (int*)malloc(N * sizeof(int));
// while (t < N) {
// MSort(arr, pArr, N, t);
// t = t * 2;
// MSort(pArr, arr, N, t);
// t = t * 2;
// }
// free(pArr);
//}
//
//int main(void) {
// TMSort(ArrarOrg, 10);
// for (int i = 0;i < 10;i++) {
// printf("%d ", ArrarOrg[i]);
// }
// getchar();
// return 0;
//}
基数排序
#include <stdio.h>
#include <stdlib.h>
int ArrarOrg[] = { 49,38,65,97,76,
13,27,49,55,4 };
//X:数值,bit是X的第bit位
//第bit位的值
int X_Bit_Number(int X, int bit) {
int temp = 1;
for (int i = 0;i < bit - 1;i++)
temp *= 10;
return (X / temp) % 10;
}
//求得是待排序数组a中元素最大的位数
int A_MaxBit(int a[], int N) {
int largest = a[0], digits = 0;
for (int i = 1;i < N;i++) {
if (a[i] > largest) {
largest = a[i];
}
}
while (largest != 0) {
++digits;
largest /= 10;
}
return digits;
}
void RadixSort(int DataArray[], int N) {
int *radixArrays[10];//0-9序列准备好
for (int i = 0;i < 10;i++) {
radixArrays[i] = (int*)malloc(sizeof(int)*(N + 1));
radixArrays[i][0] = 0;
}
int MaxBit = A_MaxBit(DataArray, N);
for (int pos = 1;pos <= MaxBit;pos++) {
for (int i = 0;i < N;i++) {
int num = X_Bit_Number(DataArray[i], pos);
int index = ++radixArrays[num][0];
radixArrays[num][index] = DataArray[i];
}
for (int i = 0, j = 0;i < 10;i++) {
for (int k = 1;k <= radixArrays[i][0];k++) {
DataArray[j++] = radixArrays[i][k];
}
radixArrays[i][0] = 0;
}
}
}
int main(void)
{
RadixSort(ArrarOrg, 10);
for (int i = 0;i < 10;i++) {
printf("%d ", ArrarOrg[i]);
}
getchar();
return 0;
}
快速排序
//#include <stdio.h>
//int ArrarOrg[] = { 49,38,65,97,76,
//13,27,49,55,4 };
//
//
//int Paritition(int arr[],int low,int high){
// int pivotLoc = arr[low];
// int temp;
//
// while (low < high) {
// while (low < high && arr[high] >= pivotLoc)
// --high;//首先找到比第一个小的数值
//
// temp = arr[low];
// arr[low] = arr[high];
// arr[high] = temp;
//
// while (low < high && arr[low] <= pivotLoc)
// ++low;
// temp = arr[low];
// arr[low] = arr[high];
// arr[high] = temp;
//
// }
// return low;
//}
//
//void QSort(int arr[], int n, int low, int hight) {
// int pivotloc;
// if (low < hight) {
// pivotloc = Paritition(arr, low, hight);
// QSort(arr, n, low, pivotloc - 1);
// QSort(arr, n, pivotloc + 1, hight);
// }
//}
//
//int main(void) {
// QSort(ArrarOrg, 10, 0, 9);
// for (int i = 0;i < 10;i++) {
// printf("%d ", ArrarOrg[i]);
// }
// getchar();
// return 0;
//}
冒泡
//#include <stdio.h>
//int ArrarOrg[] = { 49,38,65,97,76,
//13,27,49,55,4 };
//
//void BubbleSort(int a[], int length) {
// int i, j, temp;
// int change = 0;//检测一次排序中是否有交换,没有交换说明已经有序
//
// for (i = length- 1;i >= 0 && change == 0;i--) {
// change = 1;//位置不能变
// for (j = 0;j < i;j++) {
// if (a[j] > a[j + 1]) {
// //角标较小的数比角标较大的数大,交换之
// change = 0;
// temp = a[j];
// a[j] = a[j + 1];
// a[j + 1] = temp;
// }
// }
// }
//}
//
//int main(void) {
//
// BubbleSort(ArrarOrg, 10);
// for (int i = 0;i < 10;i++) {
// printf("%d ", ArrarOrg[i]);
// }
// getchar();
// return 0;
//}
希尔排序
//#include <stdio.h>
//int ArrarOrg[] = { 49,38,65,97,76,
//13,27,49,55,4 };
//
//
//void ShellInert(int arr[],int length,int dk){
// int i, j, k, temp;
// for (k = 0;k < dk;k++) {
// for (i = k + dk;i < length;i = i + dk) {
// if (arr[i] < arr[i - dk]) {
// temp = arr[i];
// for (j = i - dk;j >= 0 && temp < arr[j];j = j - dk) {
// arr[j + dk] = arr[j];
// }
// arr[j + dk] = temp;
// }
// }
// }
//}
//
//void ShellSort(int arr[], int length) {
// int delta[] = { 5,3,1 };
// for (int k = 0;k < 3;++k) {
// ShellInert(arr, length, delta[k]);
// }
//}
//
//int main(void) {
// ShellSort(ArrarOrg, 10);
// for (int i = 0;i < 10;i++) {
// printf("%d ", ArrarOrg[i]);
// }
// getchar();
// return 0;
//
//}
直接插入排序
//#include <stdio.h>
//int ArrarOrg[] = { 49,38,65,97,76,
// 13,27,49,55,4 };
//
////升序
//void InsertSort(int a[], int length) {
// int i, j;
// int temp;//存储a数组中对应的角标所存储的数值
//
// //外循环扫描所有的待排序元素
// for (i = 1;i < length;i++) {
// if (a[i] < a[i - 1]) {
// temp = a[i];
// for (j = i - 1;temp < a[j] && j >= 0;j--) {
// a[j + 1] = a[j];
// }
// a[j + 1] = temp;
// }
// }
//}
//
//int main(void) {
// InsertSort(ArrarOrg, 10);
// for (int i = 0;i < 10;i++) {
// printf("%d ", ArrarOrg[i]);
// }
// getchar();
// return 0;
//
//}
直接选择
//#include <stdio.h>
//int ArrarOrg[] = { 49,38,65,97,76,
//13,27,49,55,4 };
//
//void SelectSort(int a[], int n) {
// int i, j, temp;
// for (i = 0;i < n - 1;i++) {
// for (j = i;j < n;j++) {
// if (a[j] < a[i]) {
// temp = a[i];
// a[i] = a[j];
// a[j] = temp;
// }
// }
// }
//}
//
//
//int main() {
// SelectSort(ArrarOrg, 10);
// for (int i = 0;i < 10;i++) {
// printf("%d ", ArrarOrg[i]);
// }
// getchar();
// return 0;
//}