当前位置:文档之家› 各种排序算法C语言实现

各种排序算法C语言实现

#include <stdio.h>#include <stdlib.h>#define Max 20 //最大顶点数//顺序存储方式使用的结构体定义typedef struct vexType{char data;int indegree;}Vex;typedef struct Graph{int vexnum; //顶点数量int arcnum; //边数Vex vex_array[Max]; //存放顶点的数组int arc_array[Max][Max]; //存放邻接矩阵的二维数组}Graph; //图的定义//链式存储使用的结构体定义typedef struct arcType{char vex1,vex2; //边所依附的两点int arcVal; //边的权值}Arc; //边的定义typedef struct LinkType{int index; //在顶点表的下标struct LinkType *nextarc; //指向下一个顶点结点}LinkNode; //边表定义typedef struct vexNode{char data;int add; //在顶点数组的下表位置LinkNode *firstarc; //指向边表的第一个结点int indegree; //入度}VexNode; //顶点边定义typedef struct LGraph{VexNode vex_array[Max]; //顶点数组int vexnum; //图中顶点数}LGraph;/*函数功能:图的创建入口参数:图G返回值:无*/void Creat_G(Graph *G){char v;int i=0;int j=0;G->vexnum=0;printf("输入说明。

有权值请输入权值,无权值请输入1,无边请输入0\n");printf("\n请输入所有顶点(不超过20个,按‘#’结束输入):\n");do{printf("输入第%d 个顶点:",G->vexnum+1);scanf(" %c",&v);G->vex_array[G->vexnum].data = v;G->vexnum++;}while(v!='#');G->vexnum--;printf("输入邻接矩阵(%d * %d):",G->vexnum,G->vexnum);for(i=0; i<G->vexnum; i++){printf("输入%c 到以下各点的权值:\n",G->vex_array[i].data);for(j=0; j<G->vexnum; j++){printf("<%c, %c>: ",G->vex_array[i].data,G->vex_array[j].data);scanf("%d",&G->arc_array[i][j]);}}printf("\n构建图的顶点为:\n");for(i=0; i<G->vexnum; i++){printf("%c ",G->vex_array[i].data);}printf("\n构建图的邻接矩阵为:\n");for(i=0; i<G->vexnum; i++){for(j=0; j<G->vexnum; j++){printf("%d ",G->arc_array[i][j]);}printf("\n");}}/*函数功能:统计各点的入度入口参数:指向图的指针*G返回值:无*/void Count_indegree(Graph *G){int i;int j;for(j=0; j<G->vexnum; j++){G->vex_array[j].indegree =0;for(i=0; i<G->vexnum; i++){if(G->arc_array[i][j]!=0)G->vex_array[j].indegree++;}}}/*函数功能:对邻接矩阵进行拓扑排序入口参数:指向图的指针*G返回值:无*/void Topol_sort(Graph *G){int i,j;char topo[Max]; //存放拓扑排序的结果int count=0; //记录topo[]中的元素个数,便于与vexnum比较,判断是有环图还是无环图char stack[Max]; //存放indegree=0的顶点所在vex_array[]中的下标int top=0; //栈的指针int bool=1; //弹栈的标准int no; //接收stack[]栈中弹出的顶点下标for(i=0; i<G->vexnum; i++){if(G->vex_array[i].indegree==0){stack[top] = i;top++;}}do{if(top==-1)bool=0;else{top--;no = stack[top];topo[count] = G->vex_array[no].data;count++;for(j=0; j<G->vexnum; j++){if(G->arc_array[i][j]!=0){G->vex_array[j].indegree--;if(G->vex_array[j].indegree==0){stack[top] = j;top++;}}}}}while(bool==1);count--;if(count < G->vexnum){printf("\n结果:原图中有环,无法形成拓扑序列!\n");}else{printf("\n结果:原图的拓扑序列为:\n");for(i=0; i<count; i++){printf("%c ",topo[i]);}printf("\n");}}/*函数功能:邻接矩阵及相关操作入口参数:指向图的指针*G返回值:无*/void LinJieJuZhen(Graph *G){int choice;printf("\n1 图的创建(针对有向图)\n2 拓扑排序\n0 退出\n请选择:");scanf("%d",&choice);do{switch(choice){case 1:Creat_G(G);break;case 2:Count_indegree(G);Topol_sort(G);break;case 0:break;}printf("请选择:");scanf("%d",&choice);if(choice==0)break;}while(choice!=0);}/*函数功能:创建邻接链表T入口参数:指向连接链表的指针*T返回值:无*/void Creat_LinkT(LGraph *T){char v;int i,j,k;char answer;int count;int f=1; //标志边表的第一个结点LinkNode *p=NULL;LinkNode *q=NULL;T->vexnum = 0;printf("\n输入说明。

有权值请输入权值,无权值请输入1,无边请输入0\n");printf("\n请输入所有顶点(不超过20个,按‘#’结束输入)\n");do{printf("输入第%d 个顶点:",T->vexnum+1);scanf(" %c",&v);T->vex_array[T->vexnum].data = v;T->vex_array[T->vexnum].firstarc = NULL;T->vexnum++;}while(v!='#');T->vexnum--;for(i=0; i<T->vexnum; i++){f=1;printf("\n以顶点%c 为始点是否有边(Y / N): ",T->vex_array[i]);scanf(" %c",&answer);if(answer=='Y'){printf("输入以%c 为始点的所有终点个数:",T->vex_array[i]);scanf("%d",&count);for(j=0; j<count; j++){p = (LinkNode *)malloc(sizeof(LinkNode));p->nextarc=NULL;printf("输入第%d 个顶点:",j+1);scanf(" %c",&v);for(k=0; k<T->vexnum; k++){if(v==T->vex_array[k].data){p->index = k; //找到该元素,并记录下标if(f==1) //是第一个结点,放在T->vex_array[i].firstarc上{T->vex_array[i].firstarc = p;q = p;f = 0;}else{q->nextarc = p;q = p;}}}}}}printf("创建链表为:\n");for(i=0; i<T->vexnum; i++){printf("%c ---->",T->vex_array[i].data);p = T->vex_array[i].firstarc;while(p!=NULL){printf("%c ---->",T->vex_array[p->index].data);p=p->nextarc;}printf("NULL\n");}}/*函数功能:统计各个点的入度入口参数:指向图的指针*T返回值:无*/void Count_T_indegree(LGraph *T){int i;LinkNode *p=NULL;for(i=0; i<T->vexnum; i++){T->vex_array[i].indegree = 0;}for(i=0; i<T->vexnum; i++){p = T->vex_array[i].firstarc;while(p!=NULL){T->vex_array[p->index].indegree++;p=p->nextarc;}}}/*函数功能:拓扑排序入口参数:指向图的指针*T返回值:无*/void L_Topol_sort(LGraph *T){int i,j;int no;int stack[Max];int top=0;int topo[Max];int count=0;int bool=1;LinkNode *p=NULL;for(i=0; i<T->vexnum; i++){if(T->vex_array[i].indegree==0){stack[top] = i;top++;}}do{if(top==0)bool=0;else{top--;no = stack[top];topo[count] = T->vex_array[no].data;count++;p = T->vex_array[no].firstarc;while(p!=NULL){T->vex_array[p->index].indegree--;if(T->vex_array[p->index].indegree==0){stack[top] = p->index;top++;}p = p->nextarc;}}}while(bool==1);//printf("检测\n");if(count < T->vexnum)printf("原图有环,无法形成拓扑排序!\n");else{printf("原图的拓扑排序为:\n");for(i=0; i<count; i++){printf("%c ",topo[i]);}}}/*函数功能:邻接链表及拓扑排序入口参数:指向图的指针*T返回值:无*/void LinJieLianBiao(LGraph *T){int choice;printf("\n1 图的创建(针对有向图)\n2 拓扑排序\n0 退出\n");do{printf("\n请选择:");scanf("%d",&choice);switch(choice){case 1:Creat_LinkT(T);printf("图已创建完成!\n");break;case 2:Count_T_indegree(T);L_Topol_sort(T);break;case 0:break;}if(choice==0)break;}while(choice!=0);}void main(){int choice;//邻接矩阵中的变量Graph G;LGraph T;printf("---------------------------\n\n");printf("1、图的顺序存储--邻接矩阵并进行拓扑排序\n2、图的连式存储--邻接链表并进行拓扑排序\n0、退出\n");do{printf("请选择主菜单操作:");scanf("%d",&choice);switch(choice){case 1:printf("\n****图的顺序存储--邻接矩阵****\n");LinJieJuZhen(&G);break;case 2:printf("\n****图的链式存储--邻接链表****\n");LinJieLianBiao(&T);break;case 0:exit(0);default:printf("输入错误!\n");break;}}while(choice!=0);}#include <stdio.h>#include <stdlib.h>#define Max 20typedef struct list{int array[Max];int length;}List;/*数组复制*/void Copy(List *L,List *Lx){int i;Lx->length = L->length;for(i=1; i<=L->length; i++){Lx->array[i] = L->array[i];}/*创建顺序表*/void Creat(List *L){int data=0;int i;L->length=1;printf("输入数据,以-100为结束输入标志\n");while(data!=-100){printf("输入第%d 个元素值:",L->length);scanf("%d",&data);L->array[L->length] = data;L->length++;}L->length = L->length-2;printf("输入的元素值为:");for(i=1; i<=L->length; i++){printf("%d ",L->array[i]);}printf("\n");}/*直接插入排序*/void ZhiJieChaRu_sort(List *L){int i;int j;for(i=2; i<=L->length; i++){if(L->array[i] < L->array[i-1]){L->array[0] = L->array[i];L->array[i] = L->array[i-1];for(j=i-2; L->array[0] < L->array[j]; j--){L->array[j+1] = L->array[j];}L->array[j+1] = L->array[0];}}printf("\n----------------直接插入法排序结果为-------------\n");for(i=1; i<=L->length; i++)printf("%d ",L->array[i]);printf("\n");}/*二分法排序*/void ErFenFa_sort(List *L){int i;int j;int low;int high;int mid;for(i=2; i<=L->length; i++){low = 1;high = i-1;L->array[0] = L->array[i];while(low <= high){mid = (low+high)/2;if(L->array[0] < L->array[mid])high = mid - 1;elselow = mid + 1;}for(j=i-1; j>=high+1; j--){L->array[j+1] = L->array[j];}L->array[high+1] = L->array[0];}printf("\n-------------------二分法排序结果为-----------------\n");for(i=1; i<=L->length; i++)printf("%d ",L->array[i]);printf("\n");}//一次增量下的希尔排序void Shell_pass(List *L,int d){int i;int j;for(i=d+1; i<=L->length; i++){if(L->array[i] < L->array[i-d]){L->array[0] = L->array[i];L->array[i] = L->array[i-d];for(j=i-2*d; j>0 && L->array[0]<L->array[j]; j--)L->array[j] = L->array[j-d];L->array[j+d] = L->array[0];}}}//希尔排序void Shell_sort(List *L,int d[]){int i;for(i=0; i<4; i++) //一次取出d中的增量值Shell_pass(L,d[i]);printf("\n-----------------希尔排序结果为-----------------\n");for(i=1; i<=L->length; i++)printf("%d ",L->array[i]);printf("\n");}//冒泡排序void MaoPao_sort(List *L){int i;int j;int flag=1; //问题:课件上显示为已注销的部分,但是无法排序(没有交换=?=已经排好了)for(i=1; i<=L->length; i++) //控制趟数{// flag=1;for(j=1; j<=L->length-i; j++) //一趟的循环,第i趟结束后就筛选出第i个最小值,所以只需从前length-i个中冒出最小值{if(L->array[j+1] < L->array[j]){flag=0;L->array[0] = L->array[j+1];L->array[j+1] = L->array[j];L->array[j] = L->array[0];}// if(flag==1)// break;}}printf("\n-----------------冒泡排序结果为-----------------\n");for(i=1; i<=L->length; i++)printf("%d ",L->array[i]);printf("\n");}//快速排序的一次枢轴定位int KuaiSu_sort(List *L, int low, int high){int pivotkey; //枢轴L->array[0] = L->array[low]; //每次排序序列的第一个值作为枢轴,即low作为枢轴pivotkey = L->array[low];while(low < high){while(low<high && pivotkey<=L->array[high]) //无论是哪种退出循环方式,都恰好是high的位置就是枢轴位置high--;if(low<high){L->array[low] = L->array[high];low++;}while(low<high && pivotkey>=L->array[low])low++;if(low<high){L->array[high] = L->array[low];high--;}}//整个循环退出就得到枢轴在真正序列中的位置为low(也是high)L->array[low] = L->array[0];/* printf("\n-----------------分步排序结果为-----------------\n");for(i=1; i<=L->length; i++)printf("%d ",L->array[i]);printf("\n");*/return low;}//完整快速排序void KuaiSuPaiXu_sort(List *L,int low,int high){int pivotloc; //接收一次枢轴定位的位置if(low < high){pivotloc = KuaiSu_sort(L,low,high); //也可写为(L,low,pivotkey-1)KuaiSuPaiXu_sort(L,low,pivotloc-1);KuaiSuPaiXu_sort(L,pivotloc+1,high); //也可写为(L,high,pivotkey-1) }}//简单选择排序void JianDanXuanZe_sort(List *L){int i;int j;int min;for(i=1; i<L->length; i++) //冒泡排序的最后一个值不用参与比较{min = i;for(j=i+1; j<=L->length; j++){if(L->array[j] < L->array[min])min = j;}if(min!=i){L->array[0] = L->array[min];L->array[min] = L->array[i];L->array[i] = L->array[0];}}printf("\n-----------------简单选择排序结果为-----------------\n");for(i=1; i<=L->length; i++)printf("%d ",L->array[i]);printf("\n");}/*2—路归并排序一趟合并函数功能:将L[s...m] 和L[m+1...t]和并为T[s...t]入口参数:原列表L,合并后的列表T,起始值s,中间值m,终点值t 返回值:无void GuiBing_pass(List *L,List *T,int s,int m,int t){int i;int j;int k=1;for(i=1,j=m+1; i<=m,j<=t; k++){if(L->array[i] < L->array[j])T->array[k] = L->array[i++];elseT->array[k] = L->array[j++];}while(i < m){T->array[k++] = L->array[i++];}while(j<t){T->array[k++] = L->array[j++];}}2-归并排序递归分解函数功能:将L[s..t]归并为T2[s...t],再将T2[s..t]归并为T1[s..t]void GuiBing_sort(List *L,List *T1,int s,int t){int m;List Tx;List *T2 = &Tx;Tx.length = 6;if(s==t)L->array[s] = T2->array[s];else{m = (s+t)/2;GuiBing_sort(L,T2,s,m);GuiBing_sort(L,T2,m+1,t);GuiBing_pass(T2,T1,s,m,t);}}*/void main(){int choice;int i;int d[4] = {7,5,3,1}; //希尔排序的增量数组List L;List Lx; //每次使用一中排序后就会对数组改变,所以复制下来检测每一种排序方法List T; //存放2路归并排序的结果T.length = 6;printf("1 创建顺序表\n2 直接插入排序\n3 二分法插入排序\n4 希尔排序\n5 冒泡排序\n6 快速排序\n7 简单选择排序\n0 退出\n");do{printf("请选择:");scanf("%d",&choice);switch(choice){case 1:Creat(&L);break;case 2:Copy(&L,&Lx);ZhiJieChaRu_sort(&Lx);break;case 3:Copy(&L,&Lx);ErFenFa_sort(&Lx);break;case 4:Copy(&L,&Lx);Shell_sort(&Lx,d);break;case 5:Copy(&L,&Lx);MaoPao_sort(&Lx);break;case 6:Copy(&L,&Lx);KuaiSuPaiXu_sort(&Lx,1,Lx.length);printf("\n-----------------快速排序结果为-----------------\n");for(i=1; i<=Lx.length; i++)printf("%d ",Lx.array[i]);printf("\n");break;case 7:Copy(&L,&Lx);JianDanXuanZe_sort(&Lx);break;/* case 8:Copy(&L,&Lx);GuiBing_sort(&Lx,&T,1,Lx.length);printf("\n-----------------2-路排序结果为-----------------\n");for(i=1; i<=Lx.length; i++)printf("%d ",T.array[i]);printf("\n");break;*/case 0:printf("退出操作!\n");exit(0);break;default :printf("输入错误");break;}}while("choice!=0");}。

相关主题